5.03.1 概述3编程
5.03.1.1 性能描述4函数
5.03.1.2 传感器时序4性能
5.03.2 实验目的6spa
5.03.3 硬件设计7设计
5.03.4 软件设计73d
5.03.4.1 软件设计说明8code
5.03.4.2 STM32库函数文件8orm
5.03.4.3 自定义头文件8对象
5.03.4.4 pbdata.h文件里的内容是9blog
5.03.4.5 pbdata.c文件里的内容是9
5.03.5 STM32系统时钟配置SystemInit()12
5.03.6 GPIO引脚时钟使能12
5.03.7 GPIO管脚电平控制函数12
5.03.8 stm32f10x_it.c文件里的内容是13
5.03.9 dht11.h文件里的内容是13
5.03.10 dht11.c文件里的内容是14
5.03.11 main.c文件里的内容是17
5.03.12 程序下载19
5.03.13 实验效果图20
5.03 温湿度传感器模块实验
5.03.1 概述
DHT11 数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。它应用专用的数字模块采集技术和温湿度传感技术,确保产品具备极高的可靠性与卓越的长期稳定性。传感器包括一个电阻式感湿元件和一个NTC测温元件,并与一个高性能8 位单片机相链接。所以该产品具备品质卓越、超快响应、抗干扰能力强、性价比极高等优势。每一个DHT11 传感器都在极为精确的湿度校验室中进行校准。校准系数以程序的形式储存在OTP 内存中,传感器内部在检测信号的处理过程当中要调用这些校准系数。单线制串行接口,使系统集成变得简易快捷。超小的体积、极低的功耗,信号传输距离可达20 米以上,使其成为各种应用甚至最为苛刻的应用场合的最佳选则。
DHT11 数字温湿度传感器模块为4 针PH2.0 封装。链接方便。如右图所示。
5.03.1.1 性能描述
1. 供电电压:3-5.5V
2. 供电电流:最大2.5mA
3. 温度范围:0-50℃ 偏差±2℃
4. 湿度范围:20-90%RH 偏差±5%RH
5. 响应时间: 1/e(63%) 6-30s
6. 测量分辨率分别为 8bit(温度)、8bit(湿度)
7. 采样周期间隔不得低于1 秒钟
8. 模块尺寸:30x20mm
注释:建议链接线长度短于20米时使用5K上拉电阻,大于20米时根据实际状况使用合适的上拉电阻。
5.03.1.2 传感器时序
DATA 用于微处理器与 DHT11之间的通信和同步,采用单总线数据格式,一次通信时间4ms左右,数据分小数部分和整数部分,具体格式在下面说明,当前小数部分用于之后扩展,现读出为零.操做流程以下:
一次完整的数据传输为40bit,高位先出。
数据格式:
8bit湿度整数数据+8bit湿度小数数据
+8bi温度整数数据+8bit温度小数数据
+8bit校验和
数据传送正确时校验和数据等于“8bit湿度整数数据+8bit湿度小数数据+8bi温度整数数据+8bit温度小数数据”所得结果的末8位。
用户MCU发送一次开始信号后,DHT11从低功耗模式转换到高速模式,等待主机开始信号结束后,DHT11发送响应信号,送出40bit的数据,并触发一次信号采集,用户可选择读取部分数据.从模式下,DHT11接收到开始信号触发一次温湿度采集,若是没有接收到主机发送开始信号,DHT11不会主动进行温湿度采集.采集数据后转换到低速模式。
通信过程如图
总线空闲状态为高电平,主机把总线拉低等待DHT11响应,主机把总线拉低必须大于18毫秒,保证DHT11能检测到起始信号。DHT11接收到主机的开始信号后,等待主机开始信号结束,而后发送80us低电平响应信号.主机发送开始信号结束后,延时等待20-40us后, 读取DHT11的响应信号,主机发送开始信号后,能够切换到输入模式,或者输出高电平都可, 总线由上拉电阻拉高。
总线为低电平,说明DHT11发送响应信号,DHT11发送响应信号后,再把总线拉高80us,准备发送数据,每一bit数据都以50us低电平时隙开始,高电平的长短定了数据位是0仍是1.格式见下面图示.若是读取响应信号为高电平,则DHT11没有响应,请检查线路是否链接正常.当最后一bit数据传送完毕后,DHT11拉低总线50us,随后总线由上拉电阻拉高进入空闲状态。
5.03.2 实验目的
1. 掌握温度采集模块DHT11的工做原理;
2. 掌握单片机实现温度采集模块DHT11数据采集的基本方法,其中包括硬件和软件实现两部分;
3. 熟悉单片机数据采集系统中,温度采集模块DHT11做为传感器对象的系统设计方法。
5.03.3 硬件设计
选用大黄蜂实验板,温度采集模块DHT11是成品模块,直接插接到实验板上便可。硬件设计见“图5.03.5 温度采集模块DHT11连线图”。
5.03.4 软件设计
5.03.4.1 软件设计说明
温度采集模块DHT11是成品模块,直接插接到实验板上便可。按照上一章介绍的工做原理,咱们就能够按照工做时序编写出数据采集程序。咱们仍是采用库函数的方式进行程序设计。
在这节程序设计中,用到了外部中断函数;prinif 重定向打印输出函数; USART串口通信函数;定时器函数。
5.03.4.2 STM32库函数文件
?
本节实验及之后的实验咱们都是用到库文件,其中 stm32f10x_gpio.h头文件包含了GPIO端口的定义。stm32f10x_rcc.h 头文件包含了系统时钟配置函数以及相关的外设时钟使能函数,因此咱们要把这两个头文件对应的stm32f10x_gpio.c和stm32f10x_rcc.c加到工程中;Misc.c库函数主要包含了中断优先级的设置,stm32f10x_exti.c 库函数主要包含了外部中断设置参数,tm32f10x_tim.c库函数主要包含定时器设置,tm32f10x_usart.c库函数主要包含串行通信设置,这些函数也要添加到函数库中。以上库文件包含了本次实验全部要用到的函数使用功能。
5.03.4.3 自定义头文件
咱们在每一个工程设计中都要建立了两个公共的文件,这两个文件主要存放咱们自定义的公共函数和全局变量,以方便之后每一个功能模块(函数)之间传递参数。
5.03.4.4 pbdata.h文件里的内容是
语句 #ifndef、#endif是为了防止pbdata.h文件被多个文件调用时出现错误提示。若是不加这两条语句,当两个文件同时调用pbdata文件时,会提示重复调用错误。
5.03.4.5 pbdata.c文件里的内容是
下面是pbdata.c文件详细内容,在文件开始仍是引用“pbdata.h”文件。
5.03.5 STM32系统时钟配置SystemInit()
在每一个工程中必须在开始时配置并启动STM32系统时钟,这是基础,此次也不例外。
5.03.6 GPIO引脚时钟使能
5.03.7 GPIO管脚电平控制函数
在主程序中采用while(1)循环语句,采用查询方式不停的读取温湿度数据,而后直接经过串口送打印输出到屏幕。
while(1) { DHT11_Read_Data(&wd,&sd);//读取温湿度值 printf("当前环境温度: %d ℃\r\n",wd); printf("当前环境湿度: %d %%\r\n",sd); delay_ms(1000); delay_ms(1000); }
5.03.8 stm32f10x_it.c文件里的内容是
在中断处理stm32f10x_it.c文件里中仅串口1子函数非空,进入中断处理函数后,只有串口1有参数输出。
#include "stm32f10x_it.h" #include "stm32f10x_exti.h" #include "stm32f10x_rcc.h" #include "misc.h" #include "pbdata.h" void NMI_Handler(void) { } void USART1_IRQHandler(void) { if(USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET) { USART_SendData(USART1,USART_ReceiveData(USART1)); while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET); } }
5.03.9 dht11.h文件里的内容是
函数dht11.h在这里是为符合温湿度模块功能自定义的专用功能函数,dht11.h的内容以下:
#ifndef __DHT11_H #define __DHT11_H #include "pbdata.h" #define IO_DHT11 GPIO_Pin_4 //引入中间变量,方便移植 #define GPIO_DHT11 GPIOE //引入中间变量,方便移植 #define DHT11_DQ_High GPIO_SetBits(GPIO_DHT11,IO_DHT11) #define DHT11_DQ_Low GPIO_ResetBits(GPIO_DHT11,IO_DHT11) void DHT11_IO_OUT(void);//温湿度模块输出函数 void DHT11_IO_IN(void); //温湿度模块输入函数 void DHT11_Init(void); //初始化DHT11 u8 DHT11_Read_Data(u8 *temp,u8 *humi);//读取温湿度 u8 DHT11_Read_Byte(void); //读出一个字节 u8 DHT11_Read_Bit(void); //读出一个位 u8 DHT11_Check(void); //检测是否存在DHT11 void DHT11_Rst(void); //复位DHT11 #endif
5.03.10 dht11.c文件里的内容是
自定义函数dht11.c的内容以下:
#include "pbdata.h" void DHT11_IO_IN(void)//温湿度模块输入函数 { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin=IO_DHT11; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING; GPIO_Init(GPIO_DHT11,&GPIO_InitStructure); } void DHT11_IO_OUT(void)//温湿度模块输出函数 { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin=IO_DHT11; GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP; GPIO_Init(GPIO_DHT11,&GPIO_InitStructure); } //复位DHT11 void DHT11_Rst(void) { DHT11_IO_OUT(); //SET OUTPUT DHT11_DQ_Low; //DQ=0 delay_ms(20); //拉低至少18ms DHT11_DQ_High; //DQ=1 delay_us(30); //主机拉高20~40us } //等待DHT11的回应 //返回1:未检测到DHT11的存在 //返回0:存在 u8 DHT11_Check(void) { u8 retry=0;//定义临时变量 DHT11_IO_IN();//SET INPUT while ((GPIO_ReadInputDataBit(GPIO_DHT11,IO_DHT11)==1)&&retry<100)//DHT11会拉低40~80us { retry++; delay_us(1); }; if(retry>=100)return 1; else retry=0; while ((GPIO_ReadInputDataBit(GPIO_DHT11,IO_DHT11)==0)&&retry<100)//DHT11拉低后会再次拉高40~80us { retry++; delay_us(1); }; if(retry>=100)return 1; return 0; } //从DHT11读取一个位 //返回值:1/0 u8 DHT11_Read_Bit(void) { u8 retry=0; while((GPIO_ReadInputDataBit(GPIO_DHT11,IO_DHT11)==1)&&retry<100)//等待变为低电平 { retry++; delay_us(1); } retry=0; while((GPIO_ReadInputDataBit(GPIO_DHT11,IO_DHT11)==0)&&retry<100)//等待变高电平 { retry++; delay_us(1); } delay_us(40);//等待40us if(GPIO_ReadInputDataBit(GPIO_DHT11,IO_DHT11)==1) return 1; else return 0; } //从DHT11读取一个字节 //返回值:读到的数据 u8 DHT11_Read_Byte(void) { u8 i,dat; dat=0; for (i=0;i<8;i++) { dat<<=1; dat|=DHT11_Read_Bit(); } return dat; } //从DHT11读取一次数据 //temp:温度值(范围:0~50°) //humi:湿度值(范围:20%~90%) //返回值:0,正常;1,读取失败 u8 DHT11_Read_Data(u8 *temp,u8 *humi) { u8 buf[5]; u8 i; DHT11_Rst(); if(DHT11_Check()==0) { for(i=0;i<5;i++)//读取40位数据 { buf[i]=DHT11_Read_Byte(); } if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4]) { *humi=buf[0]; *temp=buf[2]; } }else return 1; return 0; } //初始化DHT11的IO口 DQ 同时检测DHT11的存在 //返回1:不存在 //返回0:存在 void DHT11_Init(void) { DHT11_Rst(); //复位DHT11 DHT11_Check();//等待DHT11的回应 } 5.03.11 main.c文件里的内容是 #include "pbdata.h" void RCC_Configuration(void); void GPIO_Configuration(void); void NVIC_Configuration(void); void USART_Configuration(void); int fputc(int ch,FILE *f) { USART_SendData(USART1,(u8)ch); while(USART_GetFlagStatus(USART1,USART_FLAG_TXE)==RESET); return ch; } int main(void) { u8 wd=0; u8 sd=0; RCC_Configuration();//系统时钟初始化 GPIO_Configuration();//端口初始化 USART_Configuration(); NVIC_Configuration(); DHT11_Init(); while(1) { DHT11_Read_Data(&wd,&sd);//读取温湿度值 printf("当前环境温度: %d ℃\r\n",wd); printf("当前环境湿度: %d %%\r\n",sd); delay_ms(1000); delay_ms(1000); } } void RCC_Configuration(void) { SystemInit();//72m RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1,ENABLE); RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE); } void GPIO_Configuration(void) { GPIO_InitTypeDef GPIO_InitStructure; GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;//TX GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz; GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP; GPIO_Init(GPIOA,&GPIO_InitStructure); GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;//RX GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA,&GPIO_InitStructure); } void NVIC_Configuration(void) { NVIC_InitTypeDef NVIC_InitStructure; NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1); NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; NVIC_InitStructure.NVIC_IRQChannelSubPriority = 1; NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; NVIC_Init(&NVIC_InitStructure); } void USART_Configuration(void) { USART_InitTypeDef USART_InitStructure; USART_InitStructure.USART_BaudRate=9600; USART_InitStructure.USART_WordLength=USART_WordLength_8b; USART_InitStructure.USART_StopBits=USART_StopBits_1; USART_InitStructure.USART_Parity=USART_Parity_No; USART_InitStructure.USART_HardwareFlowControl=USART_HardwareFlowControl_None; USART_InitStructure.USART_Mode=USART_Mode_Rx|USART_Mode_Tx; USART_Init(USART1,&USART_InitStructure); USART_ITConfig(USART1,USART_IT_RXNE,ENABLE); USART_Cmd(USART1,ENABLE); USART_ClearFlag(USART1,USART_FLAG_TC); }
5.03.12 程序下载
在这一章节中要掌握DHT11温湿度传感器工做时序,了解经常使用的温湿度传感器功能和原理。
请根据下图所指向的7个重点区域配置。其中(1)号区域根据本身机器的实际状况选择,个人机器虚拟出来的串口号是COM3。(2)号区域请本身选择程序代码所在的文件夹。(7)号区域当程序下载完后,进度条会到达最右边,而且提示一切正常。(四、五、6)号区域必定要按照上图显示的设置。当都设置好之后就能够直接点击(3)号区域的开始编程按钮下传程序了。
本节实验的源代码在光盘中:(LY-STM32 光盘资料\1.课程\2,外设篇\模块篇 03.温湿度传感器模块(DHT11)\程序)
5.03.13 实验效果图
打开众想科技多功能监控软件,接着打开串口,咱们在接收区能够观察到实测采集到周围环境的温湿度数据,周围环境的温度大约 摄氏度左右、湿度是 左右,说明咱们温湿度模块工做正常,程序编写和设计思路吻合。