基于?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回应。很多新手容易在这里翻车,忘记改模式导致数据读不到。

基于?STM32大棚DHT11温湿度监测protues仿真设计 资料包含:程序+仿真+原理图+PCB(具体看下文资料清单) 主要功能: 1.液晶实时显示DHT11温度和湿度值; 2.具有温湿度超上限阈值报警功能; 3.温湿度上限值阈值可通过按键调节。

数据解析部分要注意的是每个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,断电重启后依然生效,这才算真正达到实用级别。

Logo

北京人形旗下天工造物具身智能开源社区,聚焦具身天工与慧思开物两大平台

更多推荐