DHT11程序代码
dht11显示程序
SCANP=(BCD<<4)|(scan&0x0f);
// 输出BCD码(高4位元)与扫瞄信号(低4位元)
delay_ms(4); // 延迟4ms
scan>>=1; // 产生下个扫瞄信号
_nop_();
_nop_();
}
}
}
/*********************************************************************************/
delay_us();
delay_us();
delay_us();
if(TRH)
{
temp=1;
}
void scanner(void) // 扫瞄字组函数开始
{ char i,j,BCD,scan; // 声明变数
for (i=0;i<30;i++) // 扫瞄30次i循环
{ scan=0xf7; // 扫瞄信号初值1111 0111
for (j=0;j<4;j++) // 扫瞄4个数字j循环
respond=2;
while((TRH)&&respond++);
}
else
temp=0;
/*********************************************************************************/
/*********************************************************************************/
DHT11程序代码(已测)
//----------------------------------------------
void main()
{
U8 i,j;
//uchar str[6]={"RS232"};
/* 系统初始化 */
TMOD = 0x20; //定时器T1使用工作方式2
{
U8 InPut3;
if(TI==1) //发送中断
{
TI=0;
if(count!=5) //发送完5位数据
//硬件 P2.0口为通讯口连接DHT11,DHT11的电源和地连接单片机的电源和地,单片机串口加MAX232连接电脑
//****************************************************************//
#include <reg51.h>
{
for(i=0;i<27;i++);
}
}
void Delay_10us(void)
{
U8 i;
i--;
i--;
i--;
i--;
i--;
i--;
U8checkdata=U8checkdata_temp;
}//fi
}//fi
}
//----------------------------------------------
//main()功能描述: AT89C51 11.0592MHz 串口发
typedef float F32; /* single precision floating point variable (32bits) 单精度浮点数(32位长度) */
dht11程序编写流程
dht11程序编写流程下载温馨提示:该文档是我店铺精心编制而成,希望大家下载以后,能够帮助大家解决实际的问题。
文档下载后可定制随意修改,请根据实际需要进行相应的调整和使用,谢谢!并且,本店铺为大家提供各种各样类型的实用资料,如教育随笔、日记赏析、句子摘抄、古诗大全、经典美文、话题作文、工作总结、词语解析、文案摘录、其他资料等等,如想了解不同资料格式和写法,敬请关注!Download tips: This document is carefully compiled by theeditor. I hope that after you download them,they can help yousolve practical problems. The document can be customized andmodified after downloading,please adjust and use it according toactual needs, thank you!In addition, our shop provides you with various types ofpractical materials,such as educational essays, diaryappreciation,sentence excerpts,ancient poems,classic articles,topic composition,work summary,word parsing,copy excerpts,other materials and so on,want to know different data formats andwriting methods,please pay attention!1. 初始化 DHT11 传感器需要将 DHT11 传感器连接到微控制器的适当引脚。
DHT11温湿度传感器程序
//LCD 控制端口设置
PORTA &= ~((1 << RS) | (1 << RW) | (1 << E)); //
DDRA |= (1 << RS) | (1 << RW) | (1 << E);
}
if(Reset())
{ P_DHT;
while((!(I_DHT)) && ((u16Flag++)<50000));
ReceiveValue = 0;
ReceiveValue1 = 0;
u16Flag = 0;
while((I_DHT) && ((u16Flag++)<50000));
#include <avr/io.h>
#include <util/delay.h>
//口定义
#define PORT_DHT PORTC
//口方向定义
#define DDR_DHT DDRC
//读取口定义
#define PIN_DHT PINC
//数据位定义
#define BIT_DHT PC4
void Write_Data_Byte(unsigned char LCD_Data); //LCD 写字节数据
void Write_Place_xy(unsigned char x,unsigned char y); //指定当前写字符的位置
void Write_Data_String(unsigned char x,unsigned char y,unsigned char *data);//在指定的(x,y)位置上写入字符串数据
dht11的c语言程序
#include<reg51.h>#define uint unsigned int#define uchar unsigned charsbit TRH = P1^0;//温湿度传感器DHT11数据接入uchar str[]={0,0,0,0,0,0,0,0};uint TH,TL,RH,RL,CK;uint THc,TLc,RHc,RLc,CKc;uint xh,sum;// void delay(uchar s) //延时10us// {// uchar v;// for(;s>0;s--)// for(v=25;v>0;v--);// }void delay(uchar b) //误差0us{unsigned char a;for(;b>0;b--)for(a=2;a>0;a--);}//void delay1( )// 延时20ms//{//uchar x,y,z;//for(x=15;x>0;x--)//for(y=4;y>0;y--)//for(z=248;z>0;z--);//}void delay1(uchar c) //误差0us{unsigned char a,b;for(;c>0;c--)for(b=142;b>0;b--)for(a=2;a>0;a--);}void delay2()//数码管显示用的延时{uchar l,j,k;for(l=2;l>0;l--)for(j=4;j>0;j--)for(k=100;k>0;k--);}void start(){ TRH=1;delay(2);TRH=0; //主机拉低18msdelay1(20);TRH=1; //DATA总线由上拉电阻拉高主机延时20delay(3);}uchar receive(){ uchar i,temp;xh=0;while(TRH);for(i=0;i<8;i++){ while(!TRH);delay(3);if(TRH){ temp=1;while(TRH);}elsetemp=0;xh<<=1;xh|=temp;}return (xh);}void display(){uchar a[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90}; uchar m,n,s,i;m= str[3];//数码管显示部分n= str[4];s= str[5];while(1){for(i=0;i<10;i++){ if(m==i)m=a[i];}P0=m;P2=0x10;delay2();for(i=0;i<10;i++){ if(n==i)n=a[i];}P0=n-0X80;P2=0x20;delay2();for(i=0;i<10;i++){ if(s==i)s=a[i];}P0=s;P2=0x40;delay2();P0=0X9C;P2=0x80;delay2();}}void main(){while(1){start();TRH=1; // 读取数据并写入指令if(!TRH){while(!TRH); //判断DHT11发出80us 的低电平响应信号是否结束while(TRH);delay(8);RHc = receive(); //数据接收状态RLc = receive();THc = receive();TLc = receive();CKc = receive();}TRH=1;sum=(RHc+RLc+THc+TLc);//数据校验if(sum==CKc){ RH = RHc;RL = RLc;TH= THc;TL = TLc;CK = CKc;str[0] =RH/10; //湿度整数部分str[1] =RH%10;str[2] = RL/10 ;str[3] = TH/10; //温度整数部分str[4] = TH%10;str[5] = TL/10;}display();}}。
51单片机DHT11芯片,1603显示屏程序代码
51单片机DHT11芯片,1603显示屏程序代码#include<reg52.h>#include<intrins。
h>typedefunsignedcharuchar;typedefunsignedintuint;typedefunsignedlongulong;ucharcom,flag;ucharn,m,y,x,v,u,a1,a2;//温湿度上下限的参数,其中,nm是温湿度超标与否的标准,值为0或者1.这代码的温湿度报警没有用LED或者蜂鸣器,只用了一个软件参数n、m存储报警信息。
需要添加报警功能的可以自己写额外的功能代码,然后nm两个参数就是功能传递参数。
也可以写多一个串口输出代码,用串口调试助手输出n、m的值验证温湿度是否超标判断正确。
voidDelay1000ms()//@11.0592MHz延时{unsignedchari,j,k;_nop_();i=8;j=1;k=243;do{do{while(--k);}while(--j);}while(--i);}voidDelay500us()//@11.0592MHz {ucharb;_nop_();b=227;while(--b);}voidDelay10us()//@11.0592MHz {uchara;a=2;while(--a);}voiddelay(uintz){uchari,j;for(i=z;i>0;i--)for(j=110;j>0;j--);//ÑÓʱº¯Êý}//************************引脚定义************* /*******按键控制引脚定义*********/sbity_tem_inse=P1^0;//sbity_tem_duce=P1^1;//sbitx_tem_inse=P1^2;//sbitx_tem_duce=P1^3;//sbitu_hum_inse=P1^4;//sbitu_hum_duce=P1^5;//sbitv_hum_inse=P1^6;//sbitv_hum_duce=P1^7;///***********其他功能引脚*****/sbitDQ=P2^1;//DTH11//****LCD的****sbitRS=P2^7;sbitRW=P2^6;sbitEN=P2^5;#defineDataPortP0//LCD的接线,我的是8线接发//-----------------函数声明------------- voiddelay_us(uchart);voiddelay_ms(uchart);bitLCD_Check_Busy(void);voidLCD_Write_Com(ucharcom);voidLCD_Write_Data(ucharData);voidLCD_Clear(void);voidLCD_Write_String(ucharx,uchary,uchar*s);voidLCD_Write_Char(ucharx,uchary,ucharData);voidLCD_Init(void);voidCOMdata();//*************************以下是函数定义***************************//**************液晶屏显示原函数由此开始*************************bitLCD_Check_Busy(void)//检忙{DataPort=0xFF;RS=0;RW=1;EN=0;_nop_();EN=1;return(bit)(DataPort&0x80);voidLCD_Write_Com(ucharcom)//写指令原函数{while(LCD_Check_Busy());RS=0;RW=0;EN=1;DataPort=com;_nop_();EN=0;}voidLCD_Write_Data(ucharData)//写数据原函数{while(LCD_Check_Busy());RS=1;RW=0;EN=1;DataPort=Data;_nop_();EN=0;}voidLCD_Clear(void)//清屏LCD_Write_Com(0x01);delay(1);}voidLCD_Write_String(ucharx,uchary,uchar*s)//操作-显示LCD屏的哪个位置{if(y==0)LCD_Write_Com(0x80+x);elseLCD_Write_Com(0xC0+x);while(*s){LCD_Write_Data(*s);s++;}}voidLCD_Write_Char(ucharx,uchary,ucharData)//操作-显示的数据(字符类型,显示数字需找到该数字的ASCII码){if(y==0)LCD_Write_Com(0x80+x);elseLCD_Write_Com(0xC0+x);LCD_Write_Data(Data);}voidLCD_Init(void)//LCD初始化(可以理解为唤醒){delay(15);LCD_Write_Com(0x38);delay(5);LCD_Write_Com(0x38);delay(5);LCD_Write_Com(0x38);delay(5);LCD_Write_Com(0x38);LCD_Write_Com(0x08);LCD_Write_Com(0x01);LCD_Write_Com(0x06);delay(5);LCD_Write_Com(0x0C);}//****************LCD源码结束***********//*********DHT11原函数以下开始*******//*************************************************** ucharcodeASCII[]="0123456789%c";//普通数字需用该数组转成字符ucharcodetable0[]="Hum:";ucharcodetable1[]="Tem:";uchartem;ucharhum;display0[2]={0,0};display1[2]={0,0};//*************************初始化DTH11voidCOMdata()//读数据{uchari,t;for(i=0;i<8;i++){flag=2;while((!DQ)&&flag++);Delay10us();Delay10us();Delay10us();//先看懂DHT11的工作时序图就知道我这个延时操作的含义了,读高电平多少秒可以对应数据0或1t=0;if(DQ)t=1;while((DQ)&&flag++);if(flag==1)break;com<<=1;com|=t;}}voidRH(void)//该函数包括唤醒DHT11发送数据给单片机也包括单片机把数据提取{DQ=0;delay(21);DQ=1;Delay10us();Delay10us();Delay10us();Delay10us();DQ=1;if(!DQ){flag=2;while((!DQ)&&flag++);while((DQ)&&flag++);COMdata();hum=com;COMdata();COMdata();tem=com;COMdata();COMdata();//小数位这里我不显示,所以不用读取tem或hum 第二次的COMdata()函数获取的数据DQ=1;}}//*********************************LCD显示温湿度数据voidDisplay_DTH11(){ucharxh,xl,yh,yl,vh,vl,uh,ul;xh=x/10%10;xl=x%10;yh=y/10%10;yl=y%10;uh=u/10%10;ul=u%10;vh=v/10%10;vl=v%10;LCD_Write_String(8,0,"L");LCD_Write_Char(9,0,ASCII[uh]);LCD_Write_Char(10,0,ASCII[ul]);LCD_Write_String(12,0,"H");LCD_Write_Char(13,0,ASCII[vh]);LCD_Write_Char(14,0,ASCII[vl]);LCD_Write_String(8,1,"L");LCD_Write_Char(9,1,ASCII[xh]);LCD_Write_Char(10,1,ASCII[xl]);LCD_Write_String(12,1,"H");LCD_Write_Char(13,1,ASCII[yh]);LCD_Write_Char(14,1,ASCII[yl]);display0[1]=hum/10%10;//读hum十位display0[0]=hum%10;//个位LCD_Write_String(0,0,table0);LCD_Write_Char(4,0,ASCII[display0[1]]);LCD_Write_Char(5,0,ASCII[display0[0]]);LCD_Write_Char(6,0,ASCII[10]);//显示在LCD的第几行第几位(这一行是指在第0行,第6位开始显示ASCII[10]里面的字符数据,下同),运行结果是显示了“hum:”这四个字符display1[1]=tem/10%10;display1[0]=tem%10;LCD_Write_String(0,1,table1);LCD_Write_Char(4,1,ASCII[display1[1]]);LCD_Write_Char(5,1,ASCII[display1[0]]);LCD_Write_Char(6,1,0xdf);LCD_Write_Char(7,1,ASCII[11]);}//***************原函数结束*************//voidkeyscan(){if(y_tem_inse==0){delay(10);if(y_tem_inse==0)//这里是消抖,下同{y=y+5;while(y==55)y=50;while(y_tem_inse==0);}if(y_tem_duce==0){delay(10);if(y_tem_duce==0);{y=y-5;while(y==5)y=10;while(y_tem_duce==0);}}if(x_tem_inse==0){delay(10);if(x_tem_inse==0){x=x+5;while(x==55)x=50;while(x_tem_inse==0);}}if(x_tem_duce==0)delay(10);if(x_tem_duce==0);{x=x-5;while(x==5)x=10;while(x_tem_duce==0);}}if(u_hum_inse==0){delay(10);if(u_hum_inse==0){u=u+5;while(u==85)u=80;while(u_hum_inse==0);}}if(u_hum_duce==0){delay(10);if(u_hum_duce==0);u=u-5;while(u==25)u=30;while(u_hum_duce==0);}}if(v_hum_inse==0){delay(10);if(v_hum_inse==0){v=v+5;while(v==85)v=80;while(v_hum_inse==0);}}if(v_hum_duce==0){delay(10);if(v_hum_duce==0);{v=v-5;while(v==25)v=20;while(v_hum_duce==0);}}}//*******************************上面是按键扫描,以下开始是主函数main(){LCD_Clear();x=10,y=50,u=30,v=80;//温湿度上下限初值,按键函数里可调tem=0;hum=0;//赋初值LCD_Init();Delay1000ms();//DTH11上电一秒后才工作正常while(1){EA=0;keyscan();RH();if((tem>y)||(tem<x))n=1;elsen=0;//LED或蜂鸣器亮灭判断,下同if((hum>v)||(hum<u))m=1;elsem=0;Display_DTH11();Time0_Init();Delay1000ms();Delay1000ms();Delay1000ms();}}。
温湿度检测器DHT11程序及显示程序
附录1:#include <regx52.h>#include <intrins.h>#include "DHT11.H"#include "DHT11.C"unsigned char range[4]={55,75,10,30}; //温湿度上下限初值unsigned char Humi_Temp_Tab[8]={6,9,0,0,7,8,0,0}; //数码管显示初值unsigned char numt1=0; //T1中断计数标志unsigned char numt0=0;unsigned char codeTab_Seg[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};//数码管段码 0-9unsigned char code Tab_Dig[8]={0x7f,0xbf,0xdf,0xef,0xf7,0xfb,0xfd,0xfe};//位选第一位到第八位unsigned char code units[4]={0x39,0x71,0x77,0x76}; //单位C/F/RH/**********************************************//* 温湿度采集函数 *//**********************************************/void getdata(){if(start_DHT11()){read_DHT11();}if(check_sum()){Humi_Temp_Tab[0]=DHT_data.DH_H/10;Humi_Temp_Tab[1]=DHT_data.DH_H%10;Humi_Temp_Tab[2]=DHT_data.DH_L/10; //存储湿度数据if(flag == 0){Humi_Temp_Tab[4]=DHT_data.T_H/10;Humi_Temp_Tab[5]=DHT_data.T_H%10;Humi_Temp_Tab[6]=DHT_data.T_L/10;//存储摄氏温度数据}else{Humi_Temp_Tab[4]=(9*DHT_data.T_H/5+32)/10;Humi_Temp_Tab[5]=(9*DHT_data.T_H/5+32)%10;Humi_Temp_Tab[6]=(18*DHT_data.T_H+320)%100%10;//存储华氏温度数据}}}/**********************************************//* 主函数 *//**********************************************/void main(){delay_ms(500); //先进行延时等待进入稳定状态P0 = 0;P1 = 0x0C; //初始化P1口EA = 0;TR1 = 0;TR0 = 0;TMOD = 0x11; //设置定时器 T0和T1,且工作方式都为方式1TH1 = (65536-5000)/256;TL1 = (65536-5000)%256;TH0 = (65536-2000)/256;TL0 = (65536-2000)%256; //设定初值2msTR1 = 1;TR0 = 1;EA = 1;ET0 = 1;ET1 = 1; //打开中断定时器T0和T1PT1 = 0;PT0 = 1; //强制设置优先级delay_ms(1000);while(1){if(DHT_data.DH_H<range[0]) //湿度小于下限{bee = 0;delay_ms(100);bee = 1;delay_ms(100);}if(DHT_data.DH_H>range[1]) //湿度大于上限{bee = 0;delay_ms(100);bee = 1;delay_ms(100);}if(DHT_data.T_H<range[2]) //温度小于下限{bee = 0;delay_ms(10);bee = 1;delay_ms(10);}if(DHT_data.T_H>range[3]) //温度大于上限{bee = 0;delay_ms(10);bee = 1;delay_ms(10);}}}/**********************************************//* 定时器T0中断 *//**********************************************/void T0_timer() interrupt 1{unsigned char KData = 0x00;TR0 = 0; //进入T0后将T0中断关闭TH0 = (65536-2000)/256;TL0 = (65536-2000)%256;switch(numt0){case 0: P0 = 0; Seg_ce = 1; Seg_ce = 0; //段选开关if(flag2 == 1)P0 = Tab_Seg[range[0]/10];//显示湿度下限的十位elseP0 = Tab_Seg[Humi_Temp_Tab[0]];//显示读取的湿度的十位Seg_ce = 1; Seg_ce = 0;.P0 = Tab_Dig[0]; //位选第一位Dig_ce = 1; Dig_ce = 0;numt0++;break;case 1: P0 = 0; Seg_ce = 1; Seg_ce = 0;if(flag2 == 1)P0 = Tab_Seg[range[0]%10];//显示湿度下限的个位elseP0 = Tab_Seg[Humi_Temp_Tab[1]];//显示读取的湿度的个位Seg_ce = 1; Seg_ce = 0;P0 = Tab_Dig[1]; //位选第二位Dig_ce = 1; Dig_ce = 0;numt0++;break;case 2: P0 = 0; Seg_ce = 1; Seg_ce = 0;if(flag2 == 1)P0 = Tab_Seg[range[1]/10];//显示湿度上限的十位elseP0 = units[2];//显示单位RSeg_ce = 1; Seg_ce = 0;P0 = Tab_Dig[2]; //位选第三位Dig_ce = 1; Dig_ce = 0;numt0++;break;case 3: P0 = 0; Seg_ce = 1; Seg_ce = 0;if(flag2 == 1)P0 = Tab_Seg[range[1]%10];//显示湿度上限的个位elseP0 = units[3]; //显示单位H Seg_ce = 1; Seg_ce = 0;P0 = Tab_Dig[3]; //位选第四位Dig_ce = 1; Dig_ce = 0;numt0++;break;case 4: P0 = 0; Seg_ce = 1; Seg_ce = 0;P0 = Tab_Dig[4];//位选第五位,且同时拉低键盘第四行Dig_ce = 1; Dig_ce = 0;Key_ce = 0;KData = P0; //扫描键盘第四行switch(KData){case 0xfe:case 0xfd:case 0xfb:case 0xf7:default:break;}while(KData != 0xff){KData = P0;}Key_ce = 1;if(flag2 == 1)P0 = Tab_Seg[range[2]/10];//显示温度下限的十位elseP0 = Tab_Seg[Humi_Temp_Tab[4]];//显示读取的温度的十位Seg_ce = 1; Seg_ce = 0;numt0++;break;case 5: P0 = 0; Seg_ce = 1; Seg_ce = 0;P0 = Tab_Dig[5];//位选第六位,且同时拉低键盘第三行Dig_ce = 1; Dig_ce = 0;Key_ce = 0;KData = P0;//扫描键盘第三行switch(KData){case 0xfe:if(range[0]<range[1]&&flag2==1)range[0]++;break; //湿度下限加case 0xfd:if(range[1]<90&&flag2==1)range[1]++;break; //湿度上限加case 0xfb:if(range[2]<range[3]&&flag2==1range[2]++;break; //温度下限加case 0xf7:if(range[3]<50&&flag2==1)range[3]++;break; //温度上限加default:break;}while(KData != 0xff){KData = P0;}Key_ce = 1;if(flag2 == 1)P0 = Tab_Seg[range[2]%10];//显示温度下限的个位elseP0 = Tab_Seg[Humi_Temp_Tab[5]]-0x80; //显示读取温度的个位(带小数点的)Seg_ce = 1; Seg_ce = 0;numt0++;break;case 6: P0 = 0; Seg_ce = 1; Seg_ce = 0;P0 = Tab_Dig[6];//位选第七位,且同时拉低键盘第二行Dig_ce = 1; Dig_ce = 0;Key_ce = 0;KData = P0; //扫描键盘第二行switch(KData){case 0xfe:if(range[0]>20&&flag2==1)range[0]--;break; //湿度下限减case 0xfd:if(range[0]<range[1]&&flag2==1)range[1]--;break; //湿度上限减case 0xfb:if(range[2]>0&&flag2==1)range[2]--;break; //温度下限减case 0xf7:if(range[2]<range[3]&&flag2==1)range[3]--;break; //温度上限减default:break;}while(KData != 0xff){KData = P0;}Key_ce = 1;if(flag2 == 1)P0 = Tab_Seg[range[3]/10];//显示温度上限的十位elseP0 = Tab_Seg[Humi_Temp_Tab[6]];//显示读取温度的小数位的十位Seg_ce = 1; Seg_ce = 0;numt0++;break;case 7: P0 = 0; Seg_ce = 1; Seg_ce = 0;P0 = Tab_Dig[7];//位选第八位,且同时拉低键盘第一行Dig_ce = 1; Dig_ce = 0;Key_ce = 0;KData = P0; //扫描键盘第一行switch(KData){case 0xfe:flag2 = ~flag2;TR1 = ~TR1;break;//进入和退出限制调整模式case 0xfd:flag = ~flag;break;//进行华氏摄氏温度的转换设置case 0xfb:case 0xf7:default:break;}while(KData != 0xff){KData = P0;}Key_ce = 1;if(flag == 0&&flag2 == 0)P0 = units[0]; //显示单位Celse if(flag == 1&&flag2 == 0)P0 = units[1]; //显示单位Felse if(flag2 == 1)P0 = Tab_Seg[range[3]%10];//显示温度上限的个位Seg_ce = 1; Seg_ce = 0;numt0 = 0;break;default:numt0 = 0;break;}TR0 = 1; //打开T0}/**********************************************//* 定时器T1中断 *//**********************************************/void T1_timer() interrupt 3{TR1 = 0; //关闭T0TH1 = (65536-50000)/256;TL1 = (65536-50000)%256;if(numt1 == 25){getdata(); //采集数据numt1 = 0;}elsenumt1++;TR1 = 1; //打开T0}#ifndef __DHT11_h__#define __DHT11_h__#include <REGX52.H>/**********************************************//* 引脚定义 *//**********************************************/sbit DHT_bus = P2^0 ; //DHT11数据传输口sbit Key_ce=P1^3; //按键输出使能sbit Seg_ce=P1^0; //段选位sbit Dig_ce=P1^1; //位选位sbit bee = P2^1; //蜂鸣器控制口/**********************************************//* 函数声明 *//**********************************************/bit start_DHT11(void); //开始void read_DHT11(void); //读取void delay_20us(void); //20us延时void delay_ms(unsigned char m); //N ms延时bit check_sum(void); //和校验/**********************************************//* 宏定义 *//**********************************************/#define HIGH 1#define LOW 0/**********************************************//* 变量定义 *//**********************************************/#define DHT_timeover 5 //高电平维持时间,用于识别“数据0”和“数据1”bit flag2 = 0; //设置调节上下限模式转换标志bit flag=0; //设置摄氏和华氏温度模式转换标志/**********************************************//* 结构体 *//**********************************************/struct DHT_data{unsigned char DH_H; //湿度整数unsigned char DH_L; //湿度小数unsigned char T_H; //温度整数unsigned char T_L; //温度小数unsigned char Checksum; //校验和}DHT_data;#endif#include "DHT11.h"#include <intrins.h>/**********************************************//* 开始 DHT11 温湿度计 *//* 输入:无 *//* 输出:应答标志 0:应答失败 1:应答成功 *//**********************************************/bit start_DHT11(void){bit DHT_start;DHT_start = 0;DHT_bus = HIGH;DHT_bus = LOW; //拉低18ms以上delay_ms(18);TR0 = 0;DHT_bus = HIGH;delay_20us();delay_20us(); //拉高20~40uswhile(!DHT_bus){DHT_start = 1;} //DHT应答,DHT拉低80us后拉高80us,然后开始传输数据//数据(40bit)=8bit湿度整数+8bit湿度小数+8bit温度整数+8bit 温度小数+8bit校验和while(DHT_bus){};return(DHT_start); //应答成功返回1}/**********************************************//* 读取 DHT11 温湿度计 *//* 读取结果存在DHT_data结构体内 *//* 输入:无输出:无 *//**********************************************/void read_DHT11(void){unsigned char m,n,timer_dht;unsigned char *p;p=&DHT_data.DH_H; //数据放在DHT_date的结构体中for(m=0;m<5;m++){for(n=0;n<8;n++){while(~DHT_bus); //DHT拉低12-14us表示1bit数据开始timer_dht=0x00;while(DHT_bus) //随后DHT拉高总线,单片机通过高电平维持的时间判断“数据0”还是“数据1”{ //数据0维持26~28us高电平,数据1维持116~118us高电平timer_dht++; //由于此处对延时时间的长度要求很高,所以采用另一种办法判断}if(timer_dht>DHT_timeover){*p<<=1;*p|=0x01;}else{*p<<=1;*p&=0xfe;}}p++;}TR0 = 1;}/**********************************************//* 20us 精确延时 *//* 51用在12Mhz晶振下 *//* 调用函数使用LCALL和RET指令,共花费4个周期 *//* 因此只有16个NOP *//**********************************************/.void delay_20us(void){_nop_ ();_nop_ ();_nop_ ();_nop_ ();_nop_ ();_nop_ ();_nop_ ();_nop_ ();_nop_ ();_nop_ ();_nop_ ();_nop_ ();_nop_ ();_nop_ ();_nop_ ();_nop_ ();}/**********************************************//* N ms 延时 *//* while()额外占用约5周期 *//* 因此内层while(40--)20us 大约1ms *//* Nms延时函数(未测试) *//**********************************************/void delay_ms(unsigned char m){unsigned char n = 38;while(m--){while(n--){delay_20us();}}}/**********************************************//* 校验和判断 *//* 校验位 = 湿度整数位+湿度小数位+温度整数位+温度小数位之和 *//* 校验正确返回:1 失败返回:0 *//**********************************************/bit check_sum(void){if(DHT_data.Checksum==(DHT_data.DH_H+DHT_data.DH_L+DHT_data.T _H+DHT_data.T_L))return(1); //校验正确elsereturn(0); //校验失败}Word 资料。
dht11stm32程序
dht11stm32程序DHT11是一种低成本、数字式温湿度传感器,广泛应用于物联网和环境监测等领域。
DHT11可以通过单线串行通信协议与STM32微控制器进行通讯,实现温湿度数据的读取与处理。
本文将介绍如何在STM32上实现DHT11的温湿度读取功能。
1.硬件连接首先,我们需要将DHT11与STM32微控制器进行连接。
DHT11共有四个引脚,分别为:VCC、GND、DATA和NC。
其中,VCC和GND分别接STM32的5V电源和地。
DATA接STM32的任意GPIO口,NC不使用。
2.程序设计在STM32上实现DHT11的温湿度读取功能,需要编写对应的程序代码。
以下是DHT11读取函数的C语言代码:```#include "dht11.h"void DHT11_Init(void){GPIO_InitTypeDef GPIO_InitStruct;__HAL_RCC_GPIOA_CLK_ENABLE();GPIO_InitStruct.Pin = GPIO_PIN_0;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;GPIO_InitStruct.Pull = GPIO_PULLUP;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET); HAL_Delay(18);HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET); HAL_Delay(40);GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_PULLUP;HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);}void DHT11_Read(uint8_t *temp, uint8_t *hum){uint8_t buf[5] = {0};uint8_t i, j;//拉低DATA线18msHAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);HAL_Delay(18);//拉高DATA线40usHAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);HAL_Delay(40);//判断DHT11响应信号(低电平80us,高电平80us)if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_RESET){while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) ==GPIO_PIN_RESET);while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) ==GPIO_PIN_SET);//接收温度湿度数据for (i = 0; i < 5; i++){for (j = 0; j < 8; j++){while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) ==GPIO_PIN_RESET);HAL_Delay(30);if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_SET) {buf[i] |= (0x80 >> j);}while (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_0) == GPIO_PIN_SET);}}//判断校验和if (buf[0] + buf[1] + buf[2] + buf[3] == buf[4]) {*hum = buf[0]; //湿度*temp = buf[2]; //温度}}}```在上述代码中,DHT11_Init函数用于初始化DHT11模块,DHT11_Read函数用于读取DHT11的温湿度数据。
dht11 keil实例程序
简单的Keil程序实例,用于读取DHT11传感器的温度和湿度数据:
```c
#include "dht.h"
#define DHTPIN P1_3
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
void main(void)
{
while(1)
{
float temperature;
float humidity;
float t_c;
// 读取DHT值
dht.measure();
temperature = dht.temperature();
humidity = dht.humidity();
// 输出温度和湿度数据
Serial.print("Temperature: ");
Serial.print(temperature);
Serial.print("C, Humidity: ");
Serial.print(humidity);
Serial.println("%");
}
}
```
在此程序中,我们首先定义了DHT传感器引脚和类型。
然后,我们创建了一个DHT对象,用于读取DHT值。
在主循环中,我们不断读取DHT值,并使用这些值计算出温度和湿度的摄氏度表示形式。
最后,我们将这些数据输出到串行端口。
请注意,此程序仅是一个基本示例,你可能需要根据你的具体硬件配置和需求进行修改。
此外,你可能还需要安装适当的Keil库和驱动程序,以便正确地连接DHT传感器和Keil开发环境。
dht11的32代码
dht11的32代码DHT11是一款数字温湿度传感器,能够同时测量温度和湿度,并将数据以数字信号输出。
在很多物联网应用中,DHT11都是必不可少的组件之一。
在这篇文章中,我们将介绍如何使用32行代码来读取DHT11的数据。
首先,我们需要使用Arduino开发板来连接DHT11传感器。
将DHT11传感器的VCC引脚连接到Arduino板的5V引脚,将GND引脚连接到GND引脚,将DATA引脚连接到数字引脚2。
接下来,我们可以使用以下的32行代码来读取传感器的数据:```C++int data[5] = {0, 0, 0, 0, 0};void setup() {Serial.begin(9600);}void loop() {int i = 0;int j = 0;unsigned long lastTime = 0;pinMode(2, OUTPUT);digitalWrite(2, LOW);delay(20);digitalWrite(2, HIGH);delayMicroseconds(30);pinMode(2, INPUT_PULLUP);lastTime = micros();while (digitalRead(2) == LOW) {if ((micros() - lastTime) > 100) { break;}}lastTime = micros();while (digitalRead(2) == HIGH) { if ((micros() - lastTime) > 100) { break;}}for (i = 0; i < 40; i++) {lastTime = micros();while (digitalRead(2) == LOW) {if ((micros() - lastTime) > 100) { break;}}lastTime = micros();while (digitalRead(2) == HIGH) {if ((micros() - lastTime) > 100) {break;}}if ((micros() - lastTime) > 40) {data[j / 8] <<= 1;data[j / 8] |= 0x01;} else {data[j / 8] <<= 1;}j++;}if ((j >= 40) && (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF))) {Serial.print('Humidity = ');Serial.print(data[0], DEC);Serial.print('.');Serial.print(data[1], DEC);Serial.print('%, Temperature = ');Serial.print(data[2], DEC);Serial.print('.');Serial.print(data[3], DEC);Serial.println('C');}delay(1000);}```上述代码中,首先定义了一个长度为5的整型数组data,用来存储从DHT11传感器读取到的数据。
51单片机dht11驱动程序(1)
H文件:#ifndef __DHT11_H__#define __DHT11_H__#include <reg52.h>sbit DA TA=P3^3;void DHT11_DA TA(unsigned char *str); //接收温度+湿度数据并且校验#endifC文件:#include "dht11.h"#include <intrins.h>static unsigned char flag;void Delayus(void){unsigned char i;for(i=0;i<1;i++);}void Delay10ms(void)//12M晶振下延时{unsigned char i,j,k;for(i=5;i>0;i--)for(j=4;j>0;j--){for(k=248;k>0;k--);}}void Start(void){DA TA=1;Delay10ms();DA TA=0;Delay10ms(); //主机把总线拉低必须大于18ms 保证DHT11能检测到起始信号Delay10ms();Delay10ms();DA TA=1;Delayus(); //发送开始信号结束后 拉高电平延时20-40usDelayus();Delayus();}unsigned char Receive_byte(void)//接收一个字节{static unsigned char i,temp;static unsigned char data_byte;for (i=0;i<8;i++){ flag=2;while((!DA TA)&&flag++); //等待50us的低电平开始信号结束Delayus();//时间为26us-28us 表示接收的为数据'0'Delayus();Delayus();temp=0;flag=2;if(DA TA==1)temp=1;flag=2;while(DA TA&&flag++);//等待数据信号高电平 '0'为26us-28us '1'为70us if(flag==1)break;data_byte<<=1;//接收的数据为高位在前 右移data_byte|=temp;}return data_byte;}void DHT11_DA TA( unsigned char *str) //接收温度+湿度数据并且校验{ static unsigned char T_H,T_L,R_H,R_L,check,num_check;Start();//开始信号DA TA=1;if(!DA TA){flag=2;while((!DA TA)&&flag++);//判断从机发出80us的低电平响应信号是否结束//flag=2;while(DA TA&&flag++); //判断从机发出80us的高电平是否结束 如结束则主机进入数据接收状态R_H=Receive_byte();//湿度高位R_L=Receive_byte();//湿度低位T_H=Receive_byte();//温度高位T_L=Receive_byte();//温度低位check=Receive_byte();//校验位DA TA=0; //当最后一bit数据接完毕后 从机拉低电平50us//Delayus();Delayus();Delayus();Delayus();Delayus();Delayus();DA TA=1;num_check=R_H+R_L+T_H+T_L;if(num_check==check)//判断读到的四个数据之和是否与校验位相同{//温湿度低8位数据为零*str=T_H; str++;*str=R_H; str++;*str='\0';check=num_check;}}}。
DHT11
DHT11函数主函数Main.c#include"display.h"#include<reg51.h>#include"dht11.h"#define uint unsigned int#define uchar unsigned char extern uchar group[5];void main(){dht11_init();while(1){if(dht11_read())while(1)display(group[2]);elsewhile(1)display(0);}}头文件display.h#ifndef __DHT11_H_#define __DHT11_H_#include<reg51.h>#define uint unsigned int#define uchar unsigned charsbit dat=P3^7;void dht11_init();bit dht11_read();#endif#ifndef __DISPLAY_H_#define __DISPLAY_H_#include<reg51.h>#define uint unsigned int#define uchar unsigned charsbit guan1=P2^4; //位选:第1个数码管iosbit guan2=P2^5; //位选:第2个数码管iosbit guan3=P2^6; //位选:第3个数码管iosbit guan4=P2^7; //位选:第4个数码管iovoid display(uint num);#endif下面函数为读取函数/******************************************************函数:单总线读操作*备注:使用定时器 0***************************************************/#include"dht11.h"uchar group[5];//一二位湿度整数小数三四位温度整数小数五温湿度和/******************************************************函数名:void dht11_init()*函数功能:*输入:无*输出:0 或 1*备注:使用定时器0用于计数***************************************************/void dht11_init(){TMOD|=0x01; //设置定时器0为工作方式1TMOD&=0xfd;TR0=1;ET0=0;}/******************************************************函数名:uchar dht11_read()*函数功能:单总线读操作*输入:无*输出:0 或 1*备注:使用定时器0用于计数***************************************************/bit dht11_read()uchar a,b;dat=1;dat=0;TH0=0xb8;TL0=0x00;TF0=0; //计数20毫秒while(TF0==0);dat=1;TH0=0xff;TL0=0xdb; //计数40微秒TF0=0;//将溢出标志位清零while(TF0==0);//等待溢出if(dat==0){while(dat==0);while(dat==1);for(a=0;a<5;a++){for(b=0;b<8;b++){while(dat==0);TH0=0xff;TL0=0xe4; //计数30微秒TF0=0;//将溢出标志位清零while(TF0==0);group[a]<<=1;if(dat==1)group[a]|=0x01;else group[a]&=0xfe;while(dat==1);}}if(group[4]==group[0]+group[1]+group[2]+group[3]){//P2=0;return 1; }else{//P2=0;return 0; }}else{//P2=0;return 0; }}。
DHT11程序代码
//现象是循环显示温度和湿度各显示三秒(小数位显示0)//若需将dht11.c和其他的硬件结合使用,只需在需用到温湿度值的文件加下面声明//extern int wendu, shidu;(wendu是温度值,shidu是湿度值,比实际的温湿度值扩大了十倍)//一、//文件名保存为main.c/*************************************************************************************** *****///除了dht11的接口外,其他的电路原理图与天祥的C51板对应//现象是循环显示温度和湿度各显示三秒#include "dht11.h"#include <reg52.h>sbit DULA = P2^6; //数码管位定义sbit WELA = P2^7;static unsigned char flag; //中断计数标志static unsigned char code array[]= { //数码管编码0x3f,0x06,0x5b,0x4f,0x6,0x6d,0x7d,0x07,0x7f,0x6f页脚内容1};extern int wendu, shidu;static void InitTime(void);void Delay_1ms(unsigned int ms);static void SMG_Display(unsigned int value);int main(void){unsigned char mark = 0;//先等上电稳定Delay_1ms(1000);//因为读一次数据dht11才会触发一次采集数据.//即在先使用数据时采集一次数据ReadTempAndHumi();//因为在两次采集数据需一定的时间间隔,这里还可减少Delay_1ms(3000); //设定定时器InitTime();while(1)页脚内容2{//三秒读一次温湿度if(flag == 60){flag = 0;mark++;/*//读温湿度,可检测函数调用是否失败,//函数返回OK(1)表示成功,返回EROR(0)表示失败//OK和EROR是在dht11.H中定义的宏*/ReadTempAndHumi();}if(mark % 2 == 0){//显示温度SMG_Display(wendu);页脚内容3}else{//显示湿度SMG_Display(shidu);}}return 0;}//设定定时器static void InitTime(void){TH0 = (unsigned char)((65535 - 50000) >> 8);TL0 = (unsigned char)(65535 - 50000) ;TMOD = 0X01;TR0 = 1;ET0 = 1;页脚内容4EA = 1;}//数码管显示函数static void SMG_Display(unsigned int value){unsigned char ge, bai, shi;ge = value % 10;shi = value % 100 / 10;bai = value % 1000 / 100;WELA = 1;P0 = 0XFE;WELA = 0;P0 = 0XFF;DULA = 1;P0 = array[bai];DULA = 0;页脚内容5Delay_1ms(2);WELA = 1;P0 = 0XFD;WELA = 0;P0 = 0XFF;DULA = 1;P0 = array[shi];P0 |= 0x80; /*显示小数点*/DULA = 0;Delay_1ms(2);WELA = 1;P0 = 0XFB;WELA = 0;P0 = 0XFF;DULA = 1;P0 = array[ge];页脚内容6DULA = 0;Delay_1ms(2);}//中断函数void timer(void) interrupt 1{TH0 = (unsigned char)((65535 - 50000) >> 8);TL0 = (unsigned char)(65535 - 50000);flag++;}/*************************************************************************************** *****/二、保存文件名dht11.h(保存时必须命名为dht11.h)/*************************************************************************************** *****//*************************************************************************************** *****/页脚内容7#ifndef __dht11_H__#define __HDT11_H__//设定标志(static unsigned char status)的宏值#define OK 1#define EROR 0extern void Delay_1ms(unsigned int ms);//函数的返回值表示读取数据是否成功OK表示成功EROR表示失败extern unsigned char ReadTempAndHumi(void);#endif/*************************************************************************************** *****//*************************************************************************************** *****/三、保存的文件名是dht11.c/*************************************************************************************** *****//***************************************************************************************页脚内容8*****//*************************************************************************************** *****///单片机时钟为11.0592M#include "dht11.h"#include <reg52.h>//请根据自己的dht11接的IO口来改动位定义sbit dht11 = P2^0;//防止在与硬件通信时发生死循环的计数范围#define NUMBER 20#define SIZE 5static unsigned char status;//存放五字节数据的数组static unsigned char value_array[SIZE];/*可在其他的文件引用温湿度值,实际是温度的整数的10倍如dht11读回的温度是26,则wendu = 260, 湿度同理*/int wendu, shidu;页脚内容9static unsigned char ReadValue(void);extern void Delay_1ms(unsigned int ms){unsigned int x, y;for(x = ms; x > 0; x--){for(y = 124; y > 0; y--);}}static void Delay_10us(void){unsigned char i;i--;i--;i--;i--;i--;页脚内容10i--;}/*读一个字节的数据*/static unsigned char 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 = EROR; //设定错误标志页脚内容11return 0; //函数执行过程发生错误就退出函数}//26-28us的高电平表示该位是0,为70us高电平表该位1 Delay_10us();Delay_10us();Delay_10us();//延时30us后检测数据线是否还是高电平if(dht11 != 0) {//进入这里表示该位是1value++;//等待剩余(约40us)的高电平结束while(dht11 != 0 && count++ < NUMBER){dht11 = 1;}if(count >= NUMBER){页脚内容12status = EROR; //设定错误标志return 0;}}}return (value);}//读一次的数据,共五字节extern unsigned char 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 Delay_10us();页脚内容13Delay_10us();Delay_10us();Delay_10us();if(dht11 != 0) //检测应答信号,应答信号是低电平{//没应答信号EA = 1;return EROR;}else{//有应答信号while(dht11 == 0 && count++ < NUMBER); //等待应答信号结束if(count >= NUMBER) //检测计数器是否超过了设定的范围{dht11 = 1;EA = 1; return EROR; //读数据出错,退出函数页脚内容14}count = 0;dht11 = 1;//释放数据线//应答信号后会有一个80us的高电平,等待高电平结束while(dht11 != 0 && count++ < NUMBER);if(count >= NUMBER){dht11 = 1;EA = 1;return EROR; //退出函数}//读出湿.温度值for(i = 0; i < SIZE; i++){value_aray[i] = ReadValue();if(status = EROR)//调用ReadValue()读数据出错会设定status为EROR {页脚内容15dht11 = 1;EA = 1;return EROR;}//读出的最后一个值是校验值不需加上去if(i != SIZE - 1){//读出的五字节数据中的前四字节数据和等于第五字节数据表示成功check_value += value_aray[i];}}//end for//在没用发生函数调用失败时进行校验if(check_value == value_array[SIZE - 1]){//将温湿度扩大10倍方便分离出每一位shidu = value_aray[0] * 10;wendu = value_aray[2] * 10;页脚内容16dht11 = 1;EA = 1;return OK; //正确的读出dht11输出的数据}else{//校验数据出错EA = 1; return EROR;}}}/*************************************************************************************** *****//*************************************************************************************** *****//*************************************************************************************** *****/页脚内容17。
温湿度传感器DHT11程序编写
/******************DHT11******************************** FileName:dht11.cAuthor:沧海麒麟Date:2011.05.29Version :1.0Description:适用于ATmega16(L)Function: 利用串口发送温度和湿度到电脑,同时用液晶显示*/#include <iom16v.h>#include <macros.h>#include <avrdef.h>#include "delay.c"#include "LCM1602.c"#define uchar unsigned char#define uint unsigned int#define DDR_1 DDRA|=BIT(PA0)#define DDR_0 DDRA&=~BIT(PA0)#define PORT_1 PORTA|=BIT(PA0)#define PORT_0 PORTA&=~BIT(PA0)#define MOSIN (PINA&0X01)uchar U8T_data_H,U8T_data_L,U8RH_data_H,U8RH_data_L,U8checkdata; uchar DHT11_5DATA[5];uchar U8temp;uchar flag = 0;uchar humidity[] = "humidity :";uchar temperature[] = "temperature:";void COM(void){uchar i,j,m;for(i=0;i<5;i++){DHT11_5DATA[i]=0X00;for(j=0;j<8;j++){while(!MOSIN);//等待高电平的到来,当高电平到来后便开始计时Delay(60);//for(m=0;m<50;m++); //延时50us后看还是不是高电平,如果是高那么这位就为1,否则为0if(MOSIN){DHT11_5DATA[i] |= BIT(7-j);while(MOSIN);}//end of if}//end of for}//end of for}void DHT11(void){uchar i;DDR_1;PORT_0;Delay_Nms(20);//主机拉低18msPORT_1;//总线由上拉电阻拉高主机延时20usDelay(30);//for(i=0;i<23;i++); //此操作为微秒级的延时DDR_0;//主机设为输入判断从机响应信号Delay(15);//for(i=0;i<10;i++);//判断从机是否有低电平响应信号如不响应则跳出,响应则向下运行if(!MOSIN) //{while(!MOSIN);//判断从机是否发出 80us 的低电平响应信号是否结束while(MOSIN);//判断从机是否发出 80us 的高电平,如发出则进入数据接收状态COM();//数据接收状态DDR_1 ;PORT_1 ;U8temp=(DHT11_5DATA[0]+DHT11_5DATA[1]+DHT11_5DATA[2]+DHT11_5DATA[3]);//数据校验if(DHT11_5DATA[4]==U8temp){U8RH_data_H = DHT11_5DATA[0];U8RH_data_L = DHT11_5DATA[1];U8T_data_H = DHT11_5DATA[2];U8T_data_L = DHT11_5DATA[3];U8checkdata = DHT11_5DATA[4];}}}/***********端口初始化函数**********************/void init_port(void){PORTD|= 0x02; //注意这两个管脚要配置为输出DDRD |= 0x02;}/************串口初始化函数*********************/void init_uart0(void){UCSRB = 0x00;UBRRH = 0x00;UBRRL = 0x67;UCSRA = (1 << U2X);//双倍率工作模式UCSRB = (1 << RXEN)|(1 << TXEN);//|(1 << UCSZ2);使能接收器和发射器 UCSRC = 0x80|(1 << UCSZ1)|(1 << UCSZ0);}/************发送一个字节函数********************/void Send_Uart0(uchar data){while(!(UCSRA&(1<<UDRE)));UDR=data;}/************T/C1初始化函数**********************/void Timer1_InterruptMode(void)//T/C1中断方式函数{//stop errant interrupts until set upCLI(); //disable all interruptsTCCR1B = 0x00; //stopTCNT1H = 0xCF; //setupTCNT1L = 0x2C;TCCR1B = 0x03; //start TimerMCUCR = 0x00;GICR = 0x00;TIMSK = 0x04; //timer interrupt sourcesSEI(); //re-enable interrupts//all peripherals are now initialized}/************总初始化函数**********************/void Init_Devices(void){Init_Port();Init_1602(0x18);init_port();init_uart0();Timer1_InterruptMode();}/************中断服务函数**********************/#pragma interrupt_handler timer1_ovf_isr:iv_TIM1_OVF //9 void timer1_ovf_isr(void){//TIMER1 has overflowedTCNT1H = 0xCF; //reload counter high valueTCNT1L = 0x2C; //reload counter low valueflag++;}void main(void){Init_Devices();DisplayString(0,0,humidity);DisplayString(0,1,temperature);while(1){if(flag==10)//1s采集一次{ //调用温湿度读取子程序flag=0;CLI();DHT11();DisplayNumber(12,0,U8RH_data_H);//1602显示湿度Delay_Nms(10);DisplayNumber(12,1,U8T_data_H);//1602显示温度 Send_Uart0(U8RH_data_H);Send_Uart0(U8T_data_H);Send_Uart0(U8checkdata);Send_Uart0(U8temp);SEI();}}}。
单片机温度湿度控制程序(dht11)
1、温度湿度控制主程序(单片机)#include<reg52.h>#include "dht11.h"#define uchar unsigned char#define uint unsigned intsbit beep=P2^3;sbit k1=P3^2;sbit k2=P3^3;sbit k3=P3^6;sbit k4=P3^7;sbit rs=P3^5;sbit lcden=P3^4;uchar table0[]="T:00.00 TM:00.0 ";//初始化液晶温度实测值以及门限值缓存uchar table1[]="H:00.00 HM:00.0 ";//初始化液晶湿度实测值以及门限值缓存uchar table3[]="This is T/H test";//系统开机显示内容初始化缓存uchar table4[]="Result is coming";//系统开机显示内容初始化缓存static uchar flag;extern int temp_value,humi_value;void Delay_1ms(uint ms);uint TM,HM;void delay(uint x)//{uint a,b;for(a=x;a>0;a--)for(b=10;b>0;b--);}void delay1(uint x)//延时程序{uint a,b;for(a=x;a>0;a--)for(b=100;b>0;b--);}void write_com(uchar com)//液晶写指令操作{P0=com;rs=0;lcden=0;delay(10);lcden=1;delay(10);lcden=0;}void write_date(uchar date)//液晶写数据操作{P0=date;rs=1;lcden=0;delay(10);lcden=1;delay(10);lcden=0;}void init()//液晶初始化{write_com(0x38);delay(1);write_com(0x0c);delay(1);write_com(0x06);delay(1);write_com(0x01);delay(1);}void LCD_Display(uchar buff1[],uchar buff2[])//液晶显示程序{uchar aa;init();//液晶初始化write_com(0x80+16);//写入第一行数据指令delay(1);for(aa=0;aa<16;aa++)//写入第一行待显示数据{write_date(buff1[aa]);}write_com(0xc0+16); //写入第二行数据指令for(aa=0;aa<16;aa++)//写入第一行待显示数据{write_date(buff2[aa]);}for(aa=0;aa<16;aa++){write_com(0x18);delay(1);}}void Tem_Ch(uchar AA,uchar nn)//T门限数值替换{switch(AA){case 0:table0[nn]='0';break;case 1:table0[nn]='1';break;case 2:table0[nn]='2';break;case 3:table0[nn]='3';break;case 4:table0[nn]='4';break;case 5:table0[nn]='5';break;case 6:table0[nn]='6';break;case 7:table0[nn]='7';break;case 8:table0[nn]='8';break;case 9:table0[nn]='9';break;}}void Hum_Ch(uchar BB,uchar mm)//H门限数值替换{switch(BB){case 0:table1[mm]='0';break;case 1:table1[mm]='1';break;case 2:table1[mm]='2';break;case 3:table1[mm]='3';break;case 4:table1[mm]='4';break;case 5:table1[mm]='5';break;case 6:table1[mm]='6';break;case 7:table1[mm]='7';break;case 8:table1[mm]='8';break;case 9:table1[mm]='9';break;}}///////////void YZ_Resh()//门限值更新{uchar A1,A2,A3;A1=TM/10;//取十位A2=TM%10;//取个位A3=0;Tem_Ch(A1,11);//写入对应的液晶显示缓存Tem_Ch(A2,12);//写入对应的液晶显示缓存Tem_Ch(A3,14);//写入对应的液晶显示缓存A1=HM/10;A2=HM%10;A3=0;Hum_Ch(A1,11);Hum_Ch(A2,12);Hum_Ch(A3,14);}void key_test()//按键检测/*根据按键的检测结果进行温度湿度门限值的设定*/{bit kk1;bit kk2;bit kk3;bit kk4;uchar temp;k1=0;k2=1;k3=1;k4=1;kk1=k1;kk2=k2;kk3=k3;kk4=k4;if(kk3!=1){delay1(100);if(kk3!=1)//若可开=0且持续一段时间后任然为0,则执行有关操作{temp=P3;//按键一操作TM=TM+1;//提高温度门限值YZ_Resh();////更新液晶显示缓存的门限值LCD_Display(table0,table1);//液晶显示数值}}if(kk4!=1){delay1(100);if(kk4!=1){temp=P3;//按键二操作TM=TM-1;//降低温度门限值YZ_Resh();////更新液晶显示缓存的门限值LCD_Display(table0,table1);//液晶显示数值}}k1=1;k2=0;k3=1;k4=1;kk1=k1;kk2=k2;kk3=k3;kk4=k4;if(kk3!=1){delay1(100);if(kk3!=1){temp=P3;//按键三操作HM=HM+1;//提高湿度门限YZ_Resh();//更新液晶显示缓存的门限值LCD_Display(table0,table1);//液晶显示数值}}if(kk4!=1){delay1(100);if(kk4!=1){temp=P3;//按键四操作HM=HM-1;//降低湿度门限YZ_Resh();//更新液晶显示缓存的门限值LCD_Display(table0,table1);//液晶显示数值}}}void TempAndHumi_Resh()//更新液晶显示缓存中的温度湿度数值/*根据测得的结果将液晶显示缓存中的数据进行替换*/{uchar ge,shi,bai;ge=temp_value%10;shi=temp_value%100/10;bai=temp_value%1000/100;Tem_Ch(bai,2);Tem_Ch(shi,3);Tem_Ch(ge,5);ge=humi_value%10;shi=humi_value%100/10;bai=humi_value%1000/100;Hum_Ch(bai,2);Hum_Ch(shi,3);Hum_Ch(ge,5);}void beep_control()//警报状态控制函数/*如果实测温度超过门限值则报警*/{if(temp_value>(TM*10)){beep=0;}else{if(humi_value>(HM*10)){beep=0;}else{beep=1;}}}void main(){uint m=0;TM=25;//设定温度初始门限值:25°CHM=50;//设定湿度初始门限值:50%YZ_Resh();//更新液晶显示缓存的门限值beep=1;//关闭蜂鸣器LCD_Display(table3,table4);//显示系统本系统信息while(1){key_test();//监测按键状态,并根据对应按键改变温度湿度门限值,并显示if (m<100)//循环计时,3秒钟{m++;Delay_1ms(30);}else//当m=100时即为3秒时间到,则进行温度湿度数据采集{m=0;ReadTempAndHumi();//采集温度湿度数据TempAndHumi_Resh();//更新液晶显示缓存中的温度湿度数值LCD_Display(table0,table1);//显示当前温度湿度实测值以及门限值}beep_control();//根据门限值以及实测值进行警报状态设置}}#include <reg52.h>#include "dht11.h"#define uchar unsigned char#define uint unsigned int#define NUMBER 20#define SIZE 5sbit dht11=P2^2;static uchar status;static uchar value_array[SIZE];//定义存放DHT11采集的5个字节的数组int temp_value,humi_value;static uchar ReadValue(void);extern void Delay_1ms(uint ms)//毫秒延时,延时时间为ms毫秒{uint x,y;for(x=ms;x>0;x--){for(y=124;y>0;y--);}}static void Delay_10us(void)//10微秒延时{uchar i;i--;i--;i--;i--;i--;i--;}static uchar ReadValue(void)//读一个字节数据的程序{uchar count,value=0,i;status=OK;//设定标志位正常状态for(i=8;i>0;i--){value<<=1;//高位在前进行接收数据count=0;while(dht11==0&&count++<NUMBER);if(count>=NUMBER)//若大于最大数值则出错{status=ERROR;//设定错误标志return 0;//函数执行过程发生错误就退出函数}Delay_10us();//进行30us的延时Delay_10us();Delay_10us();if(dht11!=0)//再次检测是否为高电平{value++;//进入本函数说明信号为1,则进行自加while(dht11!=0&&count++<NUMBER){dht11=1;}if(count>=NUMBER){status=ERROR;return 0;}}}return(value);//返回读取的结果}extern uchar ReadTempAndHumi(void)//读取一次温度湿度数据,共5个字节{uchar i=0,check_value=0,count=0;EA=0;dht11=0;//拉低数据线20msDelay_1ms(20);dht11=1;//释放数据线,以用于检测低电平应答信号Delay_10us();//延时40usDelay_10us();Delay_10us();Delay_10us();if(dht11!=0)//检测应答信号,应答信号为低电平{EA=1;//无低电平。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
//现象是循环显示温度和湿度各显示三秒(小数位显示0)//若需将dht11.c和其他的硬件结合使用,只需在需用到温湿度值的文件加下面声明//extern int wendu, shidu;(wendu是温度值,shidu是湿度值,比实际的温湿度值扩大了十倍)//一、//文件名保存为main.c/****************************************************************************** **************///除了dht11的接口外,其他的电路原理图与天祥的C51板对应//现象是循环显示温度和湿度各显示三秒#include "dht11.h"#include <reg52.h>sbit DULA = P2^6; //数码管位定义sbit WELA = P2^7;static unsigned char flag; //中断计数标志static unsigned char code array[]= { //数码管编码0x3f,0x06,0x5b,0x4f,0x6,0x6d,0x7d,0x07,0x7f,0x6f};extern int wendu, shidu;static void InitTime(void);void Delay_1ms(unsigned int ms);static void SMG_Display(unsigned int value);int main(void){unsigned char mark = 0;//先等上电稳定Delay_1ms(1000);//因为读一次数据dht11才会触发一次采集数据.//即在先使用数据时采集一次数据ReadTempAndHumi();//因为在两次采集数据需一定的时间间隔,这里还可减少Delay_1ms(3000);//设定定时器InitTime();while(1){//三秒读一次温湿度if(flag == 60){flag = 0;mark++;/*//读温湿度,可检测函数调用是否失败,//函数返回OK(1)表示成功,返回EROR(0)表示失败//OK和EROR是在dht11.H中定义的宏*/ReadTempAndHumi();}if(mark % 2 == 0){//显示温度SMG_Display(wendu);}else{//显示湿度SMG_Display(shidu);}}return 0;}//设定定时器static void InitTime(void){TH0 = (unsigned char)((65535 - 50000) >> 8); TL0 = (unsigned char)(65535 - 50000) ; TMOD = 0X01;TR0 = 1;ET0 = 1;EA = 1;}//数码管显示函数static void SMG_Display(unsigned int value) {unsigned char ge, bai, shi;ge = value % 10;shi = value % 100 / 10;bai = value % 1000 / 100;WELA = 1;P0 = 0XFE;WELA = 0;P0 = 0XFF;DULA = 1;P0 = array[bai];DULA = 0;Delay_1ms(2);WELA = 1;P0 = 0XFD;WELA = 0;P0 = 0XFF;DULA = 1;P0 = array[shi];P0 |= 0x80; /*显示小数点*/DULA = 0;Delay_1ms(2);WELA = 1;P0 = 0XFB;WELA = 0;P0 = 0XFF;DULA = 1;P0 = array[ge];DULA = 0;Delay_1ms(2);}//中断函数void timer(void) interrupt 1{TH0 = (unsigned char)((65535 - 50000) >> 8);TL0 = (unsigned char)(65535 - 50000);flag++;}/****************************************************************************** **************/二、保存文件名dht11.h(保存时必须命名为dht11.h)/****************************************************************************** **************//****************************************************************************** **************/#ifndef __dht11_H__#define __HDT11_H__//设定标志(static unsigned char status)的宏值#define OK 1#define EROR 0extern void Delay_1ms(unsigned int ms);//函数的返回值表示读取数据是否成功OK表示成功EROR表示失败extern unsigned char ReadTempAndHumi(void);#endif/****************************************************************************** **************//****************************************************************************** **************/三、保存的文件名是dht11.c/****************************************************************************** **************//****************************************************************************** **************//****************************************************************************** **************///单片机时钟为11.0592M#include "dht11.h"#include <reg52.h>//请根据自己的dht11接的IO口来改动位定义sbit dht11 = P2^0;//防止在与硬件通信时发生死循环的计数范围#define NUMBER 20#define SIZE 5static unsigned char status;//存放五字节数据的数组static unsigned char value_array[SIZE];/*可在其他的文件引用温湿度值,实际是温度的整数的10倍如dht11读回的温度是26,则wendu = 260, 湿度同理*/int wendu, shidu;static unsigned char ReadValue(void);extern void Delay_1ms(unsigned int ms){unsigned int x, y;for(x = ms; x > 0; x--){for(y = 124; y > 0; y--);}}static void Delay_10us(void){unsigned char i;i--;i--;i--;i--;i--;i--;}/*读一个字节的数据*/static unsigned char 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 = EROR; //设定错误标志return 0; //函数执行过程发生错误就退出函数}//26-28us的高电平表示该位是0,为70us高电平表该位1Delay_10us();Delay_10us();Delay_10us();//延时30us后检测数据线是否还是高电平if(dht11 != 0) {//进入这里表示该位是1value++;//等待剩余(约40us)的高电平结束while(dht11 != 0 && count++ < NUMBER){dht11 = 1;}if(count >= NUMBER){status = EROR; //设定错误标志return 0;}}}return (value);}//读一次的数据,共五字节extern unsigned char 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 Delay_10us();Delay_10us();Delay_10us();Delay_10us();if(dht11 != 0) //检测应答信号,应答信号是低电平{//没应答信号EA = 1;return EROR;}else{//有应答信号while(dht11 == 0 && count++ < NUMBER); //等待应答信号结束if(count >= NUMBER) //检测计数器是否超过了设定的范围{dht11 = 1;EA = 1; return EROR; //读数据出错,退出函数}count = 0;dht11 = 1;//释放数据线//应答信号后会有一个80us的高电平,等待高电平结束while(dht11 != 0 && count++ < NUMBER);if(count >= NUMBER){dht11 = 1;EA = 1;return EROR; //退出函数}//读出湿.温度值for(i = 0; i < SIZE; i++){value_aray[i] = ReadValue();if(status = EROR)//调用ReadValue()读数据出错会设定status为EROR{dht11 = 1;EA = 1;return EROR;}//读出的最后一个值是校验值不需加上去if(i != SIZE - 1){//读出的五字节数据中的前四字节数据和等于第五字节数据表示成功check_value += value_aray[i];}}//end for//在没用发生函数调用失败时进行校验if(check_value == value_array[SIZE - 1]){//将温湿度扩大10倍方便分离出每一位shidu = value_aray[0] * 10;wendu = value_aray[2] * 10;dht11 = 1;EA = 1;return OK; //正确的读出dht11输出的数据}else{//校验数据出错EA = 1; return EROR;}}}/****************************************************************************** **************//****************************************************************************** **************//****************************************************************************** **************/。