DHT12使用I2C协议 (51平台)

最近在做设计需要用到温湿度传感器,DHT12是DHT11的升级版;兼容旧版单总线数据传输模式,也可使用I2C通讯。在google、百度找了一大圈,基本都是使用STM32实现的,毕竟STM32更加强大方便;但是这次想用51来做,选择的是IIC通讯方式,调试过程很艰辛,于是开这篇文章记录下。

硬件:STC89C52最小系统、DHT12、LCD1602.

官方手册:云盘下载  提取码:n1ye

特别注意:

1.用于接SCL和SDA的单片IO口应接入1KΩ~10KΩ的上拉电阻,官方文档也有说明。

2.器件IIC通信和普通的IIC通信略有区别,应特别注意文档中的数据读取时序:

dht12for51_01.png

数据读取:

dht12for51_02.png

 

具体重要程序段:

/***********数据读取及处理***********/
void Data_Read()
{
	/**temp_H 温度高八位(温度整数部分);temp_L 温度低八位(温度小数部分)
	*  humi_H 湿度高八位(湿度整数部分);humi_L 湿度低八位(湿度小数部分)
	*  temp_C 校验数据和
	**/
	uchar temp_H,temp_L,humi_H,humi_L,temp_C,temp;

	IIC_Start();			//主机发送起始信号
	IIC_Write_Byte(0Xb8);   //发送器件地址
	IIC_Response();			//应答
	IIC_Write_Byte(0x00);	//写字节,DHT12读取地址0X00~0X04
	IIC_Response();			//应答
	IIC_Start();			//主机再次发起始信号
	IIC_Write_Byte(0Xb9);   //发送读指令,为器件寻址地址+1;
	IIC_Response();			//应答
		

	humi_H=IIC_Read_Byte();  //读取数据
	ACK();					 //每次读完都要给应答
	humi_L=IIC_Read_Byte();
	ACK();
	temp_H=IIC_Read_Byte();
	ACK();
	temp_L=IIC_Read_Byte();
	ACK();
	temp_C=IIC_Read_Byte();  //接受校验位后给非应答结束通讯
	NACK();
	IIC_Stop();	 			//IIC停止信号

	//数据校验
	temp=0xff&(humi_H+humi_L+temp_H+temp_L);

   	if(temp==temp_C)   //满足校验,才显示数据
	{
		if(temp_L&0x80)	   //判断温度是否为负
		{
			//将低八位8bit位的负号位置0
			T=temp_H+int2float(temp_L&0x7f);  		
			DisplayOneChar(0,0,'-');	//温度显示负号
		}
		else{
			//int2float()函数为整型数据转换float		
			T=temp_H+int2float(temp_L);	  
		}
		H=humi_H+int2float(humi_L);	
			
		//num2str()函数为数字转字符数组
		//形参分别为 (小数,存储数组名,需要保留的小数位数)
		num2str(T,Tp,2);  	
		num2str(H,Hu,2);	
		LcdShowStr(1,0,Tp);
		LcdShowStr(9,0,Hu);
	}
}

说明:

LcdShowStr(x,y,*str)  表示显示字符数组从lcd的横坐标第x格,纵向只有0和1,0表示第一行,1表示第二行

DisplayOneChar(x,y,str);   x,y同上,但此函数只能显示一个字符。

文件说明:

main.c 程序入口,引入其它头文件,直接调用其函数
DHT12.h 温湿度传感器头文件,存有相关IIC通讯、数据读取的函数
mytools.h 为了避免引入C语言库,带来程序冗余,自己按需复写相关工具函数
lcd.h 为LCD1602的头文件,引入后可直接调用使用,内IO接口可自行修改

完整文件下载:云盘下载   提取码:hva9

点赞