enchanted_crow

lab2_everything_except_interrupt

Mar 26th, 2022 (edited)
1,002
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 10.61 KB | None | 0 0
  1. #include"stm32f446xx.h"
  2. #include <string.h>
  3.  
  4. /*
  5.     ------------
  6.     INPUT
  7.     ------------
  8.     Temperature sensor input: PB_0, PB_1
  9.     Water sensor input: PB_2, PB_3
  10.     Humidity sensor input: PB_4, PB_5
  11.     Light sensor input: PB_6 (day/night), PB_7, PB_8 (room select)
  12.    
  13.     ------------
  14.     OUTPUT         
  15.     ------------
  16.     Temperature: PC_0 (heater), PC_1 (air cooler)
  17.     Water: PC_2 (water pump)
  18.     Humidity sensor input: PC_3 (humidifier)
  19.     Light sensor input: PC_4 (on/off)
  20. */
  21.  
  22. #define TEMP_PIN_INPUT_1 0
  23. #define TEMP_PIN_INPUT_2 1
  24. #define WATER_PIN_INPUT_1 2
  25. #define WATER_PIN_INPUT_2 3
  26. #define HUMIDITY_PIN_INPUT_1 4
  27. #define HUMIDITY_PIN_INPUT_2 5
  28. #define LIGHT_PIN_INPUT_DAY_NIGHT 8
  29. #define LIGHT_PIN_INPUT_ROOM_SELECT_1 6
  30. #define LIGHT_PIN_INPUT_ROOM_SELECT_2 7
  31.  
  32. #define TEMP_PIN_OUTPUT_HEATER 0
  33. #define TEMP_PIN_OUTPUT_COOLER 1
  34. #define WATER_PIN_OUTPUT_PUMP 2
  35. #define HUMIDITY_PIN_OUTPUT_HUMIDIFIER 3
  36. #define LIGHT_PIN_OUTPUT_LIGHT 4
  37.  
  38. #define HEATER_ON_TIME_DELAY_MS 3000
  39. #define COOLER_ON_TIME_DELAY_MS 3000
  40. #define WATER_PUMP_ON_TIME_DELAY_MS 3000
  41. #define HUMIDIFIER_ON_TIME_DELAY_MS 3000
  42.  
  43. #define TEMP_INPUT_1 ((GPIOB->IDR >> TEMP_PIN_INPUT_1) & 1)
  44. #define TEMP_INPUT_2 ((GPIOB->IDR >> TEMP_PIN_INPUT_2) & 1)
  45. #define WATER_INPUT_1 ((GPIOB->IDR >> WATER_PIN_INPUT_1) & 1)
  46. #define WATER_INPUT_2 ((GPIOB->IDR >> WATER_PIN_INPUT_2) & 1)
  47. #define HUMIDITY_INPUT_1 ((GPIOB->IDR >> HUMIDITY_PIN_INPUT_1) & 1)
  48. #define HUMIDITY_INPUT_2 ((GPIOB->IDR >> HUMIDITY_PIN_INPUT_2) & 1)
  49. #define LIGHT_INPUT_DAY_NIGHT ((GPIOB->IDR >> LIGHT_PIN_INPUT_DAY_NIGHT) & 1)
  50. #define LIGHT_INPUT_ROOM_SELECT_1 ((GPIOB->IDR >> LIGHT_PIN_INPUT_ROOM_SELECT_1) & 1)
  51. #define LIGHT_INPUT_ROOM_SELECT_2 ((GPIOB->IDR >> LIGHT_PIN_INPUT_ROOM_SELECT_2) & 1)
  52.  
  53. void sys_clock_config(void);
  54.  
  55. void tim6_config(void);
  56. void tim6_set_delay_ms(uint16_t ms);
  57. void tim6_set_delay_us(uint16_t us);
  58.  
  59. void usart2_config(void);
  60. void usart2_recieve_line(char rec_string[]);
  61. void usart2_send_string(char *start_char_pos);
  62. void usart2_send_char(uint8_t c);
  63. uint8_t usart2_get_char(void);
  64.  
  65. void smart_home_get_init_config(void);
  66. void smart_home_config(void);
  67. void smart_home_set_init_config(void);
  68. void operate_smart_home(void);
  69. void modify_heater(int turn_on);
  70. void modify_cooler(int turn_on);
  71. void modify_water_pump(int turn_on);
  72. void modify_humidifier(int turn_on);
  73. void modify_light(int turn_on);
  74. void run_temperature_control(void);
  75. void run_water_pump_control(void);
  76. void run_humidifier_control(void);
  77. void run_light_sensor_control(void);
  78. void turn_on_heater_for_ms(int delay_ms);
  79. void turn_on_cooler_for_ms(int delay_ms);
  80. void turn_on_humidifier_for_ms(int delay_ms);
  81.  
  82. int is_letter(uint8_t c);
  83. int to_number(char c);
  84.  
  85. char init_config[100];
  86. char init_temp[2], init_water[2], init_hum[2];
  87. int init_light[4];
  88.  
  89. int main(){
  90.     sys_clock_config();
  91.     tim6_config();
  92.     usart2_config();
  93.     smart_home_config();
  94.    
  95.     while(1){
  96.         operate_smart_home();
  97.     }
  98. }
  99.  
  100. void modify_heater(int turn_on){
  101.     // PC_0 for heater
  102.     if(turn_on) GPIOC->BSRR |= 1 << TEMP_PIN_OUTPUT_HEATER;
  103.     else GPIOC->BSRR |= 1 << (TEMP_PIN_OUTPUT_HEATER + 16);
  104. }
  105.  
  106. void modify_cooler(int turn_on){
  107.     // PC_1 for cooler
  108.     if(turn_on) GPIOC->BSRR |= 1 << TEMP_PIN_OUTPUT_COOLER;
  109.     else GPIOC->BSRR |= 1 << (TEMP_PIN_OUTPUT_COOLER + 16);
  110. }
  111.  
  112.  
  113. void turn_on_heater_for_ms(int delay_ms){
  114.     modify_heater(1);  
  115.     tim6_set_delay_ms(delay_ms);
  116.     modify_heater(0);  
  117. }
  118. void turn_on_cooler_for_ms(int delay_ms){
  119.     modify_cooler(1);  
  120.     tim6_set_delay_ms(delay_ms);
  121.     modify_cooler(0);  
  122. }
  123. void turn_on_water_pump_for_ms(int delay_ms){
  124.     modify_water_pump(1);  
  125.     tim6_set_delay_ms(delay_ms);
  126.     modify_water_pump(0);  
  127. }
  128. void turn_on_humidifier_for_ms(int delay_ms){
  129.     modify_humidifier(1);  
  130.     tim6_set_delay_ms(delay_ms);
  131.     modify_humidifier(0);  
  132. }
  133.  
  134. void modify_water_pump(int turn_on){
  135.     if(turn_on) GPIOC->BSRR |= 1 << WATER_PIN_OUTPUT_PUMP;
  136.     else GPIOC->BSRR |= 1 << (WATER_PIN_OUTPUT_PUMP + 16);
  137. }
  138.  
  139. void modify_humidifier(int turn_on){
  140.     if(turn_on) GPIOC->BSRR |= 1 << HUMIDITY_PIN_OUTPUT_HUMIDIFIER;
  141.     else GPIOC->BSRR |= 1 << (HUMIDITY_PIN_OUTPUT_HUMIDIFIER + 16);
  142. }
  143.  
  144. void modify_light(int turn_on){
  145.     if(turn_on) GPIOC->BSRR |= 1 << LIGHT_PIN_OUTPUT_LIGHT;
  146.     else GPIOC->BSRR |= 1 << (LIGHT_PIN_OUTPUT_LIGHT + 16);
  147. }
  148.  
  149. void run_temperature_control(void){
  150.     // 01 -> heater on
  151.     if(TEMP_INPUT_1 && !TEMP_INPUT_2){
  152.         turn_on_heater_for_ms(HEATER_ON_TIME_DELAY_MS);
  153.     }
  154.     // 10 -> cooler on
  155.     else if(!TEMP_INPUT_1 && TEMP_INPUT_2){
  156.         turn_on_cooler_for_ms(COOLER_ON_TIME_DELAY_MS);
  157.     }
  158. }
  159.  
  160. void run_water_pump_control(void){
  161.     // 01, 10 -> water pump on, else -> do nothing
  162.     if(WATER_INPUT_1 ^ WATER_INPUT_2){
  163.         turn_on_water_pump_for_ms(WATER_PUMP_ON_TIME_DELAY_MS);
  164.     }
  165. }
  166.  
  167. void run_humidifier_control(void){
  168.     // 01, 10 -> humidifier on, else -> do nothing
  169.     if(HUMIDITY_INPUT_1 ^ HUMIDITY_INPUT_2) {
  170.         turn_on_humidifier_for_ms(HUMIDIFIER_ON_TIME_DELAY_MS);
  171.     }
  172. }
  173. void run_light_sensor_control(void){
  174.     if(LIGHT_INPUT_DAY_NIGHT){
  175.         if(!LIGHT_INPUT_ROOM_SELECT_1 && !LIGHT_INPUT_ROOM_SELECT_2) // 00 -> room 0
  176.             modify_light(init_light[0]);
  177.         if(!LIGHT_INPUT_ROOM_SELECT_1 && LIGHT_INPUT_ROOM_SELECT_2) // 01 -> room 1
  178.             modify_light(init_light[1]);
  179.         if(LIGHT_INPUT_ROOM_SELECT_1 && !LIGHT_INPUT_ROOM_SELECT_2) // 10 -> room 2
  180.             modify_light(init_light[2]);
  181.         if(LIGHT_INPUT_ROOM_SELECT_1 && LIGHT_INPUT_ROOM_SELECT_2) // 11 -> room 3
  182.             modify_light(init_light[3]);
  183.     }
  184.     else{
  185.         modify_light(0);
  186.     }
  187. }
  188.  
  189. void operate_smart_home(void){
  190.     run_temperature_control();
  191.     run_water_pump_control();
  192.     run_humidifier_control();
  193.     run_light_sensor_control();
  194. }
  195. void smart_home_config(void){
  196.     smart_home_set_init_config();
  197.    
  198.     RCC->AHB1ENR |= RCC_AHB1ENR_GPIOBEN | RCC_AHB1ENR_GPIOCEN;
  199.     GPIOB->MODER &= 0;
  200.     GPIOC->MODER &= 0; 
  201.     for(int i = 0; i < 10; i++)
  202.         GPIOC->MODER |= (1 << (i * 2));
  203. }
  204. void smart_home_set_init_config(void){
  205.     // Temperature in init_config[17:18]
  206.     // Water in init_config[26:27]
  207.     // Humidity in init_config[33:34]
  208.     // Light in init_config[42:45]
  209.    
  210.     smart_home_get_init_config();
  211.    
  212.     init_temp[0] = init_config[18];
  213.     init_temp[1] = init_config[19];
  214.    
  215.     init_water[0] = init_config[26];
  216.     init_water[1] = init_config[27];
  217.    
  218.     init_hum[0] = init_config[33];
  219.     init_hum[1] = init_config[34];
  220.    
  221.     init_light[0] = to_number(init_config[42]);
  222.     init_light[1] = to_number(init_config[43]);
  223.     init_light[2] = to_number(init_config[44]);
  224.     init_light[3] = to_number(init_config[45]);
  225.    
  226.        
  227.     /*
  228.        
  229.     // temperature
  230.     usart2_send_char(init_config[17]);
  231.     usart2_send_char(init_config[18]);
  232.    
  233.     // water level
  234.     usart2_send_char(init_config[26]);
  235.     usart2_send_char(init_config[27]);
  236.    
  237.     // humidity
  238.     usart2_send_char(init_config[33]);
  239.     usart2_send_char(init_config[34]);
  240.    
  241.     // light
  242.     usart2_send_char(init_config[42]);
  243.     usart2_send_char(init_config[43]);
  244.     usart2_send_char(init_config[44]);
  245.     usart2_send_char(init_config[45]);
  246.    
  247.     */
  248. }
  249.  
  250. void smart_home_get_init_config(void){ 
  251.    
  252.     char str[100];
  253.    
  254.     usart2_recieve_line(str);
  255.     strcpy(init_config, str);
  256.     usart2_send_string(init_config);
  257. }
  258. int to_number(char c){
  259.     return c - '0';
  260. }
  261. void usart2_recieve_line(char *rec_string){
  262.     int i = 0;
  263.    
  264.     char c = '\0';
  265.     while(c != '.') {
  266.         c = usart2_get_char();
  267.         rec_string[i++] = c;
  268.        
  269.         // usart2_send_char(c);
  270.     }  
  271.     rec_string[i] = 0x00;
  272. }
  273.  
  274. void usart2_send_string(char *start_char_pos){
  275.     char *curr_char_pos = start_char_pos;
  276.     while(*curr_char_pos) usart2_send_char(*curr_char_pos++); // Until null character is reached
  277. }
  278.  
  279. void usart2_send_char(uint8_t c){
  280.  
  281.     USART2->DR = c;
  282.     while(!(USART2->SR & (1<<6)));
  283. }
  284.  
  285. uint8_t usart2_get_char(void){
  286.     uint8_t tmp;
  287.     while(!(USART2->SR & (1<<5)));
  288.    
  289.     tmp = USART2->DR;
  290.     return tmp;
  291. }
  292.  
  293. int is_letter(uint8_t c){
  294.     return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z');
  295. }
  296.  
  297.  
  298. void tim6_set_delay_us(uint16_t us){
  299.     TIM6->CNT = 0;
  300.     while(TIM6->CNT < us);
  301. }
  302.  
  303. void tim6_set_delay_ms(uint16_t ms){
  304.     for(uint16_t i=0; i<ms; i++){
  305.         tim6_set_delay_us(1000);
  306.     }
  307. }
  308.  
  309. void tim6_config(void){
  310.     //1. Enable timer clock
  311.     RCC->APB1ENR |= (1<<4);
  312.    
  313.     //2.Set the prescaler and ARR
  314.     TIM6->PSC = 90-1;
  315.     TIM6->ARR = 0xffff;
  316.    
  317.     //3. Enable the timer, and wait for the update flag to set
  318.     TIM6->CR1 |= (1<<0);
  319.     while(!(TIM6->SR & (1<<0)));// UIF: Update Interrupt Flag. The bit is set by hardware when the registers are updated.
  320. }
  321. void usart2_config(void){
  322.    
  323.     //1. Enable the UART clock and the GPIO clock
  324.     RCC->APB1ENR |= (1<<17);
  325.     RCC->AHB1ENR |= (1<<0);
  326.    
  327.     //2. Configure the UART pins for alternate functions
  328.     GPIOA->MODER |= (2<<4);
  329.     GPIOA->MODER |= (2<<6);
  330.    
  331.     GPIOA->OSPEEDR |= (3<<4);
  332.     GPIOA->OSPEEDR |= (3<<6);
  333.    
  334.     GPIOA->AFR[0] |= (7<<8);
  335.     GPIOA->AFR[0] |= (7<<12);
  336.    
  337.    
  338.     //3. Enable the USART by writing the USART_CR1 register to 1
  339.     USART2->CR1 = 0x00;
  340.     USART2->CR1 |= (1<<13);
  341.    
  342.    
  343.     //4. Program the M bit to define the word length
  344.     USART2->CR1 &= ~(1<<12);
  345.    
  346.    
  347.     //5. Select the desired Baud rate using USART_BRR register
  348.     USART2->BRR = (7<<0) | (24<<4);
  349.    
  350.    
  351.     //6. Enable the transmitter/receiver by setting the TE and RE bis in USART_CR1 register
  352.     USART2->CR1 |= (1<<2);
  353.     USART2->CR1 |= (1<<3); 
  354. }
  355.  
  356. void sys_clock_config(void){
  357.    
  358. /*************>>>>>>> STEPS FOLLOWED <<<<<<<<************
  359.    
  360.     1. ENABLE HSE and wait for the HSE to become Ready
  361.     2. Set the POWER ENABLE CLOCK and VOLTAGE REGULATOR
  362.     3. Configure the FLASH PREFETCH and the LATENCY Related Settings
  363.     4. Configure the PRESCALARS HCLK, PCLK1, PCLK2
  364.     5. Configure the MAIN PLL
  365.     6. Enable the PLL and wait for it to become ready
  366.     7. Select the Clock Source and wait for it to be set
  367.    
  368.     ********************************************************/
  369.    
  370.     #define PLL_M 4
  371.     #define PLL_N 180
  372.     #define PLL_P 0
  373.    
  374.    
  375.     //1. ENABLE HSE and wait for the HSE to become Ready
  376.     RCC->CR |= RCC_CR_HSEON;
  377.     while(!(RCC->CR & RCC_CR_HSERDY));
  378.        
  379.    
  380.        
  381.     //2. Set the POWER ENABLE CLOCK and VOLTAGE REGULATOR
  382.     RCC->APB1ENR |= RCC_APB1ENR_PWREN;
  383.     PWR->CR |= PWR_CR_VOS;
  384.    
  385.    
  386.     //3. Configure the FLASH PREFETCH and the LATENCY Related Settings
  387.     FLASH->ACR = FLASH_ACR_ICEN | FLASH_ACR_DCEN | FLASH_ACR_PRFTEN |FLASH_ACR_LATENCY_5WS;
  388.    
  389.     //4. Configure the PRESCALARS HCLK, PCLK1, PCLK2
  390.     // AHB PR
  391.     RCC->CFGR |= RCC_CFGR_HPRE_DIV1;
  392.    
  393.     // APB1 PR
  394.     RCC->CFGR |= RCC_CFGR_PPRE1_DIV4;
  395.    
  396.     //APB2 PR
  397.     RCC->CFGR |= RCC_CFGR_PPRE2_DIV2;
  398.    
  399.     //5. Configure the MAIN PLL
  400.     RCC->PLLCFGR = (PLL_M << 0) | (PLL_N << 6) | (PLL_P<<16) | (RCC_PLLCFGR_PLLSRC_HSE);
  401.    
  402.     //6. Enable the PLL and wait for it to become ready
  403.     RCC->CR |= RCC_CR_PLLON;
  404.     while(!(RCC->CR & RCC_CR_PLLRDY));
  405.    
  406.     //7. Select the Clock Source and wait for it to be set
  407.     RCC->CFGR |= RCC_CFGR_SW_PLL;
  408.     while((RCC->CFGR & RCC_CFGR_SWS)!= RCC_CFGR_SWS_PLL);
  409.    
  410. }
  411.  
Add Comment
Please, Sign In to add comment