1、基于51单片机的温度上下限控制实时显示时间温度#includeSTC89C51RC.H#include#includeds18b20.h#includelcd1602.h#includeds1302.h#include2402.h uchar data datadis=0x00,0x00,0x00,0x00,0x00;uint temp=0;sbit K1=P30;sbit K2=P31;sbit K3=P32;sbit K4=P33;sbit K5=P37;sbit L1=P16;sbit L2=P17;sbit led=P27 ;sbit speaker=P10;uchar keynum=
2、1,flag,flag1,flag2,adder,q;uint k,count,th,tl;uchar th1=8;uchar th2=5;uchar th3=2;uchar th4=0;uchar tab,w;void delay(uchar z) uchar x,y; for(x=z;x0;x-) for(y=110;y0;y-);uchar key4() if(K4=0) delay(5); if(K4=0) while(!K4); keynum+; if(keynum=5)keynum=1; return keynum;void key_lcd() if(flag1=1&k=3) if
3、(K3=0) delay(5); if(K3=0) while(!K3); flag+; if(flag=5)flag=1; switch(flag) case 1: if(K1=0) delay(5); if(K1=0) th1+; while(!K1); if(th1=10)th1=0; if(K2=0) delay(5); if(K2=0) th1-; while(!K2); if(th1=-1)th1=9; write_cmd(0xc3); write_dat(th1+0x30); break; case 2: if(K1=0) delay(5); if(K1=0) th2+; whi
4、le(!K1); if(th2=10)th2=0; if(K2=0) delay(5); if(K2=0) th2-; while(!K2); if(th2=-1)th2=9; write_cmd(0xc4); write_dat(th2+0x30); break; case 3: if(K1=0) delay(5); if(K1=0) th3+; while(!K1); if(th3=10)th3=0; if(K2=0) delay(5); if(K2=0) th3-; while(!K2); if(th3=-1)th3=9; write_cmd(0xcb); write_dat(th3+0
5、x30); break; case 4: if(K1=0) delay(5); if(K1=0) th4+; while(!K1); if(th4=10)th4=0; if(K2=0) delay(5); if(K2=0) th4-; while(!K2); if(th4=-1)th4=9; write_cmd(0xcc); write_dat(th4+0x30); break; default:break; else flag1=0; th=th1*10+th2; /获取设置温度的高位 tl=th3*10+th4; /获取设置温度的低位void alarm_speaker() /报警系统与当
6、前温度进行比较并处理 if(temp(th*10) speaker=speaker; L1=1; L2=0; adder+; tab=temp/10; write_add(adder,tab); else if(temp(tl*10) speaker=1; L1=1; L2=1; void main() systemtime realtime; led=0; init_18b20(); init_lcd(); init_2402(); speaker=1; while(1) k=key4(); get_ds1302(&realtime);/取时间 temp=read_temp(); /取温度
7、delay(200); /延时 保持数据稳定 避免数据刷新 switch(k) case 1: /菜单一,显示时间 led=0; write_cmd(0x80); print( Time: ); print(realtime.TimeString); write_cmd(0xc0); print( Date: ); print(realtime.DateString); break; case 2: /菜单二,显示温度 write_cmd(0x80); print( DS18B20 is OK ); write_cmd(0xc0); print(NOW TEMP: . C ); if(flag
8、t=1)datadis0=0x2d; else datadis0=temp/1000+0x30; datadis1=temp/100%10+0x30; datadis2=temp/10%10+0x30; datadis3=0x2e; datadis4=temp%10+0x30; write_cmd(0xca); print(datadis); break; case 3: /菜单三,显示温度设置值 write_cmd(0x80); print( change temp: ); write_cmd(0xc0); print(TH= TL= ); write_cmd(0xc3); write_da
9、t(th1+0x30); write_cmd(0xc4); write_dat(th2+0x30); write_cmd(0xc5); write_dat(0xdf); /摄氏度远点 write_cmd(0xc6); write_dat(0x43); write_cmd(0xcb); write_dat(th3+0x30); write_cmd(0xcc); write_dat(th4+0x30); write_cmd(0xcd); /摄氏度符号 write_dat(0xdf); write_cmd(0xce); write_dat(0x43); flag1=1; break; case 4:
10、 /菜单四,记录报警温度 write_cmd(0x80); print( ALARM TEMP ); write_cmd(0xc0); print( RECORD: ); write_cmd(0xcb); write_dat(0xdf); write_cmd(0xcc); write_dat(0x43); flag2=1; break; default:break; key_lcd(); /菜单三中温度设置的按键扫描 alarm_speaker(); /报警系统通过2402存储超出的温度,并记录 if(K5=0) /按下K5,就显示当前报警的温度 delay(5); if(K5=0) whil
11、e(!K5); q=read_add(adder); ; if(flag2=1&k=4) write_cmd(0xc9); write_dat(q/10%10+0x30); write_cmd(0xca); write_dat(q%10+0x30); led=1; #ifndef _lcd1602_h_#define _lcd1602_h_#include#define uchar unsigned char #define uint unsigned int#define LCD_IO P0sbit LCD_RS = P24;sbit LCD_RW = P25;sbit LCD_EN = P
12、26;void delay11(uint z) uint x, y; for(x = z; x 0; x-) for(y = 10; y 0; y-);/*测忙信号bit lcd_busy() return (bit)(lcdrc&0x80);/*写数据*/void write_cmd(uchar cmd) LCD_RW=0;LCD_RS = 0; LCD_EN = 0; / LCD_RS和R/W同时为低电平时,可以写入指令. LCD_IO = cmd; delay11(5); /下面用EN输入一个高脉冲. LCD_EN = 1; delay11(5); LCD_EN = 0;/*写命令*/v
13、oid write_dat(uchar dat) LCD_RS = 1; LCD_EN = 0;LCD_RW=0; / LCD_RS为高,LCD_RW为低时,可以写入数据. LCD_IO = dat; delay11(5); /下面用EN输入一个高脉冲. LCD_EN = 1; delay11(5); LCD_EN = 0;/*LCD初始化*/void init_lcd() LCD_EN = 0; write_cmd(0x38); write_cmd(0x0c); write_cmd(0x06); write_cmd(0x01); write_cmd(0x80);void print(ucha
14、r *str) while(*str!=0) write_dat(*str); str+; #endif#ifndef _ds18b20_h_#define _ds18b20_h_#define uchar unsigned char#define uint unsigned int/晶振22MHZ/延时/sbit DQ=P13;bit flagt;void delay_18b20(uint i) while(i-);/*初始化程序*/ void init_18b20() uchar x=0; DQ=1; delay_18b20(8); DQ=0; delay_18b20(80); DQ=1;
15、 delay_18b20(15); x=DQ; delay_18b20(15); /* 读一个字节*/uchar read_byte() uchar i=0; uchar dat=0; for(i=0;i=1; DQ=1; if(DQ)dat|=0x80; delay_18b20(5); return dat;/*写一个字节*/void write_byte(uchar dat) uchar i=0; for(i=0;i=1; /*温度转换并读取温度*/uint read_temp() uchar a=0; uchar b=0; uint t; init_18b20(); write_byte
16、(0xcc); /跳过读序号列号的操作 write_byte(0x44); / 启动温度转换 delay_18b20(100); init_18b20(); write_byte(0xcc); /跳过读序号列号的操作 write_byte(0xbe); /读取温度寄存器等(共可读9个寄存器) 前两个就是温度 a=read_byte(); /读第八位 b=read_byte(); /读高八位 if(b&0x80) /高八位的最高位于是否为1,若为1,则为负温度,若为0,则是0-128; flagt=1; a=a; b=b; else flagt=0; t=(b*256+a)*5; /也可以写成
17、t=(b*256+a)*0.625 ;return t; return (t3); /右移三位相当于5/8=0.625 返回温度有4位,千、百、十、个,转化后有一位小数位,没有千位#endif#ifndef _2402_h_#define _2402_h_#define uchar unsigned char#define uint unsigned intsbit sda=P12;sbit scl=P11;/sbit sda=P16;/sbit scl=P15;void nop() ; ; void start() /功能:启动I2C 总线,即发送I2C 起始条件。 sda=1; nop()
18、; scl=1; nop(); sda=0; nop();void stop() /功能:结束I2C 总线,即发送I2C 结束条件。 sda=0; nop(); scl=1; nop(); sda=1; nop(); void respons() /功能:主控器进行应答信号,(可以是应答或非应答信号) uchar i; scl=1; nop(); while(sda=1)&(i250)i+; scl=0; nop();void write_byte_2402(uchar dat) /功能:将数据dat 发送出去,可以是地址,也可以是数据,发完后等待应答 uchar i,temp; temp=d
19、at; scl=0; nop(); for(i=0;i8;i+) temp=temp1; scl=0; /*置时钟线为低,准备接收数据位*/ nop(); sda=CY; nop(); scl=1; /*置时钟线为高,通知被控器开始接收数据位*/ nop(); scl=0; nop(); sda=1; /SDA数据线空闲 nop();uchar read_byte_2402() / 功能:用来接收从器件传来的数据,并判断总线错误(不发应答信号),发完后请用应答函数 uchar i,k; scl=0; /*置时钟线为低,准备接收数据位*/ nop(); for(i=0;i8;i+) scl=1;
20、 /*置时钟线为高使数据线上数据有效,保持数据的稳定*/ nop(); k=(k1)|sda; scl=0; nop(); return k;void write_add(uchar add,uchar dat) start(); write_byte_2402(0xa0); respons(); write_byte_2402(add); respons(); write_byte_2402(dat); respons(); stop();uchar read_add(uchar add) uchar k; start(); write_byte_2402(0xa0); respons();
21、 write_byte_2402(add); respons(); start(); write_byte_2402(0xa1); respons(); k=read_byte_2402(); stop(); return k;void init_2402() uint i; sda=1; nop(); scl=1; nop(); for(i=0;i0;i-) T_IO=ACC0; T_CLK=1; T_CLK=0; ACC=ACC1; / T_IO=0;/*从DS1302中读出1BYTE数据*/uchar readB() uchar i; for(i=8;i0;i-) ACC=ACC1; A
22、CC7=T_IO; T_CLK=1; T_CLK=0; return(ACC);/*单字节读,向DS1302某地址中读出数据, 先写地址后写命令/数据*/uchar r_ds1302(uchar ucaddr) uchar ucda; T_RST=0; T_CLK=0; T_RST=1; writeB(ucaddr); ucda=readB(); T_CLK=1; T_RST=0; return(ucda);/* 读取 DS1302当前时间, 格式为: 秒,分,时,日,月,星期,年*/void get_ds1302(systemtime *Time) uchar readtime; readt
23、ime = r_ds1302(0x81); /秒寄存器读操作0x81 Time-second = (readtime&0x70)4)*10 + (readtime&0x0f); /十位+个位 readtime = r_ds1302(0x83); /分寄存器读操作0x83 Time-minute = (readtime&0x70)4)*10 + (readtime&0x0f); readtime = r_ds1302(0x85); Time-hour = (readtime&0x70)4)*10 + (readtime&0x0f); readtime = r_ds1302(0x87); Time-day = (readtime&0x7
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1