完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
STM32
一.前言 在实际的项目开发过程中我们会使用到很多模块,今天我们说一下DHT11温湿度模块 这里是将测量的数据显示在0.96寸oled显示屏上面,如果不会oled屏幕驱动的可以看一下之前的文章 二.DHT11驱动原理 步骤一 DHT11上电后(DHT11上电后要等待 1S 以越过不稳定状态在此期间不能发送任何指令),测试环境 温湿度数据,并记录数据,同时 DHT11的 DATA 数据线由上拉电阻拉高一直保持高电平;此时 DHT11的 DATA 引脚处于输入状态,时刻检测外部信号。 步骤二 微处理器的 I/O设置为输出同时输出低电平,且低电平保持时间不能小于 18ms(最大不得超过 30ms), 然后微处理器的 I/O设置为输入状态,由于上拉电阻,微处理器的 I/O即 DHT11的 DATA 数据线也随之变 高,等待 DHT11作出回答信号,发送信号如图所示: 步骤三 DHT11 的 DATA引脚检测到外部信号有低电平时,等待外部信号低电平结束,延迟后 DHT11 的 DATA 引脚处于输出状态,输出 83微秒的低电平作为应答信号,紧接着输出 87 微秒的高电平通知外设准备接 收数据,微处理器的 I/O 此时处于输入状态,检测到 I/O 有低电平(DHT11回应信号)后,等待 87微秒 的高电平后的数据接收,发送信号如图所示: 步骤四 由 DHT11 的 DATA引脚输出 40 位数据,微处理器根据 I/O电平的变化接收 40 位数据,位数据“0” 的格式为: 54 微秒的低电平和 23-27 微秒的高电平,位数据“1”的格式为: 54 微秒的低电平加 68-74 微秒的高电平。位数据“0”、“1”格式信号如图所 三. 代码部分 整个工程代码在此处下载 STM32F103ZET6驱动DHT11 温湿度显示 DHT11.h #ifndef __DHT11_H #define __DHT11_H #include "system.h" #define BOOL unsigned char #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif //定义DHT11 GPIOD 0 #define DHT11_PORT_RCC RCC_APB2Periph_GPIOD #define DHT11_PIN GPIO_Pin_0 #define DHT11_PORT GPIOD static void DHT11_DataPin_Configure_Output(void); static void DHT11_DataPin_Configure_Input(void); BOOL DHT11_get_databit(void); void DHT11_set_databit(BOOL level); void mdelay(u16 ms); void udelay(u16 us); static uint8_t DHT11_read_byte(void); static uint8_t DHT11_start_sampling(void); void DHT11_get_data(u32 *buf); #endif DHT11.c #include "dht11.h" #include "SysTick.h" /*数据定义: ---以下变量均为全局变量-------- //----温度高8位== U8T_data_H------ //----温度低8位== U8T_data_L------ //----湿度高8位== U8RH_data_H----- //----湿度低8位== U8RH_data_L----- //-----校验 8位 == U8checkdata----- */ u8 U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata; u8 U8T_data_H_temp,U8T_data_L_temp,U8RH_data_H_temp,U8RH_data_L_temp,U8checkdata_temp; static void DHT11_DataPin_Configure_Output(void) { GPIO_InitTypeDef GPIO_InitStructure; RCC_APB2PeriphClockCmd(DHT11_PORT_RCC, ENABLE); //使能PD端口时钟 GPIO_InitStructure.GPIO_Pin = DHT11_PIN; //PD.0 端口配置 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(DHT11_PORT, &GPIO_InitStructure); } static void DHT11_DataPin_Configure_Input(void) { GPIO_InitTypeDef DataPin; DataPin.GPIO_Pin = DHT11_PIN; DataPin.GPIO_Mode = GPIO_Mode_IN_FLOATING; //悬空 输入 DataPin.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(DHT11_PORT, &DataPin); } BOOL DHT11_get_databit(void) { uint8_t val; val = GPIO_ReadInputDataBit(DHT11_PORT, DHT11_PIN); if(val == Bit_RESET) { return FALSE; } else { return TRUE; } } void DHT11_set_databit(BOOL level) { if(level == TRUE) { GPIO_SetBits(DHT11_PORT, DHT11_PIN); } else { GPIO_ResetBits(DHT11_PORT, DHT11_PIN); } } void mdelay(u16 ms) { if(ms != 0) { delay_ms(ms); } } void udelay(u16 us) { if(us != 0) { delay_us(us); } } static uint8_t DHT11_read_byte(void) { uint8_t i; uint8_t data = 0; for(i = 0; i < 8; i++) { data <<= 1; while((!DHT11_get_databit())); udelay(10); udelay(10); udelay(10); if(DHT11_get_databit()) { data |= 0x1; while(DHT11_get_databit()); } else { } } return data; } static uint8_t DHT11_start_sampling(void) { DHT11_DataPin_Configure_Output(); //主机拉低18ms DHT11_set_databit(FALSE); mdelay(18); DHT11_set_databit(TRUE); //总线由上拉电阻拉高 主机延时20us udelay(10); udelay(10); //主机设为输入 判断从机响应信号 DHT11_set_databit(TRUE); DHT11_DataPin_Configure_Input(); //判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行 if(!DHT11_get_databit()) //T ! { //判断从机是否发出 80us 的低电平响应信号是否结束 while((!DHT11_get_databit())); // printf("DHT11 answers.rn"); //判断从机是否发出 80us 的高电平,如发出则进入数据接收状态 while((DHT11_get_databit())) {} return 1; } return 0; } void DHT11_get_data(u32 *buf) { u8 temp; if(DHT11_start_sampling()) { //printf("DHT11 is ready to transmit datarn"); //数据接收状态 U8RH_data_H_temp = DHT11_read_byte(); U8RH_data_L_temp = DHT11_read_byte(); U8T_data_H_temp = DHT11_read_byte(); U8T_data_L_temp = DHT11_read_byte(); U8checkdata_temp = DHT11_read_byte(); /* Data transmission finishes, pull the bus high */ DHT11_DataPin_Configure_Output(); DHT11_set_databit(TRUE); //数据校验 temp=(U8T_data_H_temp+U8T_data_L_temp+U8RH_data_H_temp+U8RH_data_L_temp); if(temp==U8checkdata_temp) { U8RH_data_H=U8RH_data_H_temp; //湿度 U8RH_data_L=U8RH_data_L_temp; U8T_data_H=U8T_data_H_temp; //温湿 U8T_data_L=U8T_data_L_temp; U8checkdata=U8checkdata_temp; buf[0] = U8T_data_H; //温度的高低 buf[1] = U8T_data_L; buf[2] = U8RH_data_H; //湿度高低 buf[3] = U8RH_data_L; } } } main //-------------------------------------------------------------------------------------- //说明: STM32F103Zet6 驱动DHT11 在 0.96 oled屏显示温湿度 //引脚说明 // DHT11: PD0 // OLED: D0 接PC0(SCL) // D1 接PC1(SDA) // RES 接PC2 // DC 接PC3 CS 接PA0 //-------------------------------------------------------------------------------------- #include "system.h" #include "SysTick.h" //延时 #include "oled.h" #include "dht11.h" void dht11_show(u32 *buf); //oled显示 int main() { //显示温度和湿度的数组 元素0 为温度高 元素1 为温度低 // 元素2 为湿度高 元素3 为湿度的低 u32 DTH11_data[4]={0}; //时钟源获取 配置 SysTick_Init(72); //精确延时 OLED_Init(); OLED_ColorTurn(0);//0正常显示,1 反色显示 OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示 while(1) { DHT11_get_data(DTH11_data); //获取到温湿度 dht11_show(DTH11_data); delay_ms(5000); OLED_ShowString(70,20," ",16,1); OLED_ShowString(70,40," ",16,1); OLED_Refresh(); } } //温湿度显示 void dht11_show(u32 *buf) { u32 pos = 0; OLED_ShowChinese(20,20,0,16,1);//温 OLED_ShowChinese(40,20,1,16,1);//度 OLED_ShowString(60,20,":",16,1); if(buf[0] < 10) { OLED_ShowNum(70,20,buf[0],1,16,1); pos = 8; } else if(buf[0] < 100) { OLED_ShowNum(70,20,buf[0],2,16,1); pos = 16; } else { OLED_ShowNum(70,20,buf[0],3,16,1); pos = 24; } OLED_ShowString(70+pos,20,".",16,1); pos += 8; if(buf[1] < 10) { OLED_ShowNum(70+pos,20,buf[1],1,16,1); } else if(buf[1] < 100) { OLED_ShowNum(70+pos,20,buf[1],2,16,1); } else { OLED_ShowNum(70+pos,20,buf[1],3,16,1); } OLED_ShowChinese(20,40,2,16,1);//湿 OLED_ShowChinese(40,40,3,16,1);//度 OLED_ShowString(60,40,":",16,1); if(buf[2] < 10) { OLED_ShowNum(70,40,buf[2],1,16,1); pos = 8; } else if(buf[2] < 100) { OLED_ShowNum(70,40,buf[2],2,16,1); pos = 16; } else { OLED_ShowNum(70,40,buf[2],3,16,1); pos = 24; } OLED_ShowString(70+pos,40,".",16,1); pos += 8; if(buf[3] < 10) { OLED_ShowNum(70+pos,40,buf[3],1,16,1); } else if(buf[3] < 100) { OLED_ShowNum(70+pos,40,buf[3],2,16,1); } else { OLED_ShowNum(70+pos,40,buf[3],3,16,1); } OLED_Refresh(); } |
|
|
|
只有小组成员才能发言,加入小组>>
调试STM32H750的FMC总线读写PSRAM遇到的问题求解?
1767 浏览 1 评论
X-NUCLEO-IHM08M1板文档中输出电流为15Arms,15Arms是怎么得出来的呢?
1619 浏览 1 评论
1069 浏览 2 评论
STM32F030F4 HSI时钟温度测试过不去是怎么回事?
724 浏览 2 评论
ST25R3916能否对ISO15693的标签芯片进行分区域写密码?
1673 浏览 2 评论
1935浏览 9评论
STM32仿真器是选择ST-LINK还是选择J-LINK?各有什么优势啊?
727浏览 4评论
STM32F0_TIM2输出pwm2后OLED变暗或者系统重启是怎么回事?
567浏览 3评论
592浏览 3评论
stm32cubemx生成mdk-arm v4项目文件无法打开是什么原因导致的?
551浏览 3评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-12-21 19:56 , Processed in 0.673776 second(s), Total 46, Slave 40 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号