完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
.
基于51单片机的时间温度报警系统 基于AT89C51的天气温度报警系统,采用Protues仿真。 元件: DS1302时钟芯片 见图(1) DS18B20温度传感器 见图(2) LM016L(1602)液晶 见图(3) AT89C51单片机 见图(4) LED灯若干 见图(4) 蜂鸣器一只 用于报警 本人不写这个报警程序了 其实挺简单的 基于51单片机的时间温度报警系统X图(1) DS1302 基于51单片机的时间温度报警系统图(2)DS18B20 基于51单片机的时间温度报警系统图(3) LM016L 基于51单片机的时间温度报警系统图(4) AT89C51 以下为源代码 #include #include #define uchar unsigned char #define uint unsigned int uchar table[]='Week:'; uchar table2[]='Starting now'; uchar table3[]='Please,writ...'; uchar code digit[]='0123456789'; ***it lcden=P2^4; //定义液晶E接 ***it lcdrs=P2^2; //定义液晶RS接 ***it lcdrw=P2^3; //定义液晶RW接 ***it DQ=P2^0; //定义温度传感器DQ接 ***it CE=P2^5; //定义时钟芯片RST接 ***it SCLK=P2^6; //定义时钟芯片SCLK接 ***it IO=P2^7; //定义时钟芯片IO接 uchar num; uchar flag; uchar dat,LSB,MSB,TN,TD,tab,TH,TL,CR,TA; uchar YY,MM,DD,HH,MIN,SEC,WEEK; //定义年、月、日、小时、分、秒、周 void delayus(uchar x) { while(--x) { _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); _nop_(); } } void delay(uint z) // 延迟函数 { uchar i; while(z--) for(i=0;i<50;i++); } void Init_DS18B20() { //初始化DS18B20必须先给DS18B20一个复位脉冲,接收到复位脉冲后DS18B20会返回一个存在脉冲 DQ=1; //DQ先置高电平 _nop_(); //延时 _nop_(); DQ=0; //DQ置低电平(拉低总线),开始初始化 delayus(60); //DQ置低电平后必须延时至少480us,此处延时600us DQ=1; //然后DQ置高电平(释放总线) delayus(3); //释放总线后要求延时15-60us,此处延时30us flag=DQ; //读取DQ并付值flag,如果flag为0,表示返回了一个存在脉冲,初始化完成。相反失败 delayus(20); } uchar read_scratchpad() { uchar i=0; for (i=8;i>0;i--) { DQ=1; //DQ位拉高 _nop_(); //延时1us秒 DQ = 0; // DQ置0拉低总线 dat>>=1; //左移一位 delayus(1); //延时1us-15us,此处延时10us DQ = 1; // DQ置1释放总线 delayus(1); //延时10us if(DQ==1){dat|=0x80;} //采样 else{dat|=0x00;} delayus(5); //延时50us } return dat; } void write_command(uchar com) { uchar i=0; uchar num; for (i=8; i>0; i--) { DQ=1; //先将DQ置1; _nop_(); //延时 DQ = 0; //DQ置0,拉低总线 num = com&0x01; //读取指令最低位 if(num==1) //如果为1 { delayus(1); //要求先延时1-15us,此处延时10us DQ=1; //然后释放总线 delayus(4); //延时大概45us,此处延时40us }else //如果为0 { delayus(6); //要求延时60-120us,此处延时60us DQ=1; //然后DQ置1释放总线 delayus(1); //延时10us } com>>=1; } delayus(1); } void Temperature_conversion() { Init_DS18B20(); //初始化DS18B20 write_command(0xCC); // 读取ROM中64-bit code write_command(0x4E); // 写暂存器,向暂存器中的TH、TL和configuration Register中写数据 write_command(0x50);// 向TH Register位写入数据 write_command(0x00);//向TL Register位写入数据 write_command(0x7F);//向configuration Register写入数据 delay(10); Init_DS18B20(); write_command(0xCC); // 跳过读序号列号的操作 write_command(0x44); // 启动温度转换 delay(10); Init_DS18B20();// write_command(0xCC); //跳过读序号列号的操作 write_command(0xBE); //读取温度寄存器等(共可读9个寄存器) 前两个就是温度 } void write_com_1602(uchar com) { lcdrs=0; lcdrw=0; P3=com; delay(5); lcden=1; delay(5); lcden=0; } void write_data_1602(uchar date) { lcdrs=1; lcdrw=0; P3=date; delay(5); lcden=1; delay(5); lcden=0; } void init() { uchar i=0; lcden=0; CE=0; SCLK=0; write_com_1602(0x38); write_com_1602(0x0c); write_com_1602(0x06); write_com_1602(0x01); write_com_1602(0x80); for(i=0;i<12;i++) { write_data_1602(table2[i]); delay(50); } write_com_1602(0x80+0x40); for(i=0;i<14;i++) { write_data_1602(table3[i]); delay(50); } delay(2000); write_com_1602(0x01); write_com_1602(0x80+0x40); for(i=0;i<5;i++) { write_data_1602(table[i]); delay(50); } } void display_temp1(uchar x) { uchar j,k,l; //j,k,l分别储存温度的百位、十位和个位 j=x/100; //取百位 k=(x0)/10; //取十位 l=x; //取个位 write_data_1602(digit[j]); //将百位数字的字符常量写入LCD write_data_1602(digit[k]); //将十位数字的字符常量写入LCD write_data_1602(digit[l]); //将个位数字的字符常量写入LCD delay(1); //延时1ms给硬件一点反应时间 } void display_temp2(uchar x) { write_data_1602(digit[x]); //将小数部分的第一位数字字符常量写入LCD delay(1); //延时一段时间 } void display_temp3(uchar x) { uchar k,l; //j,k,l分别储存温度的百位、十位和个位 k=x/10; //取十位 l=x; //取个位 write_data_1602(digit[k]); //将十位数字的字符常量写入LCD write_data_1602(digit[l]); //将个位数字的字符常量写入LCD delay(1); } void display_dot() { write_data_1602('.'); delay(1); } void display_cent() { write_data_1602(0xdf); write_data_1602('C'); } void display_minus() { write_data_1602(0x2d); } void checkMSB(uchar ta) { if(ta==0x07) { write_com_1602(0x80+0x48); write_data_1602(0x20); TN=MSB*16+LSB/16; TD=(LSB)*10/16; if(TN>=TH){P1=~P1;} //如果温度设置的超出上限,LED闪烁 else{P1=0xFF;} }else{ write_com_1602(0x80+0x48); display_minus(); LSB=~LSB+1; MSB=~MSB; TN=MSB*16+LSB/16; TD=(LSB)*10/16; P1=~P1; //如果温度超出设置的下限(小于0),LED闪烁 } } void write_com_1302(uchar add,com) { uchar i; CE=1; for(i=0;i<8;i++) { SCLK=0; IO=add&0x01; add>>=1; SCLK=1; } for(i=0;i<8;i++) { SCLK=0; IO=com&0x01; com>>=1; SCLK=1; } SCLK=0; CE=0; } uchar read_data_1302(uchar add) { uchar Data,i; CE=1; for(i=0;i<8;i++) { SCLK=0; IO=add&0x01; add>>=1; SCLK=1; } for(i=0;i<8;i++) { SCLK=0; Data>>=1; if(IO==1)Data|=0x80; SCLK=1; _nop_(); } SCLK=0; CE=0; return Data; } uchar changenum(uchar num) { uchar TH,TL,new_num; TH=num&0xF0; TH>>=4; TH*=10; TL=num&0x0F; new_num=TH+TL; return new_num; } void main() { init(); while(1) { Temperature_conversion(); //温度转换 LSB=read_scratchpad(); //读取LSB位数据 MSB=read_scratchpad(); //读取MSB位数据 TH=read_scratchpad(); //读取TH Register数据 TL=read_scratchpad(); //读取TL Register数据 CR=read_scratchpad(); //读取Configuration Register数据 TA=MSB|0x07; //按位与,从MSB位判断温度正负 checkMSB(TA); //判断温度正负 write_com_1602(0x80+0x49); display_temp1(TN); display_dot(); display_temp2(TD); display_cent(); write_com_1602(0x80); YY=read_data_1302(0x8D); YY=changenum(YY); display_temp3(YY); display_minus(); MM=read_data_1302(0x89); MM=changenum(MM); display_temp3(MM); display_minus(); DD=read_data_1302(0x87); DD=changenum(DD); display_temp3(DD); write_data_1602(0x20); write_data_1602(0x20); write_data_1602(0x20); HH=read_data_1302(0x85); HH=changenum(HH); display_temp3(HH); display_minus(); MIN=read_data_1302(0x83); MIN=changenum(MIN); display_temp3(MIN); WEEK=read_data_1302(0x8B)-1; write_com_1602(0x80+0x45); write_data_1602(digit[WEEK]); //SEC=read_data_1302(0x81); //SEC=changenum(SEC); //display_temp3(SEC); } } 程序运行如下: 基于51单片机的时间温度报警系统 |
|
相关推荐
1 个讨论
|
|
想请教下楼主有原理图吗
|
|
|
|
|
|
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-1 08:42 , Processed in 0.554018 second(s), Total 45, Slave 34 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号