stm32+dht11温湿度数据实验-stm32将采集dht11温湿度通过usart1在串口助手打印

网上其实已经介绍了很多dht11这种单线通讯协议

这里就不多重复大佬们的工作了,直接上keil5工程

keil5工程百度网盘链接:https://pan.baidu.com/s/1HDNe7gUM_dplRzR_j17wtA 

提取码:xpfj

另外我把dht11.c和dht11.h直接贴在下面,小伙伴可以直接移植到自己的代码中就行了

之后会把stm32的两个实验组合起来实现一个简单的室内温度计,温湿度数据显示在oled上,学以致用嘛

岂不美哉

 1 #ifndef __DHT11_H
 2 #define    __DHT11_H
 3 
 4 #include "stm32f10x.h"
 5 #include "delay.h"
 6 
 7 #define HIGH  1
 8 #define LOW   0
 9 
10 #define DHT11_CLK     RCC_APB2Periph_GPIOC
11 #define DHT11_PIN     GPIO_Pin_4                  
12 #define DHT11_PORT        GPIOC 
13 
14 //带参宏,可以像内联函数一样使用,输出高电平或低电平
15 #define DHT11_DATA_OUT(a)    if (a)    \
16                     GPIO_SetBits(GPIOC,GPIO_Pin_4);\
17                     else        \
18                     GPIO_ResetBits(GPIOC,GPIO_Pin_4)
19  //读取引脚的电平
20 #define  DHT11_DATA_IN()       GPIO_ReadInputDataBit(GPIOC,GPIO_Pin_4)
21 
22 typedef struct
23 {
24     uint8_t  humi_int;        //湿度的整数部分
25     uint8_t  humi_deci;         //湿度的小数部分
26     uint8_t  temp_int;         //温度的整数部分
27     uint8_t  temp_deci;         //温度的小数部分
28     uint8_t  check_sum;         //校验和
29                          
30 }DHT11_Data_TypeDef;
31 
32 void DHT11_GPIO_Config(void);
33 static void DHT11_Mode_IPU(void);
34 static void DHT11_Mode_Out_PP(void);
35 uint8_t Read_DHT11(DHT11_Data_TypeDef *DHT11_Data);
36 static uint8_t Read_Byte(void);
37 
38 #endif /* __DHT11_H */
bsp_dht11.h
  1 #include "bsp_dht11.h"
  2 
  3 
  4 /*
  5  * 函数名:DHT11_GPIO_Config
  6  * 描述  :配置DHT11用到的I/O口
  7  * 输入  :无
  8  * 输出  :无
  9  */
 10 void DHT11_GPIO_Config(void)
 11 {        
 12     /*定义一个GPIO_InitTypeDef类型的结构体*/
 13     GPIO_InitTypeDef GPIO_InitStructure;
 14 
 15     /*开启DHT11_PORT的外设时钟*/
 16     RCC_APB2PeriphClockCmd(DHT11_CLK, ENABLE); 
 17 
 18     /*选择要控制的DHT11_PORT引脚*/                                                               
 19       GPIO_InitStructure.GPIO_Pin = DHT11_PIN;    
 20 
 21     /*设置引脚模式为通用推挽输出*/
 22       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   
 23 
 24     /*设置引脚速率为50MHz */   
 25       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
 26 
 27     /*调用库函数,初始化DHT11_PORT*/
 28       GPIO_Init(DHT11_PORT, &GPIO_InitStructure);          
 29 
 30     /* 拉高GPIOC 4    */
 31     GPIO_SetBits(DHT11_PORT, GPIO_Pin_4);     
 32 }
 33 
 34 /*
 35  * 函数名:DHT11_Mode_IPU
 36  * 描述  :使DHT11-DATA引脚变为上拉输入模式
 37  * 输入  :无
 38  * 输出  :无
 39  */
 40 static void DHT11_Mode_IPU(void)
 41 {
 42        GPIO_InitTypeDef GPIO_InitStructure;
 43 
 44           /*选择要控制的DHT11_PORT引脚*/    
 45       GPIO_InitStructure.GPIO_Pin = DHT11_PIN;
 46 
 47        /*设置引脚模式为浮空输入模式*/ 
 48       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU ; 
 49 
 50       /*调用库函数,初始化DHT11_PORT*/
 51       GPIO_Init(DHT11_PORT, &GPIO_InitStructure);     
 52 }
 53 
 54 /*
 55  * 函数名:DHT11_Mode_Out_PP
 56  * 描述  :使DHT11-DATA引脚变为推挽输出模式
 57  * 输入  :无
 58  * 输出  :无
 59  */
 60 static void DHT11_Mode_Out_PP(void)
 61 {
 62      GPIO_InitTypeDef GPIO_InitStructure;
 63 
 64          /*选择要控制的DHT11_PORT引脚*/                                                               
 65       GPIO_InitStructure.GPIO_Pin = DHT11_PIN;    
 66 
 67     /*设置引脚模式为通用推挽输出*/
 68       GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   
 69 
 70     /*设置引脚速率为50MHz */   
 71       GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 72 
 73     /*调用库函数,初始化DHT11_PORT*/
 74       GPIO_Init(DHT11_PORT, &GPIO_InitStructure);          
 75 }
 76 
 77 /* 
 78  * 从DHT11读取一个字节,MSB先行
 79  */
 80 static uint8_t Read_Byte(void)
 81 {
 82     uint8_t i, temp=0;
 83 
 84     for(i=0;i<8;i++)    
 85     {     
 86         /*每bit以50us低电平标置开始,轮询直到从机发出 的50us 低电平 结束*/  
 87         while(DHT11_DATA_IN()==Bit_RESET);
 88 
 89         /*DHT11 以26~28us的高电平表示“0”,以70us高电平表示“1”,
 90          *通过检测 x us后的电平即可区别这两个状 ,x 即下面的延时 
 91          */
 92         delay_us(40); //延时x us 这个延时需要大于数据0持续的时间即可             
 93 
 94         if(DHT11_DATA_IN()==Bit_SET)/* x us后仍为高电平表示数据“1” */
 95         {
 96             /* 等待数据1的高电平结束 */
 97             while(DHT11_DATA_IN()==Bit_SET);
 98 
 99             temp|=(uint8_t)(0x01<<(7-i));  //把第7-i位置1,MSB先行 
100         }
101         else     // x us后为低电平表示数据“0”
102         {               
103             temp&=(uint8_t)~(0x01<<(7-i)); //把第7-i位置0,MSB先行
104         }
105     }
106     return temp;
107 }
108 /*
109  * 一次完整的数据传输为40bit,高位先出
110  * 8bit 湿度整数 + 8bit 湿度小数 + 8bit 温度整数 + 8bit 温度小数 + 8bit 校验和 
111  */
112 uint8_t Read_DHT11(DHT11_Data_TypeDef *DHT11_Data)
113 {  
114     /*输出模式*/
115     DHT11_Mode_Out_PP();
116     /*主机拉低*/
117     DHT11_DATA_OUT(LOW);
118     /*延时18ms*/
119     delay_ms(18);
120 
121     /*总线拉高 主机延时30us*/
122     DHT11_DATA_OUT(HIGH); 
123 
124     delay_us(30);   //延时30us
125 
126     /*主机设为输入 判断从机响应信号*/ 
127     DHT11_Mode_IPU();
128 
129     /*判断从机是否有低电平响应信号 如不响应则跳出,响应则向下运行*/   
130     if(DHT11_DATA_IN()==Bit_RESET)     
131     {
132         /*轮询直到从机发出 的80us 低电平 响应信号结束*/  
133         while(DHT11_DATA_IN()==Bit_RESET);
134 
135         /*轮询直到从机发出的 80us 高电平 标置信号结束*/
136         while(DHT11_DATA_IN()==Bit_SET);
137 
138         /*开始接收数据*/   
139         DHT11_Data->humi_int= Read_Byte();
140 
141         DHT11_Data->humi_deci= Read_Byte();
142 
143         DHT11_Data->temp_int= Read_Byte();
144 
145         DHT11_Data->temp_deci= Read_Byte();
146 
147         DHT11_Data->check_sum= Read_Byte();
148 
149 
150         /*读取结束,引脚改为输出模式*/
151         DHT11_Mode_Out_PP();
152         /*主机拉高*/
153         DHT11_DATA_OUT(HIGH);
154 
155         /*检查读取的数据是否正确*/
156         if(DHT11_Data->check_sum == DHT11_Data->humi_int + DHT11_Data->humi_deci + DHT11_Data->temp_int+ DHT11_Data->temp_deci)
157             return SUCCESS;
158         else 
159             return ERROR;
160     }
161     else
162     {        
163         return ERROR;
164     }   
165 }
166 
167 /*************************************END OF FILE******************************/
bsp_dht11.c
 1 #include "sys.h"
 2 #include "delay.h"
 3 #include "usart.h"
 4 #include "bsp_dht11.h"
 5 
 6 DHT11_Data_TypeDef DHT11_Data;
 7 
 8 uint16_t times=0;
 9     
10 int main(void)
11 {    
12 
13     delay_init();     //延时函数初始化      
14     uart_init(115200);     //串口初始化为115200
15     DHT11_GPIO_Config();
16     delay_ms(500);
17     while(1)
18     {
19         /*调用Read_DHT11读取温湿度,若成功则输出该信息*/
20         if( Read_DHT11(&DHT11_Data)==SUCCESS)
21         {
22             printf("\r\n读取DHT11成功!\r\n\r\n湿度为%d.%d %RH ,温度为 %d.%d℃ \r\n",\
23             DHT11_Data.humi_int,DHT11_Data.humi_deci,DHT11_Data.temp_int,DHT11_Data.temp_deci);
24             delay_ms(1500);        /* 1s 读取一次温度值 */
25         }
26         else
27         {
28             printf("Read DHT11 ERROR!\r\n");//读取数据失败,串口打印:Read DHT11 ERROR.
29 
30         }
31     }    
32 }
main.c

把在串口助手显示的效果图也贴出来

坚持天天更新,今天也是充满希望的一天啊

 

 

猜你喜欢

转载自www.cnblogs.com/hjf-log/p/stm32-dht11.html