• 温湿度传感器DHT11:神舟IV


    DHT11与DS18B20很像,都是单总线。不过DHT11操作简单多了,不用查询ROM,不需要操作流程,初始化之后有需要时候读取数据就可以了。

    DHT11数字湿温度传感器采用单总线数据格式。即,单个数据引脚端口完成输入输出双向传输。其数据包由5Byte40Bit)组成。数据分小数部分和整数部分,一次完整的数据传输为40bit,高位先出。DHT11的数据格式为:8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据+8bit校验和。其中校验和数据为前四个字节相加。

    我们使用PE2作为DQ pin,宏定义操作与18B20一样

    .h
    1 //PE2作为DHT11的DQ pin
    2 #define DHT11_OUT_High  GPIO_SetBits(GPIOE, GPIO_Pin_2) 
    3 #define DHT11_OUT_Low   GPIO_ResetBits(GPIOE, GPIO_Pin_2)
    4 #define    DHT11_DQ_IN      GPIO_ReadInputDataBit(GPIOE, GPIO_Pin_2)
    DHT11_Init
     1 //初始化DHT11的IO口 DQ 同时检测DHT11的存在
     2 //返回1:不存在
     3 //返回0:存在         
     4 u8 DHT11_Init(void)
     5 {     
     6      GPIO_InitTypeDef  GPIO_InitStructure;
     7      
     8      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOE, ENABLE);     //使能PG端口时钟
     9     
    10      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;                 //PG11端口配置
    11      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;          //推挽输出
    12      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    13      GPIO_Init(GPIOE, &GPIO_InitStructure);                 //初始化IO口
    14      GPIO_SetBits(GPIOE,GPIO_Pin_2);                         //PG11 输出高
    15                 
    16     DHT11_Rst();  //复位DHT11
    17     return DHT11_Check();//等待DHT11的回应
    18 } 
    DHT11_Rst
    1 //复位DHT11
    2 void DHT11_Rst(void)       
    3 {                 
    4     DHT11_IO_OUT();     //SET OUTPUT
    5     DHT11_OUT_Low;         //拉低DQ
    6     delay_ms(20);        //拉低至少18ms
    7     DHT11_OUT_High;     //DQ=1 
    8     delay_us(30);         //主机拉高20~40us
    9 }
    DHT11_Check
     1 //等待DHT11的回应
     2 //返回1:未检测到DHT11的存在
     3 //返回0:存在
     4 u8 DHT11_Check(void)        
     5 {   
     6     u8 retry=0;
     7     DHT11_IO_IN();//SET INPUT     
     8     while (DHT11_DQ_IN&&retry<100)//DHT11会拉低40~80us
     9     {
    10         retry++;
    11         delay_us(1);
    12     };     
    13     if(retry>=100)return 1;
    14     else retry=0;
    15     while (!DHT11_DQ_IN&&retry<100)//DHT11拉低后会再次拉高40~80us
    16     {
    17         retry++;
    18         delay_us(1);
    19     };
    20     if(retry>=100)return 1;        
    21     return 0;
    22 }

    以上为初始化所用到的函数
    因为DHT11不需要发送指令,所以只是读取,很简单,没有了写操作

    DHT11_Read_Data
     1 //从DHT11读取一次数据
     2 //temp:温度值(范围:0~50°)
     3 //humi:湿度值(范围:20%~90%)
     4 //返回值:0,正常;1,读取失败
     5 u8 DHT11_Read_Data(u8 *temp,u8 *humi)    
     6 {        
     7      u8 buf[5];
     8     u8 i;
     9     DHT11_Rst();
    10     if(DHT11_Check()==0)
    11     {
    12         for(i=0;i<5;i++)//读取40位数据
    13         {
    14             buf[i]=DHT11_Read_Byte();
    15         }
    16         if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])
    17         {
    18             *humi=buf[0];
    19             *temp=buf[2];
    20         }
    21     }else return 1;
    22     return 0;        
    23 }
    DHT11_Read_Byte
     1 //从DHT11读取一个字节
     2 //返回值:读到的数据
     3 u8 DHT11_Read_Byte(void)    
     4 {        
     5     u8 i,dat;
     6     dat=0;
     7     for (i=0;i<8;i++) 
     8     {
     9            dat<<=1; 
    10         dat|=DHT11_Read_Bit();
    11     }                            
    12     return dat;
    13 }
    DHT11_Read_Bit
     1 //从DHT11读取一个位
     2 //返回值:1/0
     3 u8 DHT11_Read_Bit(void)              
     4 {
     5      u8 retry=0;
     6     while(DHT11_DQ_IN&&retry<100)//等待变为低电平
     7     {
     8         retry++;
     9         delay_us(1);
    10     }
    11     retry=0;
    12     while(!DHT11_DQ_IN&&retry<100)//等待变高电平
    13     {
    14         retry++;
    15         delay_us(1);
    16     }
    17     delay_us(40);//等待40us
    18     if(DHT11_DQ_IN)return 1;
    19     else return 0;           
    20 }

    main函数中进行初始化

            /* 温湿度传感器DHT11初始化 */  
      if(DHT11_Init()) 
      {
              DHT11Init_Flag=0;
        printf("\r\n DHT11 Init Failed! \n\r");   
      }
      else  
      {
        DHT11Init_Flag=1;
        printf("\r\n DHT11 Init Success! \n\r");
      }

    中断中显示:

    显示数值
    1     if(DHT11Init_Flag)     
    2     {
    3        DHT11_Read_Data(&temperature,&humidity);    //读取温湿度值
    4        printf("\r\n 当前温度值:%d° 当前湿度值:%d\n\r",temperature,humidity);
    5     }
    6     else printf("\r\n 温湿度传感器DHT11初始化失败 \n\r");

    实验中遇到一个问题:PE2端口并没有上拉电阻,而DQ pin需要上拉电阻,利用板子上IIC的接口,将PE2改为PB6,实验成功了。温度值很不准确。

  • 相关阅读:
    .net源码分析 – List<T>【转】
    js如何安全扩展系统函数
    ASP.NET Core 资源打包与压缩
    Jwt介绍
    Asp.Net Core中JWT刷新Token解决方案【转】
    关于同步方法里面调用异步方法引起死锁【转】
    CountDownEvent
    读写锁-ReaderWriterLockSlim
    自旋锁-SpinLock
    原子操作-Interlocked(CAS算法实现)
  • 原文地址:https://www.cnblogs.com/wwjdwy/p/3021841.html
Copyright © 2020-2023  润新知