基于STM32微控制器的DHT11环境温湿度监测系统设计与实现
基于stm32的环境温湿度监测系统设计(DHT11)最近在折腾STM32的环境监测小项目发现DHT11这玩意儿真是便宜又好用。虽然精度比不上那些高端传感器但做个室内温湿度监控绰绰有余。今天咱们直接开干手把手搭个能跑的系统。硬件部分简单到哭STM32F103C8T6最小系统板DHT11模块VCC接3.3VDATA脚随便找个GPIO我用的PA6记得加个4.7K上拉电阻。重点全在软件时序上毕竟这个传感器用的是单总线协议。先上启动代码void DHT11_Start(void) { GPIO_InitTypeDef gpio; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); gpio.GPIO_Pin GPIO_Pin_6; gpio.GPIO_Mode GPIO_Mode_Out_PP; // 先切输出模式 gpio.GPIO_Speed GPIO_Speed_50MHz; GPIO_Init(GPIOA, gpio); GPIO_ResetBits(GPIOA, GPIO_Pin_6); // 拉低18ms delay_ms(20); GPIO_SetBits(GPIOA, GPIO_Pin_6); delay_us(30); // 主机拉高20-40us gpio.GPIO_Mode GPIO_Mode_IN_FLOATING; // 切输入模式准备读取 GPIO_Init(GPIOA, gpio); }这个启动信号要注意两点拉低时间必须大于18ms然后切换输入模式时的时序要快。实测发现不加nop()空指令的话模式切换可能来不及这时候可以在GPIO初始化后插入几个nop()。基于stm32的环境温湿度监测系统设计(DHT11)数据读取才是重头戏uint8_t DHT11_ReadByte(void) { uint8_t data 0; for(int i0; i8; i){ while(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6)); // 等低电平 delay_us(40); // 关键延时 if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6)) data | (1(7-i)); while(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6)); // 等高电平结束 } return data; }这个40us的延时决定数据是0还是1——低于30us是0高于是1。但实际调试发现用循环延时误差较大建议上定时器或者改用systick。不过对于要求不高的场景直接delay_us也能凑合用。完整数据包处理int DHT11_GetData(float *temp, float *humi) { uint8_t buf[5] {0}; DHT11_Start(); if(GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6) 0){ while(!GPIO_ReadInputDataBit(GPIOA, GPIO_Pin_6)); // 等传感器拉高 for(int i0; i5; i) buf[i] DHT11_ReadByte(); if(buf[0] buf[1] buf[2] buf[3] buf[4]){ *humi buf[0] buf[1]*0.1; *temp buf[2] buf[3]*0.1; return 0; } } return -1; // 校验失败或超时 }这里有个坑DHT11的温度小数位实际只有1位0.1精度但有些商家手册乱写。校验和记得要把前四个字节加起来比对我遇到过传感器老化导致校验失败的情况这时候需要加retry机制。实测中发现的问题汇总电源不稳会导致数据乱跳建议给DHT11单独加104电容长导线容易受干扰建议线长不要超过1米两次读取间隔必须大于1秒否则传感器不响应低温环境0℃需要特别注意DHT11的温度寄存器是带符号的最后用串口打印结果验证printf(湿度:%.1f%% 温度:%.1f℃\n, humidity, temperature);别被时序图吓到实际写起来也就那么回事。下次打算加上LCD实时显示和超限报警功能有兴趣的可以自己接着折腾。完整代码已经扔Github假装有链接需要自取。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2476323.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!