赞
踩
DATA 用于微处理器与 DHT11之间的通讯和同步,采用单总线数据格式,一次
通讯时间4ms左右,数据分小数部分和整数部分,具体格式在下面说明,当前小数
部分用于以后扩展,现读出为零.操作流程如下:
一次完整的数据传输为40bit,高位先出。
数据格式:8bit湿度整数数据+8bit湿度小数数据
+8bi温度整数数据+8bit温度小数数据
+8bit校验和
数据传送正确时校验和数据等于“8bit湿度整数数据+8bit湿度小数数据
+8bi温度整数数据+8bit温度小数数据” 所得结果的末8位。
用户MCU发送一次开始信号后,DHT11从低功耗模式转换到速模式,等待主
机开始信号结束后,DHT11发送响应信号,送出40bit的数据,并触发一次信号采集,
用户可选择读取部分数据.从模式下,DHT11接收到开始信号触发一次温湿度采集,
如果没有接收到主机发送开始信号,DHT11不会主动进行温湿度采集.采集数据后
转换到低速模式.
直接上代码
- //main程序
- #include "stdio.h"
- #include "stm32f10x.h"
- #include "USART.h"
- #include "dht11.h"
- #include "Delay.h"
-
- extern u8 dat[5];
-
- int main(void)
- {
- uart1_init();
-
-
-
- printf( "串口printf函数测试\n" );
-
-
- while (1)
- {
-
- if(DHT_Read())
- printf("湿度:%d%%,温度:%d度\r\n",dat[0],dat[2]);
- //printf("湿度:%d.%d%%,温度:%d.%d度\r\n",dat[0],dat[1],dat[2],dat[3]); 显示小数
- Delay_ms(3000);
- }
- }
- //UART1.C程序
- #include "stm32f10x.h" // Device header
- #include "stdio.h"
- #include "USART.h"
- u8 Recse;
- void uart1_init(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- USART_InitTypeDef USART_InitStructure;
- NVIC_InitTypeDef NVIC_InitStructure;
-
- RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE);
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
-
- USART_InitStructure.USART_BaudRate = 9600; //波特率
- USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//不进行硬件流控制
- USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;//模式为接收和发送双向
- USART_InitStructure.USART_Parity = USART_Parity_No;//不校验
- USART_InitStructure.USART_StopBits = USART_StopBits_1;//停止1位
- USART_InitStructure.USART_WordLength = USART_WordLength_8b;//数据8位
- USART_Init(USART1, &USART_InitStructure);
-
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;//输出复用推挽
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
-
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//输入复用浮空
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
- GPIO_Init(GPIOA, &GPIO_InitStructure);
-
- USART_Cmd(USART1, ENABLE);//使能串口1
-
- }
-
-
- /* 重定向printf函数 */
- int fputc(int ch, FILE *f)
- {
- while (USART_GetFlagStatus(USART1, USART_FLAG_TXE) == RESET);
- USART_SendData(USART1,ch);
- /* 等待发送完毕 */
- return ch;
- }
-
- //UART.H程序
- #ifndef __USART_H
- #define __USART_H
-
- void uart1_init(void);
-
-
- #endif
- //dht11.c程序
- #include "dht11.h"
- #include "Delay.h"
-
- uint8_t dat[5]={0x00,0x00,0x00,0x00,0x00};
- uint8_t sum=0;
-
- //初始化为输出
- void DHT11_GPIO_OUT(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
-
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- }
- //初始化为输入
- void DHT11_GPIO_IN(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
-
- RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
-
- GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
- GPIO_Init(GPIOB, &GPIO_InitStructure);
- }
-
- //读一个字节
- uint8_t DHT_Read_Byte(void)
- {
- uint8_t temp;
- uint8_t ReadDat=0;
-
- uint8_t retry = 0;
- uint8_t i;
-
- for(i=0;i<8;i++)
- {
- //数据信号低电平50us
- while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)==0&&retry<100)
- {
- Delay_us(1);
- retry++;
- }
- retry=0;
- Delay_us(30);
- temp=0;//数字信号0,temp=0
- //数字0信号高电平持续28us,数字1信号高电平70us,延时30us以确认数字0或1
- if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)==1) temp=1;
- while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)==1&&retry<100)//数字1信号高电平剩余40us
- {
- Delay_us(1);
- retry++;
- }
- retry=0;
- ReadDat<<=1;
- ReadDat|=temp;
- }
- return ReadDat;
- }
-
- uint8_t DHT_Read(void)
- {
- uint8_t i;
- uint8_t retry = 0;
-
- //主机设置为输出,发送开始信号低电平18ms,高电平40us
- DHT11_GPIO_OUT();
- GPIO_ResetBits(GPIOB,GPIO_Pin_14);
- Delay_ms(18);
- GPIO_SetBits(GPIOB,GPIO_Pin_14);
- Delay_us(40);
- //主机设置为输入,检查并接收响应信号低电平80us,高电平80us
- DHT11_GPIO_IN();
- Delay_us(20);
- //延时20us,低电平80us,还剩60us,检查是否是低电平以确定是否有响应信号
- if(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)==0)
- {
- while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)==0&&retry<100)//接收响应信号低电平剩余60us
- {
- Delay_us(1);
- retry++;
- }
- retry=0;//超过100us自动向下运行,以免卡死
- while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)==1&&retry<100)//接收响应信号高电平80us
- {
- Delay_us(1);
- retry++;
- }
- retry=0;
- //接收8字节数据
- for(i=0;i<5;i++)
- {
- dat[i]=DHT_Read_Byte();
- }
- Delay_us(50);//DHT11拉低总线50us作为结束信号,或者使用以下语句
-
- // while(GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_14)==0&&retry<100)//接收响应信号低电平剩余60us
- // {
- // SysTick_Delay_us(1);
- // retry++;
- // }
- // retry=0;
-
- }
- sum=dat[0]+dat[1]+dat[2]+dat[3];
- if(dat[4]==sum)
- {
- return 1;
- }
- else
- return 0;
- }
- //dth11.h程序
- #ifndef __DHT11_H
- #define __DHT11_H
-
- #include "stm32f10x.h"
-
-
- void DHT11_GPIO_OUT(void);
- void DHT11_GPIO_IN(void);
- uint8_t DHT_Read_Byte(void);
- uint8_t DHT_Read(void);
-
- #endif
- //Delay.c程序
- #include "stm32f10x.h"
-
- /**
- * @brief 微秒级延时
- * @param xus 延时时长,范围:0~233015
- * @retval 无
- */
- void Delay_us(uint32_t xus)
- {
- SysTick->LOAD = 72 * xus; //设置定时器重装值
- SysTick->VAL = 0x00; //清空当前计数值
- SysTick->CTRL = 0x00000005; //设置时钟源为HCLK,启动定时器
- while(!(SysTick->CTRL & 0x00010000)); //等待计数到0
- SysTick->CTRL = 0x00000004; //关闭定时器
- }
-
- /**
- * @brief 毫秒级延时
- * @param xms 延时时长,范围:0~4294967295
- * @retval 无
- */
- void Delay_ms(uint32_t xms)
- {
- while(xms--)
- {
- Delay_us(1000);
- }
- }
-
- /**
- * @brief 秒级延时
- * @param xs 延时时长,范围:0~4294967295
- * @retval 无
- */
- void Delay_s(uint32_t xs)
- {
- while(xs--)
- {
- Delay_ms(1000);
- }
- }
- //Delay.h程序
- #ifndef __DELAY_H
- #define __DELAY_H
-
- void Delay_us(uint32_t us);
- void Delay_ms(uint32_t ms);
- void Delay_s(uint32_t s);
-
- #endif
-
上结果图
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。