DHT11主要代码
同时上传一份在CSDN资源中,没有积分可以微信扫码回复“DHT11”获得百度网盘链接
下面贴出dht11的主要代码和在main中的使用代码
会移植的自行移植就不用下载工程了
bsp_dht11.h
#ifndef __DHT11_H#define__DHT11_H#include "stm32f10x.h"#include "delay.h"#define HIGH 1#define LOW 0#define DHT11_CLKRCC_APB2Periph_GPIOC#define DHT11_PINGPIO_Pin_4 #define DHT11_PORTGPIOC //带参宏,可以像内联函数一样使用,输出高电平或低电平#define DHT11_DATA_OUT(a)if (a)\GPIO_SetBits(GPIOC,GPIO_Pin_4);\else\GPIO_ResetBits(GPIOC,GPIO_Pin_4)//读取引脚的电平#define DHT11_DATA_IN() GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_4)typedef struct{uint8_t humi_int;//湿度的整数部分uint8_t humi_deci; //湿度的小数部分uint8_t temp_int; //温度的整数部分uint8_t temp_deci; //温度的小数部分uint8_t check_sum; //校验和}DHT11_Data_TypeDef;void DHT11_GPIO_Config(void);static void DHT11_Mode_IPU(void);static void DHT11_Mode_Out_PP(void);uint8_t Read_DHT11(DHT11_Data_TypeDef *DHT11_Data);static uint8_t Read_Byte(void);#endif /* __DHT11_H */
bsp_dht11.c
#include "bsp_dht11.h"/** 函数名:DHT11_GPIO_Config* 描述 :配置DHT11用到的I/O口* 输入 :无* 输出 :无*/void DHT11_GPIO_Config(void){/*定义一个GPIO_InitTypeDef类型的结构体*/GPIO_InitTypeDef GPIO_InitStructure;/*开启DHT11_PORT的外设时钟*/RCC_APB2PeriphClockCmd(DHT11_CLK, ENABLE); /*选择要控制的DHT11_PORT引脚*/ GPIO_InitStructure.GPIO_Pin = DHT11_PIN;/*设置引脚模式为通用推挽输出*/GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; /*设置引脚速率为50MHz */ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; /*调用库函数,初始化DHT11_PORT*/GPIO_Init(DHT11_PORT, &GPIO_InitStructure); /* 拉高GPIOC 4*/GPIO_SetBits(DHT11_PORT, GPIO_Pin_4); }/** 函数名:DHT11_Mode_IPU* 描述 :使DHT11-DATA引脚变为上拉输入模式* 输入 :无* 输出 :无*/static void DHT11_Mode_IPU(void){GPIO_InitTypeDef GPIO_InitStructure;/*选择要控制的DHT11_PORT引脚*/GPIO_InitStructure.GPIO_Pin = DHT11_PIN;/*设置引脚模式为浮空输入模式*/ GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ; /*调用库函数,初始化DHT11_PORT*/GPIO_Init(DHT11_PORT, &GPIO_InitStructure); }/** 函数名:DHT11_Mode_Out_PP* 描述 :使DHT11-DATA引脚变为推挽输出模式* 输入 :无* 输出 :无*/static void DHT11_Mode_Out_PP(void){GPIO_InitTypeDef GPIO_InitStructure;/*选择要控制的DHT11_PORT引脚*/ GPIO_InitStructure.GPIO_Pin = DHT11_PIN;/*设置引脚模式为通用推挽输出*/GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; /*设置引脚速率为50MHz */ GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;/*调用库函数,初始化DHT11_PORT*/GPIO_Init(DHT11_PORT, &GPIO_InitStructure); }/* * 从DHT11读取一个字节,MSB先行*/static uint8_t Read_Byte(void){uint8_t i, temp=0;for(i=0;i<8;i++) {/*每bit以50us低电平标置开始,轮询直到从机发出 的50us 低电平 结束*/ while(DHT11_DATA_IN()==Bit_RESET);/*DHT11 以26~28us的高电平表示“0”,以70us高电平表示“1”,*通过检测 x us后的电平即可区别这两个状 ,x 即下面的延时 */delay_us(40); //延时x us 这个延时需要大于数据0持续的时间即可if(DHT11_DATA_IN()==Bit_SET)/* x us后仍为高电平表示数据“1” */{/* 等待数据1的高电平结束 */while(DHT11_DATA_IN()==Bit_SET);temp|=(uint8_t)(0x01<<(7-i)); //把第7-i位置1,MSB先行 }else // x us后为低电平表示数据“0”{temp&=(uint8_t)~(0x01<<(7-i)); //把第7-i位置0,MSB先行}}return temp;}/** 一次完整的数据传输为40bit,高位先出* 8bit 湿度整数 + 8bit 湿度小数 + 8bit 温度整数 + 8bit 温度小数 + 8bit 校验和 */uint8_t Read_DHT11(DHT11_Data_TypeDef *DHT11_Data){/*输出模式*/DHT11_Mode_Out_PP();/*主机拉低*/DHT11_DATA_OUT(LOW);/*延时18ms*/delay_ms(18);/*总线拉高 主机延时30us*/DHT11_DATA_OUT(HIGH); delay_us(30); //延时30us/*主机设为输入 判断从机响应信号*/ DHT11_Mode_IPU();/*判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行*/ if(DHT11_DATA_IN()==Bit_RESET){/*轮询直到从机发出 的80us 低电平 响应信号结束*/ while(DHT11_DATA_IN()==Bit_RESET);/*轮询直到从机发出的 80us 高电平 标置信号结束*/while(DHT11_DATA_IN()==Bit_SET);/*开始接收数据*/ DHT11_Data->humi_int= Read_Byte();DHT11_Data->humi_deci= Read_Byte();DHT11_Data->temp_int= Read_Byte();DHT11_Data->temp_deci= Read_Byte();DHT11_Data->check_sum= Read_Byte();/*读取结束,引脚改为输出模式*/DHT11_Mode_Out_PP();/*主机拉高*/DHT11_DATA_OUT(HIGH);/*检查读取的数据是否正确*/if(DHT11_Data->check_sum == DHT11_Data->humi_int + DHT11_Data->humi_deci + DHT11_Data->temp_int+ DHT11_Data->temp_deci)return SUCCESS;else return ERROR;}else{return ERROR;} }/*************************************END OF FILE******************************/
在mian.c中串口显示的调用
#include "sys.h"#include "delay.h"#include "usart.h"#include "bsp_dht11.h"DHT11_Data_TypeDef DHT11_Data;uint16_t times=0;int main(void){delay_init();//延时函数初始化 uart_init(115200); //串口初始化为115200DHT11_GPIO_Config();delay_ms(500);while(1){/*调用Read_DHT11读取温湿度,若成功则输出该信息*/if( Read_DHT11(&DHT11_Data)==SUCCESS){printf("\r\n读取DHT11成功!\r\n\r\n湿度为%d.%d %RH ,温度为 %d.%d℃ \r\n",\DHT11_Data.humi_int,DHT11_Data.humi_deci,DHT11_Data.temp_int,DHT11_Data.temp_deci);delay_ms(1500);/* 1s 读取一次温度值 */}else{printf("Read DHT11 ERROR!\r\n");//读取数据失败,串口打印:Read DHT11 ERROR.}}}
串口显示效果:
注意小事项:
代码写入后可能在串口助手没有显示,可以按下单片机上的复位或者重新拔插一下串口