CC2530之DHT11温湿度测量

  DHT11数字温湿度传感器内部含一个电阻式感湿元件和一个NTC(Negative Temperature Coefficient,负温度系数)测温元件,与一个高性能8位单片机相连接。采用单线制串行接口,通信接口简单,具有小体积、低功耗、响应速度快等优点。实物图如下图所示:

CC2530之DHT11温湿度测量_第1张图片

需注意的是:湿度测量量程为20-90%RH,精度+-5%RH;温度测量量程为0~50℃,精度+-2℃(精度有点差,个人不喜欢用^-^)。

1. 接口说明:
  建议连接线长度小于20米时采用5K的上拉电阻,大于20米根据实际情况选择合适的上拉电阻。典型应用电路如下图所示:
CC2530之DHT11温湿度测量_第2张图片

2. 程序编写说明:
  DHT11与MCU通讯采用单总线数据格式,一次传输5字节即40位数据,高位在先。具体数据格式如下(当前小数部分留作扩展,现读出为零):
8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据+8bit校验和。

  若数据传送正确,则(8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据)所得结果的末8bit与8bit校验和相等。通信过程如下图所示:

CC2530之DHT11温湿度测量_第3张图片

  MCU控制相关引脚产生一个大于18ms的负脉冲为一个起始信号,DHT11接收到主机的开始信号后,等待主机开始信号结束,然后发送80us低电平响应信号。主机发送开始信号结束后,延时等待20-40us后, 读取DHT11的响应信号,主机发送开始信号后,可以切换到输入模式,或者输出高电平均可, 总线由上拉电阻拉高。  

CC2530之DHT11温湿度测量_第4张图片

  若总线线为低电平,说明DHT11发送响应信号,DHT11发送响应信号后。然后总线被拉高,当总线被拉低时,准备发送数据。每一bit数据都以50us低电平时隙开始,高电平持续时间的长短决定了数据位是0还是1(26~28μs为数据0,70μs为数据1)。
    

3. 测试程序如下:

#define DHT11_SDA   P0_0

void delay_us(void);
void delay_10us(void); 
void delay_ms(uint Time);


uchar datBuf[5] = {0};  // 存储5字节的数据 

/**
 * DHT11数据读取
 * @return 读取成功返回1    
 */
uchar dht11ReadDat()
{
    uchar i, tmp = 0, WAIT_FLAG = 0, checkOut = 0;

    P0DIR |= 0x01;  // 设置为输出模式
    DHT11_SDA = 0;
    delay_ms(19);   // 总线拉低时间大于18ms为起始信号
    DHT11_SDA = 1;
    P0DIR &= ~0x01;   // 设置为输入模式
    delay_10us();  delay_10us();  delay_10us();  delay_10us();  // 延时等待20~40us,等待从机响应信号

    if (!DHT11_SDA) {
        WAIT_FLAG = 2;
        while ((!DHT11_SDA) && WAIT_FLAG++);  // 等待高电平信号结束,开始接收数据
        if (WAIT_FLAG == 1)  return 0;  // 等待超时,退出本次操作
        WAIT_FLAG = 2;
        while (DHT11_SDA && WAIT_FLAG++);  

       for (i=0; i<40; i++) {
            WAIT_FLAG = 2;
            while ((!DHT11_SDA) && WAIT_FLAG++);   // 等待下一位数据开始发送 
            delay_10us();  delay_10us();  delay_10us(); 
            tmp = 0;
            if(DHT11_SDA) tmp = 1;  // 延时30us后仍为高电平,则为数据1
            WAIT_FLAG = 2;
            while (DHT11_SDA && WAIT_FLAG++);  // 等待高电平结束
            if(WAIT_FLAG == 1)  break;  // 等待超时,退出本次操作
            datBuf[i/8] <<= 1;
            datBuf[i/8] |= tmp;
        }

        P0DIR |= 0x01;  // 设置为输出模式
        DHT11_SDA = 1;

        for (i=0; i<4; i++) {
            checkOut += datBuf[i];
        }    
        if (checkOut == datBuf[4]) {
            return 1;  // 数据校验正确
        }
        else 
          return 0;
    } 
    else 
        return 0;
}

void delay_us(void) 
{
    asm("nop"); asm("nop"); asm("nop"); asm("nop");
    asm("nop"); asm("nop"); asm("nop"); asm("nop");    
    asm("nop");
}

void delay_10us(void) 
{
    delay_us(); delay_us(); delay_us(); delay_us(); delay_us();
    delay_us(); delay_us(); delay_us(); delay_us(); delay_us();
}

void delay_ms(uint Time)
{
    uchar i;
    while (Time--) {
        for(i=0; i<100; i++)
        delay_10us();
    }
}

你可能感兴趣的:(MCU,-,CC2530)