1、51单片机带闹钟可调时间的电子时钟程序设计 硬件部分 基于51单片机、ds1302时钟芯片、ds18b20温度芯片、以及1602液晶显示的 实时时间和实时温度显示。同时可通过按键 设置 年、月、日、时、分、星期。并且可以设置闹钟 当闹钟时间到时 蜂鸣器持续发出 滴声 同时led灯不停闪烁 且在一分钟内没有按指定停止按键 闹钟将自动停止 。 软件部分 如 果 网 页 上 复 制 的 代 码 不 能 编 译 可 以 从 这 里 下 载 keil 工程: http:/ #include #define uchar unsigned char #define uint unsigned int sbi
2、t spk=P17; sbit led=P15; sbit DQ=P10; sbit RS=P24; sbit RW=P25; sbit EN=P26; sbit key1=P20; sbit key2=P21; sbit key3=P22; sbit key4=P23; sbit IO=P36; sbit RST=P37; sbit SCLK=P35; uchar code table=0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39; int nian,xing,yue,ri,shi,fen,miao; uchar num,temp,c,d
3、,time7,a,b,aa,bb,ns,ng,ys,yg,rs,rg,ss,sg,fs,fg,ms,mg,flag; /*1602*/ void delay(int z) int x,y; for(x=z;x0;x-) for(y=100;y0;y-); void write_com(uchar com) /写命令 RS=0; P0=com; delay(5); EN=1; delay(5); EN=0; void write_data(uchar date) /写数据 RS=1; P0=date; delay(5); EN=1; delay(5); EN=0; void init() /初始
4、化 RW=0; EN=0; write_com(0x38); /显示模式设置 write_com(0x0c); /开显示 不显示光标 不闪 write_com(0x06); /写一个字符 地址指针 光标 加一 整屏不移动 write_com(0x01); /显示清零 write_com(0x80+0x04); write_data(2); write_com(0x80+0x05); write_data(0); write_com(0x80+0x00); write_data(c); write_com(0x80+0x01); write_data(a); write_com(0x80+0x0
5、2); write_data(i); write_com(0x80+0x4e); write_data(0xdf); write_com(0x80+0x4f); write_data(C); write_com(0x80+0x4b); write_data(0x2e); /显示“。“ /*DS18B20*/ void delay1(unsigned int t) /延时函数 while(t-); void init1() /初始化 uchar n=0; DQ=1; /DQ复位 delay1(8); DQ=0; /主机将DQ拉低 delay1(80); /大于480us的延时 DQ=1; del
6、ay1(5); /延时1560us n=DQ; delay1(5); /若n=0初始成功 n=1初始失败(可设置返回值查看n是否为1) void write_byte(uchar dat) /写入一个字节 uint i; for(i=0;i=1; delay1(4); uchar read_byte() /读入一个字节 uint k=0; uchar value=0; for(k=0;k=1; DQ=1; if(DQ) value|=0x80; delay1(4); return value; uchar read_temp() /读取温度函数 uchar a=0,b=0; init1();
7、write_byte(0xcc); write_byte(0x44); delay1(200); init1(); write_byte(0xcc); write_byte(0xbe); a=read_byte(); b=read_byte(); c=b; d=a; b4; return b; /*1302*/ void wirte_byte1(uchar date) /写入一个字节 uchar i; for(i=8;i0;i-) IO=date SCLK=0; SCLK=1; date=date1; uchar read_byte1() /读一个字节 uchar dat,i; for(i=8
8、;i0;i-) dat=dat1; SCLK=0; if(IO) dat=dat|0x80; SCLK=1; return(dat); void write_ds1302(uchar add,uchar date) /将数据写入1302中 RST=0; SCLK=0; RST=1; wirte_byte1(add); wirte_byte1(date); RST=0; SCLK=1; uchar read_ds1302(uchar add) /读出1302中数据 uchar temp; RST=0; SCLK=0; RST=1; wirte_byte1(add); temp=read_byte
9、1(); RST=0; SCLK=0; return (temp); uchar huan_BCD(uint z) /将数据 转换成BCD uint a,b; a=z/10; b=z%10; a=a b=b a=24) shi=0; if(a=2) fen+; if(fen=60) fen=0; if(a=3) ri+; if(ri=32) ri=1; if(a=4) yue+; if(yue=12) yue=1; if(a=5) nian+; if(nian=99) nian=0; if(a=6) xing+; if(xing=8) xing=1; if(key3=0) /key3按键 可将
10、需设置的数 调小 if(a=1) shi-; if(shi=24) shi=0; if(b=2) fen+; if(fen=60) fen=0; if(key3=0) /key3按键 可将需设置的数 调小 if(b=1) shi-; if(shi0) shi=23; if(b=2) fen-; if(fen0) fen=59; aa=huan_BCD(shi); /将设置的时钟 赋值给aa bb=huan_BCD(fen); /将设置的分钟 赋值给bb if(b=3) /当按下key4 3次后 闹钟设置完成 b=0; void main() uint i,temp; init(); TMOD=
11、0x10; EA=1; TH1=(65536-51200)/256; TL1=(65536-51200)%256; ET1=1; while(1) temp=0x81; /读的初始地址 for(i=0;i7;i+) /分别把秒分时日月年星期数据读出分 7 次读好一次地址加 2“ temp+=2;“ timei=read_ds1302(temp); temp+=2; if(bb=time1 flag=1; /标志位设置为1 if(key3=0) /进入闹钟后 可由 key3 按下 停止中断 标志位置零 允许调时闹钟设置按键动作 停止闹铃 led=1; spk=1; flag=0; TR1=0;
12、if(flag!=1) /当进入闹钟中断后 调时与设置闹钟的按键 无效 naozhong(); keyscan(); xian_shi(); temp=read_temp(); write_com(0x80+0x49); write_data(tabletemp/10); /在液晶第二行第十位显示温度的十位 write_com(0x80+0x4a); write_data(tabletemp%10); /在液晶第二行第十一位显示温度的个位 write_com(0x80+0x4c); write_data(table(d /在液晶第二行第十三位显示温度的小数点后一位 write_com(0x80+0x4d); write_data(table(d /在液晶第二行第十四位显示温度的小数点后二位 void timer1() interrupt 3 /定时器 uint t; TH1=(65536-50000)/256; TL1=(65536-50000)%256; t+; spk=0; /蜂鸣器 发出 滴答 声 led=!led; /发光二极管 不停闪烁 delay1(10); if(t=1120) /约1分钟后 闹钟自动停止 标志位 led=1; spk=1; t=0; TR1=0; flag=0;