关于DHT11的检测及串口
单片机源程序如下:
- #include <reg51.h>
- #include"stdio.h"
- #include"intrins.h"
- #define OK 1
- #define ERROR 0
- extern void Delay_1ms(unsigned int ms);
- //函数的返回值表示读取数据是否成功 OK 表示成功 ERROR 表示失败
- extern unsigned char DHT11_ReadTempAndHumi(void);
- sbit dht11 = P2^0; //IO口定义
- //防止在与硬件通信时发生死循环的计数范围
- #define NUMBER 120 //20 12T
- #define SIZE 5
- static unsigned char status;
- unsigned char tempshi,tempge;
- //存放五字节数据的数组
- static unsigned char value_array[SIZE];
- /*可在其他的文件引用温湿度值,实际是温度的整数的10 倍
- 如dht11 读回的温度是26,则temp_value = 260, 湿度同理*/
- int temp_value, humi_value;
- static unsigned char ReadValue(void);
- void serial_init(){
- TMOD=0x20;
- TH1=0xfd;
- TL1=0xfd; //设置9600波特率
- SCON=0x50; //串口方式1,允许接收
- TR1=1;
- }
- void main(){
- serial_init();
-
- while(1){
- if(DHT11_ReadTempAndHumi()==OK){
- TI=1;
- SBUF=temp_value;
- TI=0;
- Delay_1ms(1000);
- TI=1;
- SBUF=humi_value;
- TI=0;
- Delay_1ms(1000);
- }
- else if(DHT11_ReadTempAndHumi()==ERROR){
- TI=1;
- SBUF=0x01;
- TI=0;
- Delay_1ms(1000);
- }
- }
- }
- extern void Delay_1ms(unsigned int a){ //延时约1ms
- unsigned int i;
- while (--a!=0)
- for(i=600;i>0;i--);
- }
- static void DHT11_Delay_10us(void){
- unsigned char i;
- i--;
- i--;
- i--;
- i--;
- i--;
- i--;
- i--;
- i--;
- i--;
- i--;
- i--;
- i--;
- i--;
- i--;
- i--;
- i--;
- i--;
- i--;
- i--;
- i--;
- i--;
- i--;
- }
- /*读一个字节的数据*/
- static unsigned char DHT11_ReadValue(void){
- unsigned char count, value = 0, i;
- status = OK; //设定标志为正常状态
- for(i = 8; i > 0; i--){
- //高位在先
- value <<= 1;
- count = 0;
- //每一位数据前会有一个50us 的低电平时间.等待50us 低电平结束
- while(dht11 == 0 && count++ < NUMBER);
- if(count >= NUMBER){
- status = ERROR; //设定错误标志
- return 0; //函数执行过程发生错误就退出函数
- }
- //26-28us 的高电平表示该位是0,为70us 高电平表该位1
- DHT11_Delay_10us();
- DHT11_Delay_10us();
- DHT11_Delay_10us();
- //延时30us 后检测数据线是否还是高电平
- if(dht11 != 0){
- //进入这里表示该位是1
- value++;
- //等待剩余(约40us)的高电平结束
- while(dht11 != 0 && count++ < NUMBER){
- dht11 = 1;
- }
- if(count >= NUMBER){
- status = ERROR; //设定错误标志
- return 0;
- }
- }
- }
- return (value);
- }
- //读温度和湿度函数,读一次的数据,共五字节,读出成功函数返回OK, 错误返回ERROR
- extern unsigned char DHT11_ReadTempAndHumi(void){
- unsigned char i = 0, check_value = 0,count = 0;
- //EA = 0;
- dht11 = 0; //拉低数据线大于18ms 发送开始信号
- Delay_1ms(20); //需大于18 毫秒
- dht11 = 1; //释放数据线,用于检测低电平的应答信号
- //延时20-40us,等待一段时间后检测应答信号,应答信号是从机拉低数据线80us
- DHT11_Delay_10us();
- DHT11_Delay_10us();
- DHT11_Delay_10us();
- DHT11_Delay_10us();
- if(dht11 != 0){ //检测应答信号,应答信号是低电平
- //没应答信号
- // EA = 1;
- return ERROR;
- }
- else{
- //有应答信号
- while(dht11 == 0 && count++ < NUMBER); //等待应答信号结束
- if(count >= NUMBER){ //检测计数器是否超过了设定的范围
- dht11 = 1;
- // EA = 1;
- return ERROR; //读数据出错,退出函数
- }
- count = 0;
- dht11 = 1;//释放数据线
- //应答信号后会有一个80us 的高电平,等待高电平结束
- while(dht11 != 0 && count++ < NUMBER);
- if(count >= NUMBER){
- dht11 = 1;
- // EA = 1;
- return ERROR; //退出函数
- }
- //读出湿.温度值
- for(i = 0; i < SIZE; i++){
- value_array[i] = DHT11_ReadValue();
- if(status == ERROR){ //调用ReadValue()读数据出错会设定status 为ERROR
- dht11 = 1;
- // EA = 1;
- return ERROR;
- }
- //读出的最后一个值是校验值不需加上去
- if(i != SIZE - 1){
- //读出的五字节数据中的前四字节数据和等于第五字节数据表示成功
- check_value += value_array[i];
- }
- }//end for
- //在没用发生函数调用失败时进行校验
- if(check_value == value_array[SIZE - 1]){
- //将温湿度扩大10 倍方便分离出每一位
- humi_value = value_array[0] * 10;
- temp_value = value_array[2] * 10;
- dht11 = 1;
- // EA = 1;
- return OK; //正确的读出dht11 输出的数据
- }
- else{
- //校验数据出错
- // EA = 1;
- return ERROR;
- }
- }
- }
- /*****************************************************************************/
- /*****************************************************************************/
- /************************************************************************/
复制代码
所有资料51hei提供下载:
1985486dht11.zip
(1.83 KB, 下载次数: 146)
|