51单片机做的温湿度测量仪
时间:11-29
来源:互联网
点击:
本人去年用51单片机做的温湿度传感器模块,有实物,有程序,供大家分享。
该1602液晶的D0~D7数据口连接单片机的P17~P10口,所以程序里的指令和数据都是逆向输入的。
程序和电路图下载:http://www.51hei.com/f/温湿度传感器+1602原理图.rar
#include#include #include #define uchar unsigned char #define uint unsigned int #define noACK 0 #define ACK 1#define STATUS_REG_W 0x06#define STATUS_REG_R 0x07#define MEASURE_TEMP 0x03 #define MEASURE_HUMI 0x05 #define RESET 0x1esbit SCK =P1^0;sbit DATA=P1^1;sbit led1=P1^7; sbit rs=P2^3; //H数据,L命令sbit en=P2^5; //高脉冲使能,使能脉宽最小150nssbit rw=P2^4;uchar code table_temp[]=" TEMP: ";uchar code table_humi[]=" HUMI: ";uchar code table_c[]=" C ";uchar code table_p[]=" % ";uchar error=0; void delayms(uint z) { uint i,j; for(i=z;i>0;i--) for( j=110;j>0;j--); } //启动时序 void transstart() { SCK=1;_nop_(); DATA=0;_nop_(); SCK=0;_nop_();_nop_();_nop_(); SCK=1;_nop_(); DATA=1;_nop_(); SCK=0; } //写入命令子函数 uchar write_byte(uchar value) { uchar i; for(i=0x80;i>0;i=i/2) { if(i&value) DATA=1; else DATA=0; SCK=1; _nop_();_nop_();_nop_(); SCK=0; } DATA=1; SCK=1; error=DATA; SCK=0; return error; } //从传感器读数据 uchar read_byte(bit ack) { uchar i,val=0; DATA=1; for(i=0x80;i>0;i=i/2) { SCK=1; if(DATA) val=val|i; SCK=0; } DATA=!ack; SCK=1; _nop_();_nop_();_nop_(); SCK=0; DATA=1; return val; } //void connectionreset() { uchar i; DATA=1; SCK=0; for(i=0;i<9;i++) { SCK=1; SCK=0; } transstart(); } uint measure1() //测量温度函数{ uchar value_1,value_2;uint tempvalue;transstart();error+=write_byte(MEASURE_TEMP);if(error!=0){connectionreset();}else { while(DATA==1){_nop_();}if(DATA==0){ value_1=read_byte(ACK);value_2=read_byte(noACK);tempvalue=value_2+value_1*256; //转换成 16 位的 int 型}else error=1; } return tempvalue; }uint measure2() //测量湿度函数{ uchar value_1,value_2; uint tempvalue; transstart(); error+=write_byte(MEASURE_HUMI); if(error!=0) connectionreset(); else { while(DATA==1) _nop_(); if(DATA==0) { value_1=read_byte(ACK);value_2=read_byte(noACK); tempvalue=value_2+value_1*256; } else error=1; } return tempvalue; } void lcdwrdata(uchar dat){dat = ((dat&0x01)<7)|((dat&0x02)<5)|((dat&0x04)<3)|((dat&0x08)<1)|((dat&0x10)>>1)|((dat&0x20)>>3)|((dat&0x40)>>5)|((dat&0x80)>>7);rs=1;//写数据时RS拉高en=1;P0=dat;delayms(6);en=0;delayms(6);}void lcdwrcom(uchar cdat)//写指令数据到LCD { cdat = ((cdat&0x01)<7)|((cdat&0x02)<5)|((cdat&0x04)<3)|((cdat&0x08)<1)|((cdat&0x10)>>1)|((cdat&0x20)>>3)|((cdat&0x40)>>5)|((cdat&0x80)>>7);rs=0;//写指令时RS拉低en=1;P0=cdat;//delayms(6);//不加此延时将导致不能写入指令,但能写入显示数据en=0;delayms(6);}void lcd_init(){lcdwrcom(0x38); //0x38设置显示模式为:16X2显示,5X7点阵,8位数据接口lcdwrcom(0x0c); //打开显示光标闪烁lcdwrcom(0x06); //lcdwrcom(0x01); //}void display(float temp,float humi) //1602显示函数(温度,湿度){uint a,b,c,d,e,f,g,h;a=(temp/1000);b=((temp-a*1000)/100);c=((temp-a*1000-b*100)/10);d=(temp-a*1000-b*100-c*10);e=(humi/1000);f=((humi-e*1000)/100);g=((humi-e*1000-f*100)/10);h=(humi-e*1000-f*100-g*10);lcdwrcom(0x80+0x07);lcdwrdata(0+a);lcdwrcom(0x80+0x08);lcdwrdata(0+b);lcdwrcom(0x80+0x09);lcdwrdata(.) ;lcdwrcom(0x80+0x0A);lcdwrdata(0+c);lcdwrcom(0x80+0x0B);lcdwrdata(0+d);lcdwrcom(0x80+0x47);lcdwrdata(0+e);lcdwrcom(0x80+0x48);lcdwrdata(0+f);lcdwrcom(0x80+0x49);lcdwrdata(.) ;lcdwrcom(0x80+0x4A);lcdwrdata(0+g);lcdwrcom(0x80+0x4B);lcdwrdata(0+h);}float calc_temp(uint tempvalue) //计算温度值子函数 { const float d1=-39.9;const float d2=+0.01;float temp_final;tempvalue=tempvalue&0x3fff; //取出低 14 位temp_final=d1+d2*((float)tempvalue);return temp_final; //返回温度值}//计算湿度值子函数 float calc_humi(float humivalue) { const float c1=-4.0,c2=0.0405,c3=-0.0000028,t1=0.01,t2=0.00008; float rh=humivalue; float rhlin; float rhtrue; rhlin=c1+c2*rh+c3*rh*rh; rhtrue=(27.87-25)*(t1+t2*rh)+rhlin; if(rhtrue>100) rhtrue=100; if(rhtrue<0.1) rhtrue=0.1; humivalue=rhtrue; return humivalue;}void main() { uint i; //定义计数器uint value1; //定义传感器传出来的数值(16位)uint value2; //定义传感器传出来的数值(16位)float dis_tempvalue; //定义温度变量float dis_humivalue; //定义湿度变量//以下是初始化液晶操作rw=0;delayms(200);en=0;lcd_init();//以下是液晶固定显示lcdwrcom(0x80+0x00); //第1行00位置for(i=0;i<7;i++){lcdwrdata(table_temp[i]);}lcdwrcom(0x80+0x0C); //第1行0C位置for(i=0;i<4;i++){lcdwrdata(table_c[i]);}lcdwrcom(0x80+0x40); //第2行40位置for(i=0;i<7;i++){lcdwrdata(table_humi[i]);}lcdwrcom(0x80+0x4C); //第2行4C位置for(i=0;i<4;i++){lcdwrdata(table_p[i]);}//while(1) { connectionreset(); error=0; value1=measure1(); value2=measure2(); if(error==0) { led1=0; delayms(200); led1=1; delayms(200);dis_tempvalue=calc_temp(value1); //计算温度值dis_humivalue=calc_humi(value2); //计算湿度值display(dis_tempvalue*100,dis_humivalue*100); //LCD1602显示温湿度} else { continue; } } }
51单片机温湿度测量 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)