玩转传感器----理解时序和数据采集(DHT11)

该文章以DHT11模块进行分析

目录

1.模块复位(时序图)

2.DHT11的应答信号

3.读取1bit数值(比较高电平的时间是否大于40us)

4.读取一个字节

5.把读取的字节放入单片机

6. 寄存器设置IO口方向


1.模块复位(时序图)

 void DHT11_Rst(void)       
{                 
    DHT11_IO_OUT();     //设置IO为输出
    DHT11_DQ_OUT=0;     //IO口置为低电平
    delay_ms(20);        //至少18ms
    DHT11_DQ_OUT=1;     //IO口置为高电平
    delay_us(30);        
}

2.DHT11的应答信号

u8 DHT11_Check(void)        
{   
    u8 retry=0;
    DHT11_IO_IN();//SET INPUT     
    while (DHT11_DQ_IN&&retry<100)
    {
        retry++;
        delay_us(1);
    };     
    if(retry>=100)return 1;
    else retry=0;
    while (!DHT11_DQ_IN&&retry<100)
    {
        retry++;
        delay_us(1);
    };
    if(retry>=100)return 1;        
    return 0;
}

这个地方时一个难点,巧妙读取io口电平的持续时间是否为80us,首先设置IO状态为输入,读取io电平,当io口为低电平时,DHT11_DQ_IN&&retry<100为true,执行retry++,延时1us;当跳变到高电平则DHT11_DQ_IN&&retry<100为false,若retry>100就提前结束。

3.读取1bit数值(比较高电平的时间是否大于40us)

 u8 DHT11_Read_Bit(void)              
{
     u8 retry=0;
    while(DHT11_DQ_IN&&retry<100)
    {
        retry++;
        delay_us(1);
    }
    retry=0;
    while(!DHT11_DQ_IN&&retry<100)
    {
        retry++;
        delay_us(1);
    }
    delay_us(40);
    if(DHT11_DQ_IN)return 1;
    else return 0;           
}

 如果经过40us后,电平认为高则是1,反之为0。

4.读取一个字节

u8 DHT11_Read_Byte(void)    
{        
    u8 i,dat;
    dat=0;
    for (i=0;i<8;i++) 
    {
           dat<<=1; 
        dat|=DHT11_Read_Bit();//按位异或,与0异或=本身
    }                            
    return dat;
}

5.把读取的字节放入单片机

u8 DHT11_Read_Data(u8 *temp,u8 *humi)    
{        
     u8 buf[5];
    u8 i;
    DHT11_Rst();
    if(DHT11_Check()==0)//存放数组
    {
        for(i=0;i<5;i++)
        {
            buf[i]=DHT11_Read_Byte();
        }
        if((buf[0]+buf[1]+buf[2]+buf[3])==buf[4])   //校验
        {
            *humi=buf[0];
            *temp=buf[2];
        }
    }else return 1;
    return 0;        

6. 寄存器设置IO口方向


#define DHT11_IO_IN()  {GPIOG->CRH&=0XFFFF0FFF;GPIOG->CRH|=8<<12;}
#define DHT11_IO_OUT() {GPIOG->CRH&=0XFFFF0FFF;GPIOG->CRH|=3<<12;}                                         
#define    DHT11_DQ_OUT PGout(11) 
#define    DHT11_DQ_IN  PGin(11)  

  |= 常用于位操作,目的是把值放入指定位置

&=0的目的是把该位置的位全部清0

操作高八位CR寄存器 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,这是一个关于嵌入式设备上使用wiringPi驱动dht11采集数据的问题。我可以为您提供一些参考代码,请注意以下事项: 1. 确认已经安装了wiringPi库和dht11驱动程序; 2. 确认已经正确连接了dht11传感器,引脚分别连接到树莓派的GPIO引脚; 3. 以下代码是C语言编写的,可以在NanoPC-T4上使用。 这是一个示例代码: ``` #include <wiringPi.h> #include <stdio.h> #include <stdlib.h> #include <stdint.h> #define MAX_TIMINGS 85 #define DHT_PIN 7 // 根据您实际连接的GPIO引脚进行修改 int data[5] = { 0, 0, 0, 0, 0 }; void read_dht11_dat() { uint8_t laststate = HIGH; uint8_t counter = 0; uint8_t j = 0, i; data[0] = data[1] = data[2] = data[3] = data[4] = 0; pinMode(DHT_PIN, OUTPUT); digitalWrite(DHT_PIN, LOW); delay(18); digitalWrite(DHT_PIN, HIGH); delayMicroseconds(40); pinMode(DHT_PIN, INPUT); for (i = 0; i < MAX_TIMINGS; i++) { counter = 0; while (digitalRead(DHT_PIN) == laststate) { counter++; delayMicroseconds(1); if (counter == 255) { break; } } laststate = digitalRead(DHT_PIN); if (counter == 255) break; if ((i >= 4) && (i % 2 == 0)) { data[j / 8] <<= 1; if (counter > 16) data[j / 8] |= 1; j++; } } if ((j >= 40) && (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF))) { float h = (float)((data[0] << 8) + data[1]) / 10; if (h > 100) { h = data[0]; // for DHT11 } float c = (float)(((data[2] & 0x7F) << 8) + data[3]) / 10; if (c > 125) { c = data[2]; // for DHT11 } if (data[2] & 0x80) { c = -c; } printf("Humidity = %.1f %% Temperature = %.1f *C\n", h, c); } else { printf("Data not good, skip\n"); } } int main(void) { printf("DHT11 temperature and humidity sensor\n"); if (wiringPiSetup() == -1) exit(1); while (1) { read_dht11_dat(); delay(1000); // 间隔1秒采集一次 } return 0; } ``` 注意:在实际使用中,您需要根据实际连接的GPIO引脚进行修改,比如上面代码中的DHT_PIN就需要根据实际连接的引脚进行修改。另外,您还需要在代码中添加相应的头文件和库文件链接选项,具体方法可以参考wiringPi官方文档。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值