基于?STM32大棚DHT11温湿度监测protues仿真设计 资料包含:程序+仿真+原理图+PCB(具体看下文资料清单) 主要功能: 1.液晶实时显示DHT11温度和湿度值; 2.具有温湿度超上限阈值报警功能; 3.温湿度上限值阈值可通过按键调节。
老铁们今天带大家玩点实在的——用STM32搞个能报警的温湿度监控系统。直接上干货,这个系统最骚的地方在于能用按键随时调报警阈值,液晶屏实时显示数据,温湿度超标直接亮灯+哔哔叫,特别适合大棚种植这类需要精准监控的场景。
先看硬件配置(Proteus仿真截图示意):STM32F103C8T6当大脑,DHT11传感器负责温湿度采集,1602液晶做显示,三个按键用来设置阈值,蜂鸣器配LED组成报警双保险。重点说下DHT11的数据脚接在PA0,这货的时序要求贼严格,代码里必须把延时搞精准。
核心代码先从数据读取开刀。DHT11的启动信号需要单片机先拉低18ms然后拉高20-40us,这个操作必须用微秒级延时实现:
void DHT11_Start(void){ GPIO_InitTypeDef gpio; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); gpio.GPIO_Pin = GPIO_Pin_0; gpio.GPIO_Mode = GPIO_Mode_Out_PP; gpio.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOA, &gpio); GPIO_ResetBits(GPIOA, GPIO_Pin_0); //拉低18ms Delay_ms(18); GPIO_SetBits(GPIOA, GPIO_Pin_0); Delay_us(30); //主机拉高20-40us //切换输入模式等待响应 gpio.GPIO_Mode = GPIO_Mode_IPU; GPIO_Init(GPIOA, &gpio); }这段代码的关键在于模式切换——输出模式发完启动信号后要立即切回上拉输入模式等DHT11回应。很多新手容易在这里翻车,忘记改模式导致数据读不到。
数据解析部分要注意的是每个bit都以50us低电平开始,高电平持续时间决定数据是0还是1。这里必须用精准的while循环检测:
for(i=0; i<5; i++){ for(j=0; j<8; j++){ while(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)); //等待高电平 Delay_us(40); //关键延时!超过30us算1 if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)) data[i] |= (1<<(7-j)); //高位在前 else data[i] &= ~(1<<(7-j)); while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_0)); //等待低电平 } }校验位计算也不能马虎,前四个字节的和必须等于第五个字节,否则数据无效。建议加上重试机制,连续三次读取失败要报传感器故障。
阈值设置功能主要靠按键扫描实现。这里用状态机方式处理长按加速,代码比普通扫描复杂但用户体验更爽:
if(HAL_GPIO_ReadPin(SET_GPIO_Port, SET_Pin) == GPIO_PIN_RESET){ delay_ms(10); //消抖 if(HAL_GPIO_ReadPin(SET_GPIO_Port, SET_Pin) == GPIO_PIN_RESET){ set_mode = !set_mode; //进入/退出设置模式 while(!HAL_GPIO_ReadPin(SET_GPIO_Port, SET_Pin)); //等待松开 } } //在设置模式下处理加减 if(set_mode){ handle_inc_dec_keys(&temp_threshold, &humid_threshold); //参数保存到EEPROM EE_WriteVariable(VirtAddVarTab[0], temp_threshold); EE_WriteVariable(VirtAddVarTab[1], humid_threshold); }报警逻辑简单粗暴,直接在主循环里对比当前值和阈值。双阈值分开设定更灵活,比如温度设35℃湿度设80%:
if(current_temp > temp_threshold || current_humid > humid_threshold){ HAL_GPIO_WritePin(BUZZER_GPIO_Port, BUZZER_Pin, GPIO_PIN_SET); HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_RESET); }else{ HAL_GPIO_WritePin(BUZZER_GPIO_Port, BUZZER_Pin, GPIO_PIN_RESET); HAL_GPIO_WritePin(LED_GPIO_Port, LED_Pin, GPIO_PIN_SET); }实测发现DHT11在高温高湿环境下响应会变慢,建议在代码里加入超时判断。当传感器无响应超过2秒时,在液晶屏显示"Sensor Error"并闪烁报警灯,防止系统死机。
最后说下仿真中的坑:Proteus里的DHT11模块对时序要求比实物更严格,建议把代码中的微秒级延时适当调小10%-15%。按键防抖处理也不能省,不然设置值时容易跳变。整个系统跑起来后,阈值修改能实时保存到EEPROM,断电重启后依然生效,这才算真正达到实用级别。