这是我做的多功能电子时钟,基于ds1302和ds18b20的电子时钟,附带温度计功能,还有基于内部定时器的秒表功能。当温度超过某一设定值的时候,发生报警,并且启动直流电机,实现温控。
电路原理图如下:
程序源码:
代码:
- #include <reg52.h>
- #include <intrins.h>
- #define uint unsigned int
- #define uchar unsigned char
- uchar code table[]="MONTUEWEDTHUFRISATSUNMAX TEMPMIN TEMPALARM! ";
- int i;//存放温度的值的变量
- char settempmax,settempmin,n;
- uchar temp,sumup,count,hundredms,L,M,C_qian,C_bai,C_shi,C_ge,tempmax;
- uchar shi=3,fen=3,miao=3,nian=3,yue=3,week=3,ri=3,s1num=0,s2num,s3num,s4num,num,fiftyms;
- float f_temp;
- uint Int_temp;
- sbit du=P2^6;
- sbit we=P2^7;
- sbit di=P2^3;
- sbit lcdrs=P3^5;
- sbit lcdwr=P3^6;
- sbit lcden=P3^4;
- sbit s1=P3^0;
- sbit s2=P3^1;
- sbit s3=P3^2;
- sbit s4=P3^3;
- sbit rd=P3^7;
- sbit TSCLK=P1^0;
- sbit TIO=P1^1;
- sbit TRST=P1^2;
- sbit ds=P2^2;
- void delay(uint xms)
- {
- uint i,j;
- for(i=xms;i>0;i--)
- for(j=110;j>0;j--);
- }
- void delay_us(uchar us)
- {
- while(us--);
- }
- void write_com(uchar com)
- {
- lcdrs=0;
- lcden=0;
- P0=com;
- delay(5);
- lcden=1;
- delay(5);
- lcden=0;
- }
- void write_date(uchar date)
- {
- lcdrs=1;
- lcden=0;
- P0=date;
- delay(5);
- lcden=1;
- delay(5);
- lcden=0;
- }
- void lcdinit()
- {
- du=0;
- we=0;
- lcdwr=0;
- lcden=0;
- write_com(0x38);
- write_com(0x0c);
- write_com(0x06);
- write_com(0x01);
- }
- void write_sfm(uchar add,uchar date)
- {
- uchar shi,ge;
- shi=date/10;
- ge=date%10;
- write_com(0x80+0x40+add);
- write_date(0x30+shi);
- write_date(0x30+ge);
- }
- void write_nyr(uchar add,uchar date)
- {
- uchar shi,ge;
- shi=date/10;
- ge=date%10;
- write_com(0x80+add);
- write_date(0x30+shi);
- write_date(0x30+ge);
- }
- void write_miaobiao(uchar add,uchar date)
- {
- uchar shi,ge;
- shi=date/10;
- ge=date%10;
- write_com(0x80+0x40+add);
- write_date(0x30+shi);
- write_date(0x30+ge);
- }
- void write_wendu(uchar add,uchar date)
- {
- write_com(0x80+add);
- write_date(0x30+date);
- }
- void wendufuhaoinit()
- {
- write_com(0x80+0x40+7);//写一个字母T
- write_date(0x54);
- write_com(0x80+0x40+8);//写一个等号=
- write_date(0x3d);
- write_com(0x80+0x40+11);//写小数点
- write_date(0x2e);
- write_com(0x80+0x40+14);//设置摄氏度符号
- write_date(0xdf);
- write_com(0x80+0x40+15);
- write_date(0x43);
- }
- void wendufuhao2init()
- {
- write_com(0x80+7);//写一个字母T
- write_date(0x54);
- write_com(0x80+8);//写一个等号=
- write_date(0x3d);
- write_com(0x80+11);//写小数点
- write_date(0x2e);
- write_com(0x80+14);//设置摄氏度符号
- write_date(0xdf);
- write_com(0x80+15);
- write_date(0x43);
- }
- void write_ds1302(uchar cmd,uchar dat)
- {
- uchar i;
- TRST=0;
- TSCLK=0;
- TRST=1;
- for(i=0;i<8;i++)
- {
- TSCLK=0;
- TIO=cmd&0x01;
- TSCLK=1;
- cmd>>=1;
- }
- for(i=0;i<8;i++)
- {
- TSCLK=0;
- TIO=dat&0x01;
- TSCLK=1;
- dat>>=1;
- }
- TRST=0;
- }
- uchar read_ds1302(uchar cmd)
- {
- uchar i,dat;
- TRST=0;
- TSCLK=0;
- TRST=1;
- for(i=0;i<8;i++)
- {
- TSCLK=0;
- TIO=cmd&0x01;
- TSCLK=1;
- cmd>>=1;
- }
- for(i=0;i<8;i++)
- {
- TSCLK=0;
- dat>>=1;
- if(TIO)
- dat=dat|0x80;
- TSCLK=1;
- }
- TRST=0;
- return dat;
- }
- //数据转BCD码
- uchar dat_chg_bcd(uchar dat)
- {
- uchar dat1,dat2;
- dat1=dat/10;
- dat2=dat%10;
- dat2=dat2+dat1*16;
- return dat2;
- }
- //bcd码转数据
- uchar bcd_chg_dat(uchar dat)
- {
- uchar dat1,dat2;
- dat1=dat/16;
- dat2=dat%16;
- dat2=dat2+dat1*10;
- return dat2;
- }
- void ds1302_init()
- {
- write_ds1302(0x8e,0);
- write_ds1302(0x80,dat_chg_bcd(miao));
- write_ds1302(0x82,dat_chg_bcd(fen));
- write_ds1302(0x84,dat_chg_bcd(shi));
- write_ds1302(0x86,dat_chg_bcd(ri));
- write_ds1302(0x88,dat_chg_bcd(yue));
- write_ds1302(0x8a,dat_chg_bcd(week));
- write_ds1302(0x8c,dat_chg_bcd(nian));
- write_ds1302(0x8e,0x80);
- }
- bit ds18b20_init()
- {
- bit i;
- ds=1;
- _nop_();
- ds=0;
- delay_us(75);
- ds=1;
- delay_us(4);
- i=ds;
- delay_us(20);
- ds=1;
- _nop_();
- return (i);
- }
- void write_ds(uchar dat)
- {
- uchar i;
- for(i=0;i<8;i++)
- {
- ds=0;
- _nop_();
- ds=dat&0x01;
- delay_us(10);
- ds=1;
- _nop_();
- dat>>=1;
- }
- }
- uchar read_ds()
- {
- uchar i,j,dat;
- for(i=0;i<8;i++)
- {
- ds=0;
- _nop_();
- ds=1;
- _nop_();
- j=ds;
- delay_us(10);
- ds=1;
- _nop_();
- dat=(j<<=7)|dat>>1;
- }
- return (dat);
- }
- void keyscan()
- {
- rd=0;
- if(s1==0)
- {
- delay(5);
- if(s1==0)
- {
- while(!s1);
- s1num++;
- di=0;
- delay(800);
- di=1;
- while(s1num==1)
- {
- if(s1==0)
- {
- delay(5);
- if(s1==0)
- {
- s1num++;
- }
- }
- if(s2==0)
- {
- delay(5);
- if(s2==0)
- {
- di=0;
- while(!s2);
- di=1;
- s2num++;
- if(s2num==1)
- {
- write_com(0x80+0x40+10);//把指针定到秒的位置
- write_com(0x0f);//开光标闪烁(开一次就行了)
- }
- if(s2num==2)
- {
- write_com(0x80+0x40+7);
- }
- if(s2num==3)
- {
- write_com(0x80+0x40+4);
- }
- if(s2num==4)
- {
- write_com(0x80+13);
- }
- if(s2num==5)
- {
- write_com(0x80+11);
- }
- if(s2num==6)
- {
- write_com(0x80+8);
- }
- if(s2num==7)
- {
- write_com(0x80+5);
- }
- if(s2num==8)
- {
- write_com(0x80+0x40+10);
- s2num=0;
- }
- }
- }
- if(s3==0)
- {
- delay(5);
- if(s3==0)
- {
- di=0;
- while(!s3);
- di=1;
- if(s2num==1)
- {
- miao++;
- if(miao==60)
- miao=0;
- write_sfm(9,miao);
- }
- if(s2num==2)
- {
- fen++;
- if(fen==60)
- fen=0;
- write_sfm(6,fen);
- }
- if(s2num==3)
- {
- shi++;
- if(shi==24)
- shi=0;
- write_sfm(3,shi);
- }
- if(s2num==4)
- {
- week++;
- if(week==8)
- week=1;
- write_nyr(13,week);
- }
- if(s2num==5)
- {
- ri++;
- if(ri==32)
- ri=1;
- write_nyr(10,ri);
- }
- if(s2num==6)
- {
- yue++;
- if(yue==13)
- yue=1;
- write_nyr(7,yue);
- }
- if(s2num==7)
- {
- nian++;
- if(nian==99)
- nian=0;
- write_nyr(4,nian);
- }
- }
- }
- if(s4==0)
- {
- delay(5);
- if(s4==0)
- {
- di=0;
- while(!s4);
- di=1;
- if(s2num==1)
- {
- miao--;
- if(miao==0)
- miao=59;
- write_sfm(9,miao);
- }
- if(s2num==2)
- {
- fen--;
- if(fen==0)
- fen=59;
- write_sfm(6,fen);
- }
- if(s2num==3)
- {
- shi--;
- if(shi==0)
- shi=23;
- write_sfm(3,shi);
- }
- if(s2num==4)
- {
- week--;
- if(week==0)
- week=7;
- write_nyr(13,week);
- }
- if(s2num==5)
- {
- ri--;
- if(ri==1)
- ri=31;
- write_nyr(10,ri);
- }
- if(s2num==6)
- {
- yue--;
- if(yue==1)
- yue=12;
- write_nyr(7,yue);
- }
- if(s2num==7)
- {
- nian--;
- if(nian==0)
- nian=99;
- write_nyr(4,nian);
- }
- }
- }
- }
- write_ds1302(0x8e,0);
- write_ds1302(0x80,dat_chg_bcd(miao));
- write_ds1302(0x82,dat_chg_bcd(fen));
- write_ds1302(0x84,dat_chg_bcd(shi));
- write_ds1302(0x8a,dat_chg_bcd(week));
- write_ds1302(0x86,dat_chg_bcd(ri));
- write_ds1302(0x88,dat_chg_bcd(yue));
- write_ds1302(0x8c,dat_chg_bcd(nian));
- write_ds1302(0x8e,0x80);
- s1num=0;
- s2num=0;
- write_com(0x0c);//清除光标闪烁
- }
- }
- if(s4==0)
- {
- delay(5);
- if(s4==0)
- {
- while(!s4);
- s4num++;
- write_com(0x01);
- write_com(0x80);//写字母MAXTEMP
- for(i=21;i<29;i++)
- write_date(table[i]);
- write_com(0x80+8);//写等号
- write_date(0x3d);
- write_nyr(9,settempmax);//写温度的初始状态
- write_com(0x80+11);//写摄氏度符号
- write_date(0xdf);
- write_com(0x80+12);
- write_date(0x43);
- write_com(0x80+0x40);//写字母MINTEMP
- for(i=29;i<37;i++)
- write_date(table[i]);
- write_com(0x80+0x40+8);//写等号
- write_date(0x3d);
- write_sfm(9,settempmin);
- write_com(0x80+0x40+12);//写摄氏度符号
- write_date(0xdf);
- write_com(0x80+0x40+13);
- write_date(0x43);
- while(s4num==1)
- {
- if(s4==0)
- {
- delay(5);
- if(s4==0)
- {
- while(!s4);
- s4num++;
- }
- }
- if(s1==0)
- {
- delay(5);
- if(s1==0)
- {
- while(!s1);
- settempmax++;
- if(settempmax==38)
- settempmax=25;
- write_nyr(9,settempmax);
- }
- }
- if(s2==0)
- {
- delay(5);
- if(s2==0)
- {
- while(!s2);
- settempmin--;
- if(settempmin==-1)
- settempmin=25;
- write_sfm(9,settempmin);
- }
- }
- }
- write_com(0x01);
- s4num=0;
- }
- }
- else
- {
- if(s2==0)
- {
- delay(5);
- if(s2==0)
- {
- while(!s2);
- s2num++;
- write_com(0x01);
- di=0;
- delay(100);
- di=1;
- delay(100);
- di=0;
- delay(100);
- di=1;
- TR0=1;
- while(s2num==1)
- {
- if(num==20)
- {
- num=0;
- fiftyms++;
- if(fiftyms==20)
- {
- fiftyms=0;
- miao++;
- if(miao==60)
- {
- miao=0;
- fen++;
- write_miaobiao(5,fen);
- }
- write_miaobiao(11,miao);
- }
- write_miaobiao(14,fiftyms);
- }
- if(s2==0)
- {
- delay(5);
- if(s2==0)
- {
- while(!s2);
- s2num++;
- }
- }
- if(s3==0)
- {
- delay(5);
- if(s3==0)
- {
- di=0;
- while(!s3);
- di=1;
- s3num++;
- if(s3num==1)
- {
- write_nyr(0,miao);
- write_nyr(3,fiftyms);
- }
- if(s3num==2)
- {
- write_nyr(11,miao);
- write_nyr(14,fiftyms);
- }
- if(s3num==3)
- {
- write_sfm(0,miao);
- write_sfm(3,fiftyms);
- s3num=0;
- }
- }
- }
- }
- s2num=0;
- TR0=0;
- write_com(0x01);
- num=0;
- fiftyms=0;
- miao=0;
- fen=0;
- }
- }
- if(s3==0)
- {
- delay(5);
- if(s3==0)
- {
- while(!s3);
- s3num++;
- write_com(0x01);
- wendufuhaoinit();
- while(s3num==1)
- {
- ds18b20_init();
- write_ds(0xcc);
- write_ds(0x44);
- ds18b20_init();
- write_ds(0xcc);
- write_ds(0xbe);
- L=read_ds();
- M=read_ds();
- i=0;
- i=M;
- i<<=8;
- i|=L;
- f_temp=i*0.0625;
- if(f_temp>settempmax) //如果超过报警温度,则蜂鸣器闹响,
- { //而且闪烁alarm提醒词
- di=0;
- write_com(0x80+0x40); //写入警报提醒单词,又能有延时效果
- for(n=37;n<43;n++)
- {
- write_date(table[n]);
- }
- }
- di=1;
- if(f_temp<settempmin)
- {
- di=0;
- write_com(0x80+0x40);
- for(n=37;n<43;n++)
- {
- write_date(table[n]);
- }
- }
- di=1;
- delay(100);
- write_com(0x80+0x40);//写空格清除提醒词达到闪烁效果
- for(n=43;n<49;n++)
- {
- write_date(table[n]);
- }
- Int_temp=i*0.0625*100+0.5;
- C_qian=Int_temp/1000;
- C_bai=Int_temp%1000/100;
- C_shi=Int_temp%100/10;
- C_ge =Int_temp%10;
- write_wendu(0x40+9,C_qian);
- write_wendu(0x40+10,C_bai);
- write_wendu(0x40+12,C_shi);
- write_wendu(0x40+13,C_ge);
- if(s3==0)
- {
- delay(5);
- if(s3==0)
- {
- while(!s3);
- s3num++;
- }
- }
- if(s4==0)
- {
- delay(5);
- if(s4==0)
- {
- di=0;
- while(!s4);
- di=1;
- s4num++;
- if(s4num==1)
- {
- miao=bcd_chg_dat(read_ds1302(0x81));
- fen=bcd_chg_dat(read_ds1302(0x83));
- write_nyr(3,miao);
- write_nyr(0,fen);
- wendufuhao2init();
- write_wendu(9,C_qian);
- write_wendu(10,C_bai);
- write_wendu(12,C_shi);
- write_wendu(13,C_ge);
- s4num=0;
- }
- }
- }
- }
- s3num=0;
- write_com(0x01);
- }
- }
- }
- }
- void t0_init()
- {
- TMOD=0x02;
- TH0=6;
- TL0=6;
- EA=1;
- ET0=1;
- }
- void main()
- {
- uchar miao,fen,shi,nian,yue,ri,week;
- settempmax=37;
- settempmin=0;
- lcdinit();
- ds1302_init();
- t0_init();
- while(1)
- {
- keyscan();
- write_ds1302(0x8e,0);//关闭写保护
- miao=bcd_chg_dat(read_ds1302(0x81));
- fen=bcd_chg_dat(read_ds1302(0x83));
- shi=bcd_chg_dat(read_ds1302(0x85));
- ri=bcd_chg_dat(read_ds1302(0x87));
- yue=bcd_chg_dat(read_ds1302(0x89));
- week=bcd_chg_dat(read_ds1302(0x8b));
- nian=bcd_chg_dat(read_ds1302(0x8d));
- write_ds1302(0x8e,0x80); //打开写保护
- if(week==1)
- {
- write_com(0x80+13);
- for(num=0;num<3;num++)
- write_date(table[num]);
- }
- if(week==2)
- {
- write_com(0x80+13);
- for(num=3;num<6;num++)
- write_date(table[num]);
- }
- if(week==3)
- {
- write_com(0x80+13);
- for(num=6;num<9;num++)
- write_date(table[num]);
- }
- if(week==4)
- {
- write_com(0x80+13);
- for(num=9;num<12;num++)
- write_date(table[num]);
- }
- if(week==5)
- {
- write_com(0x80+13);
- for(num=12;num<15;num++)
- write_date(table[num]);
- }
- if(week==6)
- {
- write_com(0x80+13);
- for(num=15;num<18;num++)
- write_date(table[num]);
- }
- if(week==7)
- {
- write_com(0x80+13);
- for(num=18;num<21;num++)
- write_date(table[num]);
- }
-
- write_sfm(9,miao);
- write_sfm(6,fen);
- write_sfm(3,shi);
- write_nyr(10,ri);
- write_nyr(7,yue);
- write_nyr(4,nian);
- write_nyr(2,20);
- }
- }
- void t0_time() interrupt 1
- {
- num++;
- }