您的位置:首页 > 其它

CC2530之DHT11温湿度测量

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



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

1. 接口说明:

  建议连接线长度小于20米时采用5K的上拉电阻,大于20米根据实际情况选择合适的上拉电阻。典型应用电路如下图所示:


2. 程序编写说明:

  DHT11与MCU通讯采用单总线数据格式,一次传输5字节即40位数据,高位在先。具体数据格式如下(当前小数部分留作扩展,现读出为零):

8bit湿度整数数据+8bit湿度小数数据+8bit温度整数数据+8bit温度小数数据+8bit校验和。

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



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



  若总线线为低电平,说明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();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: