找回密码
 注册

QQ登录

只需一步,快速开始

搜索

基于STM32F103的DHT11完美配置例程

[复制链接]
路漫漫 发表于 2020-6-4 01:11:10 | 显示全部楼层 |阅读模式
  1. DHT11头文件:
  2. #ifndef _DHT11_H_
  3. #define _DHT11_H_

  4. #include "stm32f10x.h"
  5. #include "bitband_cm3.h" // 位带操作头文件

  6. #define DHT11_REV_DATA  PBin(6)
  7. #define DHT11_SEND_DATA PBout(6)

  8. void DHT11_Init(void);
  9. int DHT11_Read_Data(uint8_t *Temp_H,uint8_t* Temp_L,uint8_t* RH_H,uint8_t* RH_L);



  10. #endif



  11. DHT11源文件:
  12. #include "dht11.h"
  13. #include "systick.h"
  14. #if 0  //0---库函数  1---寄存器
  15. // DTH11  ---> PB6
  16. // 输出模式
  17. void DHT11_OUT(void)
  18. {
  19.   GPIOB->CRL &=~ (0xf<<24);
  20.         GPIOB->CRL |=  (3<<24);//通用推挽输出模式 50M
  21. }

  22. // 输入模式
  23. void DHT11_IN(void)  
  24. {
  25.         GPIOB->CRL &=~ (0xf<<24);
  26.         GPIOB->CRL |=  (4<<24);//配置浮空输入(外接上拉电阻)
  27. }

  28. //DHT11初始化
  29. void DHT11_Init(void)
  30. {
  31.         RCC->APB2ENR |= (1<<3); // 开启PB端口时钟
  32.         DHT11_IN( );// DHT11 的DATA 引脚处于输入状态,时刻检测外部信号
  33.         delay_ms(500);
  34.         delay_ms(500);//DHT11 上电后要等待 1S 以越过不稳定状态在此期间不能发送任何指令
  35. }
  36. #else
  37. // DTH11  ---> PB6
  38. // 输出模式
  39. void DHT11_OUT(void)
  40. {
  41.         GPIO_InitTypeDef GPIO_InitStruct;
  42.         GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6;
  43.         GPIO_InitStruct.GPIO_Mode=GPIO_Mode_Out_PP;//通用推挽输出
  44.         GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;//50M
  45.         GPIO_Init(GPIOB, &GPIO_InitStruct);//PB6
  46. }

  47. // 输入模式
  48. void DHT11_IN(void)  
  49. {
  50.         GPIO_InitTypeDef GPIO_InitStruct;
  51.         GPIO_InitStruct.GPIO_Pin=GPIO_Pin_6;
  52.         GPIO_InitStruct.GPIO_Mode=GPIO_Mode_IN_FLOATING;//配置浮空输入(外接上拉电阻)
  53.         GPIO_InitStruct.GPIO_Speed=GPIO_Speed_50MHz;//50M
  54.         GPIO_Init(GPIOB, &GPIO_InitStruct);//PB6
  55. }

  56. //DHT11初始化
  57. void DHT11_Init(void)
  58. {
  59.         RCC->APB2ENR |= (1<<3); // 开启PB端口时钟
  60.         RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);//开启PB端口时钟.
  61.         DHT11_IN( );// DHT11 的DATA 引脚处于输入状态,时刻检测外部信号
  62.         delay_ms(500);
  63.         delay_ms(500);//DHT11 上电后要等待 1S 以越过不稳定状态在此期间不能发送任何指令
  64. }
  65. #endif
  66. //起始信号
  67. void DHT11_Start(void)
  68. {
  69.         DHT11_SEND_DATA=0;
  70.         delay_ms(18);
  71.         DHT11_SEND_DATA=1;
  72.         delay_us(20);//释放总线
  73. }

  74. //应答信号
  75. //返回值 0--无应答  1--有应答
  76. u8 DHT11_Ack(void)
  77. {
  78.         if(DHT11_REV_DATA!=0)
  79.         {
  80.                 return 0;
  81.         }
  82.         while(DHT11_REV_DATA==0);//等待80us低电平应答结束
  83.       
  84.         while(DHT11_REV_DATA==1);//等待80us高电平应答结束
  85.       
  86.         return 1;
  87. }

  88. //读取一个字节数据
  89. u8 DHT11_Read_Byte(void)
  90. {
  91.         u8 data=0;
  92.         u8 i;
  93.         //接受数据,每个数据以50us低电平开始
  94.         for(i=0;i<8;i++)
  95.         {
  96.                 data <<= 1;
  97.                 while(!DHT11_REV_DATA);//等待发送数据的时序变为高电平
  98.                 delay_us(40);//23~27u为数据0,68~74us为u数据1
  99.                 if(DHT11_REV_DATA==1)
  100.                 {
  101.                         data |=1;//数据1
  102.                         while(DHT11_REV_DATA);//等待高电平应答结束
  103.                 }
  104.         }
  105.         return data;
  106. }

  107. //读取温湿度
  108. int DHT11_Read_Data(u8 *Temp_H,u8* Temp_L,u8* RH_H,u8* RH_L)
  109. {
  110.         u8 check;
  111.         DHT11_OUT( );
  112.         DHT11_Start( );
  113.         DHT11_IN( );//切换为输入
  114.         if( DHT11_Ack( )==0 )
  115.         {
  116.                 return -1;
  117.         }
  118.       
  119.         //读取数据
  120.         *RH_H=DHT11_Read_Byte( );
  121.         *RH_L=DHT11_Read_Byte( );
  122.         *Temp_H=DHT11_Read_Byte( );
  123.         *Temp_L=DHT11_Read_Byte( );
  124.         check=DHT11_Read_Byte( );      
  125.       
  126.         //结束读取
  127.         delay_ms(50);
  128.         DHT11_OUT( );//切换为输出
  129.         DHT11_SEND_DATA=1;//释放总线
  130.       
  131.         //校验数据
  132.         if(check !=(*Temp_H+*Temp_L+*RH_H+*RH_L) )
  133.         {
  134.                 return -2;
  135.         }
  136.         return 0;
  137. }
复制代码


您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|手机版|小黑屋|ELEOK |网站地图

GMT+8, 2024-12-22 10:24

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表