Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include"stm32f446xx.h"
- #include <string.h>
- /*
- ------------
- INPUT
- ------------
- Temperature sensor input: PB_0, PB_1
- Water sensor input: PB_2, PB_3
- Humidity sensor input: PB_4, PB_5
- Light sensor input: PB_6 (day/night), PB_7, PB_8 (room select)
- ------------
- OUTPUT
- ------------
- Temperature: PC_0 (heater), PC_1 (air cooler)
- Water: PC_2 (water pump)
- Humidity sensor input: PC_3 (humidifier)
- Light sensor input: PC_4 (on/off)
- */
- #define TEMP_PIN_INPUT_1 0
- #define TEMP_PIN_INPUT_2 1
- #define WATER_PIN_INPUT_1 2
- #define WATER_PIN_INPUT_2 3
- #define HUMIDITY_PIN_INPUT_1 4
- #define HUMIDITY_PIN_INPUT_2 5
- #define LIGHT_PIN_INPUT_DAY_NIGHT 8
- #define LIGHT_PIN_INPUT_ROOM_SELECT_1 6
- #define LIGHT_PIN_INPUT_ROOM_SELECT_2 7
- #define TEMP_PIN_OUTPUT_HEATER 0
- #define TEMP_PIN_OUTPUT_COOLER 1
- #define WATER_PIN_OUTPUT_PUMP 2
- #define HUMIDITY_PIN_OUTPUT_HUMIDIFIER 3
- #define LIGHT_PIN_OUTPUT_LIGHT 4
- #define HEATER_ON_TIME_DELAY_MS 3000
- #define COOLER_ON_TIME_DELAY_MS 3000
- #define WATER_PUMP_ON_TIME_DELAY_MS 3000
- #define HUMIDIFIER_ON_TIME_DELAY_MS 3000
- #define TEMP_INPUT_1 ((GPIOB->IDR >> TEMP_PIN_INPUT_1) & 1)
- #define TEMP_INPUT_2 ((GPIOB->IDR >> TEMP_PIN_INPUT_2) & 1)
- #define WATER_INPUT_1 ((GPIOB->IDR >> WATER_PIN_INPUT_1) & 1)
- #define WATER_INPUT_2 ((GPIOB->IDR >> WATER_PIN_INPUT_2) & 1)
- #define HUMIDITY_INPUT_1 ((GPIOB->IDR >> HUMIDITY_PIN_INPUT_1) & 1)
- #define HUMIDITY_INPUT_2 ((GPIOB->IDR >> HUMIDITY_PIN_INPUT_2) & 1)
- #define LIGHT_INPUT_DAY_NIGHT ((GPIOB->IDR >> LIGHT_PIN_INPUT_DAY_NIGHT) & 1)
- #define LIGHT_INPUT_ROOM_SELECT_1 ((GPIOB->IDR >> LIGHT_PIN_INPUT_ROOM_SELECT_1) & 1)
- #define LIGHT_INPUT_ROOM_SELECT_2 ((GPIOB->IDR >> LIGHT_PIN_INPUT_ROOM_SELECT_2) & 1)
- void sys_clock_config(void);
- void tim6_config(void);
- void tim6_set_delay_ms(uint16_t ms);
- void tim6_set_delay_us(uint16_t us);
- void usart2_config(void);
- void usart2_recieve_line(char rec_string[]);
- void usart2_send_string(char *start_char_pos);
- void usart2_send_char(uint8_t c);
- uint8_t usart2_get_char(void);
- void smart_home_get_init_config(void);
- void smart_home_config(void);
- void smart_home_set_init_config(void);
- void operate_smart_home(void);
- void modify_heater(int turn_on);
- void modify_cooler(int turn_on);
- void modify_water_pump(int turn_on);
- void modify_humidifier(int turn_on);
- void modify_light(int turn_on);
- void run_temperature_control(void);
- void run_water_pump_control(void);
- void run_humidifier_control(void);
- void run_light_sensor_control(void);
- void turn_on_heater_for_ms(int delay_ms);
- void turn_on_cooler_for_ms(int delay_ms);
- void turn_on_humidifier_for_ms(int delay_ms);
- int is_letter(uint8_t c);
- int to_number(char c);
- char init_config[100];
- char init_temp[2], init_water[2], init_hum[2];
- int init_light[4];
- int main(){
- sys_clock_config();
- tim6_config();
- usart2_config();
- smart_home_config();
- while(1){
- operate_smart_home();
- }
- }
- void modify_heater(int turn_on){
- // PC_0 for heater
- if(turn_on) GPIOC->BSRR |= 1 << TEMP_PIN_OUTPUT_HEATER;
- else GPIOC->BSRR |= 1 << (TEMP_PIN_OUTPUT_HEATER + 16);
- }
- void modify_cooler(int turn_on){
- // PC_1 for cooler
- if(turn_on) GPIOC->BSRR |= 1 << TEMP_PIN_OUTPUT_COOLER;
- else GPIOC->BSRR |= 1 << (TEMP_PIN_OUTPUT_COOLER + 16);
- }
- void turn_on_heater_for_ms(int delay_ms){
- modify_heater(1);
- tim6_set_delay_ms(delay_ms);
- modify_heater(0);
- }
- void turn_on_cooler_for_ms(int delay_ms){
- modify_cooler(1);
- tim6_set_delay_ms(delay_ms);
- modify_cooler(0);
- }
- void turn_on_water_pump_for_ms(int delay_ms){
- modify_water_pump(1);
- tim6_set_delay_ms(delay_ms);
- modify_water_pump(0);
- }
- void turn_on_humidifier_for_ms(int delay_ms){
- modify_humidifier(1);
- tim6_set_delay_ms(delay_ms);
- modify_humidifier(0);
- }
- void modify_water_pump(int turn_on){
- if(turn_on) GPIOC->BSRR |= 1 << WATER_PIN_OUTPUT_PUMP;
- else GPIOC->BSRR |= 1 << (WATER_PIN_OUTPUT_PUMP + 16);
- }
- void modify_humidifier(int turn_on){
- if(turn_on) GPIOC->BSRR |= 1 << HUMIDITY_PIN_OUTPUT_HUMIDIFIER;
- else GPIOC->BSRR |= 1 << (HUMIDITY_PIN_OUTPUT_HUMIDIFIER + 16);
- }
- void modify_light(int turn_on){
- if(turn_on) GPIOC->BSRR |= 1 << LIGHT_PIN_OUTPUT_LIGHT;
- else GPIOC->BSRR |= 1 << (LIGHT_PIN_OUTPUT_LIGHT + 16);
- }
- void run_temperature_control(void){
- // 01 -> heater on
- if(TEMP_INPUT_1 && !TEMP_INPUT_2){
- turn_on_heater_for_ms(HEATER_ON_TIME_DELAY_MS);
- }
- // 10 -> cooler on
- else if(!TEMP_INPUT_1 && TEMP_INPUT_2){
- turn_on_cooler_for_ms(COOLER_ON_TIME_DELAY_MS);
- }
- }
- void run_water_pump_control(void){
- // 01, 10 -> water pump on, else -> do nothing
- if(WATER_INPUT_1 ^ WATER_INPUT_2){
- turn_on_water_pump_for_ms(WATER_PUMP_ON_TIME_DELAY_MS);
- }
- }
- void run_humidifier_control(void){
- // 01, 10 -> humidifier on, else -> do nothing
- if(HUMIDITY_INPUT_1 ^ HUMIDITY_INPUT_2) {
- turn_on_humidifier_for_ms(HUMIDIFIER_ON_TIME_DELAY_MS);
- }
- }
- void run_light_sensor_control(void){
- if(LIGHT_INPUT_DAY_NIGHT){
- if(!LIGHT_INPUT_ROOM_SELECT_1 && !LIGHT_INPUT_ROOM_SELECT_2) // 00 -> room 0
- modify_light(init_light[0]);
- if(!LIGHT_INPUT_ROOM_SELECT_1 && LIGHT_INPUT_ROOM_SELECT_2) // 01 -> room 1
- modify_light(init_light[1]);
- if(LIGHT_INPUT_ROOM_SELECT_1 && !LIGHT_INPUT_ROOM_SELECT_2) // 10 -> room 2
- modify_light(init_light[2]);
- if(LIGHT_INPUT_ROOM_SELECT_1 && LIGHT_INPUT_ROOM_SELECT_2) // 11 -> room 3
- modify_light(init_light[3]);
- }
- else{
- modify_light(0);
- }
- }
- void operate_smart_home(void){
- run_temperature_control();
- run_water_pump_control();
- run_humidifier_control();
- run_light_sensor_control();
- }
- void smart_home_config(void){
- smart_home_set_init_config();
- RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN;
- GPIOB->MODER &= 0;
- GPIOC->MODER &= 0;
- for(int i = 0; i < 10; i++)
- GPIOC->MODER |= (1 << (i * 2));
- }
- void smart_home_set_init_config(void){
- // Temperature in init_config[17:18]
- // Water in init_config[26:27]
- // Humidity in init_config[33:34]
- // Light in init_config[42:45]
- smart_home_get_init_config();
- init_temp[0] = init_config[18];
- init_temp[1] = init_config[19];
- init_water[0] = init_config[26];
- init_water[1] = init_config[27];
- init_hum[0] = init_config[33];
- init_hum[1] = init_config[34];
- init_light[0] = to_number(init_config[42]);
- init_light[1] = to_number(init_config[43]);
- init_light[2] = to_number(init_config[44]);
- init_light[3] = to_number(init_config[45]);
- /*
- // temperature
- usart2_send_char(init_config[17]);
- usart2_send_char(init_config[18]);
- // water level
- usart2_send_char(init_config[26]);
- usart2_send_char(init_config[27]);
- // humidity
- usart2_send_char(init_config[33]);
- usart2_send_char(init_config[34]);
- // light
- usart2_send_char(init_config[42]);
- usart2_send_char(init_config[43]);
- usart2_send_char(init_config[44]);
- usart2_send_char(init_config[45]);
- */
- }
- void smart_home_get_init_config(void){
- char str[100];
- usart2_recieve_line(str);
- strcpy(init_config, str);
- usart2_send_string(init_config);
- }
- int to_number(char c){
- return c - '0';
- }
- void usart2_recieve_line(char *rec_string){
- int i = 0;
- char c = '\0';
- while(c != '.') {
- c = usart2_get_char();
- rec_string[i++] = c;
- // usart2_send_char(c);
- }
- rec_string[i] = 0x00;
- }
- void usart2_send_string(char *start_char_pos){
- char *curr_char_pos = start_char_pos;
- while(*curr_char_pos) usart2_send_char(*curr_char_pos++); // Until null character is reached
- }
- void usart2_send_char(uint8_t c){
- USART2->DR = c;
- while(!(USART2->SR & (1<<6)));
- }
- uint8_t usart2_get_char(void){
- uint8_t tmp;
- while(!(USART2->SR & (1<<5)));
- tmp = USART2->DR;
- return tmp;
- }
- int is_letter(uint8_t c){
- return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z');
- }
- void tim6_set_delay_us(uint16_t us){
- TIM6->CNT = 0;
- while(TIM6->CNT < us);
- }
- void tim6_set_delay_ms(uint16_t ms){
- for(uint16_t i=0; i<ms; i++){
- tim6_set_delay_us(1000);
- }
- }
- void tim6_config(void){
- //1. Enable timer clock
- RCC->APB1ENR |= (1<<4);
- //2.Set the prescaler and ARR
- TIM6->PSC = 90-1;
- TIM6->ARR = 0xffff;
- //3. Enable the timer, and wait for the update flag to set
- TIM6->CR1 |= (1<<0);
- while(!(TIM6->SR & (1<<0)));// UIF: Update Interrupt Flag. The bit is set by hardware when the registers are updated.
- }
- void usart2_config(void){
- //1. Enable the UART clock and the GPIO clock
- RCC->APB1ENR |= (1<<17);
- RCC->AHB1ENR |= (1<<0);
- //2. Configure the UART pins for alternate functions
- GPIOA->MODER |= (2<<4);
- GPIOA->MODER |= (2<<6);
- GPIOA->OSPEEDR |= (3<<4);
- GPIOA->OSPEEDR |= (3<<6);
- GPIOA->AFR[0] |= (7<<8);
- GPIOA->AFR[0] |= (7<<12);
- //3. Enable the USART by writing the USART_CR1 register to 1
- USART2->CR1 = 0x00;
- USART2->CR1 |= (1<<13);
- //4. Program the M bit to define the word length
- USART2->CR1 &= ~(1<<12);
- //5. Select the desired Baud rate using USART_BRR register
- USART2->BRR = (7<<0) | (24<<4);
- //6. Enable the transmitter/receiver by setting the TE and RE bis in USART_CR1 register
- USART2->CR1 |= (1<<2);
- USART2->CR1 |= (1<<3);
- }
- void sys_clock_config(void){
- /*************>>>>>>> STEPS FOLLOWED <<<<<<<<************
- 1. ENABLE HSE and wait for the HSE to become Ready
- 2. Set the POWER ENABLE CLOCK and VOLTAGE REGULATOR
- 3. Configure the FLASH PREFETCH and the LATENCY Related Settings
- 4. Configure the PRESCALARS HCLK, PCLK1, PCLK2
- 5. Configure the MAIN PLL
- 6. Enable the PLL and wait for it to become ready
- 7. Select the Clock Source and wait for it to be set
- ********************************************************/
- #define PLL_M 4
- #define PLL_N 180
- #define PLL_P 0
- //1. ENABLE HSE and wait for the HSE to become Ready
- RCC->CR |= RCC_CR_HSEON;
- while(!(RCC->CR & RCC_CR_HSERDY));
- //2. Set the POWER ENABLE CLOCK and VOLTAGE REGULATOR
- RCC->APB1ENR |= RCC_APB1ENR_PWREN;
- PWR->CR |= PWR_CR_VOS;
- //3. Configure the FLASH PREFETCH and the LATENCY Related Settings
- FLASH->ACR = FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_PRFTEN |FLASH_ACR_LATENCY_5WS;
- //4. Configure the PRESCALARS HCLK, PCLK1, PCLK2
- // AHB PR
- RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
- // APB1 PR
- RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;
- //APB2 PR
- RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;
- //5. Configure the MAIN PLL
- RCC->PLLCFGR = (PLL_M << 0) | (PLL_N << 6) | (PLL_P<<16) | (RCC_PLLCFGR_PLLSRC_HSE);
- //6. Enable the PLL and wait for it to become ready
- RCC->CR |= RCC_CR_PLLON;
- while(!(RCC->CR & RCC_CR_PLLRDY));
- //7. Select the Clock Source and wait for it to be set
- RCC->CFGR |= RCC_CFGR_SW_PLL;
- while((RCC->CFGR & RCC_CFGR_SWS)!= RCC_CFGR_SWS_PLL);
- }
Add Comment
Please, Sign In to add comment