1、简介
按照基于STM32单片机的疫情防控系统(一),对各个子模块硬件进行测试无误后进行,按照原理图焊接好元器件进行应用层代码书写。
2、子模块代码整合
2.1 子代码数据读取与发送
首先在icode文件夹下建立func文件夹,文件夹内建立func.c,func.h文件,如下图所示:
接着在Keil中对func.c,func.h进行添加编译如下图所示:
func.h代码如下所示:
#ifndef FUNC_FUNC_H_ #define FUNC_FUNC_H_ #include "main.h" #include "tim.h" #include "oled.h" #include "usart.h" #include "HC-SR04.h" #include "string.h" #define O_door 100 #define C_door 250 __packed struct QT_info { unsigned char Head[2]; float distant; float temp; float temp_threshold; float distant_threshold; uint8_t person; char revebuf[10]; }; void door(uint8_t door); void CSH(void); void oled_ui(void); void alarm(void); void Person(void); void Qt_UART_RxCallBack(unsigned char *Data,unsigned int Len); void threshold_ui(void); #endif /* FUNC_FUNC_H_ */
func.c代码如下所示:
#include "func.h" struct QT_info QT_info_TX; uint8_t sign_c; void CSH(void) { OLED_Clear(); OLED_Init(); HAL_Delay(200); QT_info_TX.temp_threshold = 39.0; QT_info_TX.distant_threshold = 10.0; QT_info_TX.person = 0; QT_info_TX.Head[0]=0x55; QT_info_TX.Head[1]=0xFF; HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_4);//***定时器初始化 //door(C_door); } void oled_ui(void) { SR04_GetData(); QT_info_TX.distant = distant; Person(); if(QT_info_TX.distant<10.0){ QT_info_TX.temp=SMBus_ReadTemp()+2.7; } HAL_UART_Receive_IT(&huart2,(uint8_t *)&QT_info_TX.revebuf,10); HAL_Delay(100); OLED_ShowCHinese(30,0,0); OLED_ShowCHinese(46,0,1); OLED_ShowCHinese(62,0,2); OLED_ShowCHinese(78,0,3); OLED_ShowCHinese(0,3,4); OLED_ShowCHinese(16,3,5); OLED_ShowString(32,3,(uint8_t *)":",16); OLED_ShowNum(48,3,QT_info_TX.temp,2,16); //OLED_ShowNum(80,3,QT_info_TX.temp_threshold,2,16); OLED_ShowCHinese(0,6,6); OLED_ShowCHinese(16,6,7); OLED_ShowString(32,6,(uint8_t *)":",16); OLED_ShowNum(48,6,QT_info_TX.distant,2,16); //OLED_ShowNum(80,6,QT_info_TX.distant_threshold,2,16); HAL_Delay(100);//毫秒延时 //HAL_UART_Transmit(&huart1,(uint8_t *)&QT_info_TX,sizeof(QT_info_TX),100); } void alarm(void) { if(sign_c == 0){ sign_c= 2; } } void door(uint8_t door) { __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_4, door);//相当于一个周期内(20ms)有1ms高脉冲 //HAL_Delay(500); } void Person(void) { if(HAL_GPIO_ReadPin(HY_GPIO_Port, HY_Pin) == GPIO_PIN_RESET) { delay_us(10); if(HAL_GPIO_ReadPin(HY_GPIO_Port, HY_Pin) == GPIO_PIN_RESET) { QT_info_TX.person++; } while(HAL_GPIO_ReadPin(HY_OUT_GPIO_Port, HY_Pin) == GPIO_PIN_RESET); } else if(HAL_GPIO_ReadPin(HY_OUT_GPIO_Port, HY_OUT_Pin) == GPIO_PIN_RESET) { delay_us(10); if(HAL_GPIO_ReadPin(HY_OUT_GPIO_Port, HY_OUT_Pin) == GPIO_PIN_RESET) { QT_info_TX.person = QT_info_TX.person - 1 >= 0 ? QT_info_TX.person -1 : 0; } while(HAL_GPIO_ReadPin(HY_OUT_GPIO_Port, HY_OUT_Pin) == GPIO_PIN_RESET); } }
2.2 应用层代码设计
接着进行应用层代码,因为需要上位机指令,因此在icode文件夹下建立key文件,key.h程序如下所示:
/* * key.h * * Created on: Jan 18, 2022 * Author: Administrator */ #ifndef KEY_KEY_H_ #define KEY_KEY_H_ #include "stm32f1xx_hal.h" //HAL库文件声明 #include "main.h" //IO定义与初始化函数在main.c文件中,必须引用 //#include "../../icode/delay/delay.h" #include "GY906.h" #include "oled.h" #include "func.h" uint8_t KEY_1(void);//按键1 uint8_t KEY_2(void);//按键2 void threshold_ui(void); extern uint8_t sign_a,sign_b,sign_c; #endif /* KEY_KEY_H_ */
key.c代码如下所示:
#include "key.h" #include "../../icode/key/key.h" #include "main.h" #include "usart.h" #include "stdio.h" #include "func.h" char buf; uint8_t sign_a =0,sign_b=0; static uint8_t sign_c; void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)//串口中断回调函数 { if(huart1.Instance == USART1) { if(buf == 'A') { sign_a++; } else if(buf == 'B') { sign_b++; } else if(buf == 'C') { sign_b--; } else if(buf == 'D') { sign_c=1; door(C_door); LED_OFF; } else if(buf == 'E') { sign_c=1; door(O_door); LED_OFF; } else if(buf == 'F') { sign_c=0; LED_ON; } } } extern struct QT_info QT_info_TX; void threshold_ui() { HAL_UART_Transmit(&huart1,(unsigned char *)&QT_info_TX,sizeof(QT_info_TX),100); HAL_UART_Receive_IT(&huart1, (uint8_t *)&buf, 1); alarm(); switch(sign_a){ case 0: oled_ui(); break; case 1: OLED_ShowNum(80,3,QT_info_TX.temp_threshold,2,16); switch(sign_b){ case 0: QT_info_TX.temp_threshold--; sign_b = 1; break; case 1: break; case 2: QT_info_TX.temp_threshold++; sign_b = 1; break; default: break; } break; case 2: OLED_ShowNum(80,6,QT_info_TX.distant_threshold,2,16); switch(sign_b){ case 0: QT_info_TX.distant_threshold--; sign_b = 1; break; case 1: break; case 2: QT_info_TX.distant_threshold++; sign_b = 1; break; default: break; } break; case 3: OLED_Clear(); OLED_On(); sign_a=0; break; default: break; } }
接着需要进行上位机的设计。
上文如有错误,恳请各位大佬指正。