带闹钟的万年历程序测试无误,希望能帮到大家
单片机源程序如下:
- #include "12864.h"
- #include "DS1302.h"
- #include "KEY.h"
- #include "DS18B20.h"
- #include<intrins.h>
- sfr CLK_DIV=0x97;
- uchar clock_page=0; //闹钟
- //uchar flag=0;
- uchar keynum;
- char yearH=20,year,month,date,day,hour=0,min=0,sec=0; //时间变量
- //char cursor_xy=0; //光标位置
- uchar page=0; //page菜单页面
- code char* Weekday[8]={" ","一","二","三","四","五","六","日"};
- code uchar cursor[6][2]={{0,16},{4,16},{0,32},{4,32},{0,48},{4,48}}; //光标位置
- extern code uchar DS1302_Addr[7];
- uchar M_num=59,S_num=59;
- uchar counter=1; //定时器计数
- struct TIME
- {
- char x;
- char y;
- char num;
- char max;
- char min;
- };
- struct TIME Time[10]=
- {
- {1,2,0,99,0}, //年
- {3,2,0,12,1}, //月
- {5,2,0,31,1}, //日
- {1,3,0,23,0}, //时
- {2,3,0,59,0}, //分
- {4,3,0,59,0}, //秒
- {4,4,0,7,1}, //星期
- {1,2,0,23,0}, //闹钟小时
- {3,2,0,59,0}, //闹钟分钟
- {3,3,0,1,0} //闹钟标志
- };
- uchar Clock_num_hour[3]={0,0,0}; //三个闹钟小时
- uchar Clock_num_min[3]={0,0,0}; //三个闹钟分钟
- uchar Clock_flag[3]={0,0,0}; //三个闹钟使能标志
- void Timer(void)
- {
- uint temp; //温度
- while(DS18B20_Init()) //DS18B20初始化
- {
- LCD12864_datas(3,2,"未插入");
- LCD12864_datas(2,3,"温度模块");
- LCD12864_WriteCom(0x01); //12864清屏(DDRAM)
- }
- LCD12864_datas(2,1,"年");
- LCD12864_datas(4,1,"月");
- LCD12864_datas(6,1,"日");
- LCD12864_datas(2,4,"星期");
- while(1)
- {
- if(Clock_flag[0]==1||Clock_flag[1]==1||Clock_flag[2]==1) LCD12864_DrawPic1616(0,48,0);
- else LCD12864_DrawPic1616(0,48,1); //闹钟标志
- hour=DS1302_ReadData(HOUR);
- min=DS1302_ReadData(MIN);
- sec=DS1302_ReadData(SEC); //读取时间
-
- LCD12864_Num3216(0,16,hour>>4);
- LCD12864_Num3216(1,16,hour&0x0f); //小时
- LCD12864_Num3216(2,16,10); //冒号
-
- LCD12864_Num3216(3,16,min>>4);
- LCD12864_Num3216(4,16,min&0x0f); //分钟
- LCD12864_Num3216(5,16,10); //冒号
-
- LCD12864_Num3216(6,16,sec>>4);
- LCD12864_Num3216(7,16,sec&0x0f); //秒针
-
- year=DS1302_ReadData(YEAR);
- month=DS1302_ReadData(MONTH);
- date=DS1302_ReadData(DATE); //读取年月日
-
- LCD12864_SetXY(0,1);
- LCD12864_WriteData(yearH/10+'0');
- LCD12864_WriteData(yearH%10+'0');
- LCD12864_WriteData('0'+(year>>4));
- LCD12864_WriteData('0'+(year&0x0f)); //年份
-
- LCD12864_SetXY(3,1);
- LCD12864_WriteData('0'+(month>>4));
- LCD12864_WriteData('0'+(month&0x0f)); //月份
-
- LCD12864_SetXY(5,1);
- LCD12864_WriteData('0'+(date>>4));
- LCD12864_WriteData('0'+(date&0x0f)); //日期
-
- LCD12864_datas(4,4,Weekday[DS1302_ReadData(DAY)]); //星期
-
- temp=DS18B20_ReadTemp(); //读取温度值
- LCD12864_SetXY(6,4);
- LCD12864_WriteData('0'+(temp%10000/1000));
- LCD12864_WriteData('0'+(temp%1000/100));
- // LCD12864_WriteData('C');
- LCD12864_DrawPic1616(7,48,2); //温度符号
- keynum=Key_Scan();
- if(keynum==13) {page=4;break;} //当按键按下键值为13时,打开菜单
- LCD12864_Delay1ms(500);
- }
- }
- void Cursor(uchar n)
- {
- switch(n)
- {
- case 0:LCD12864_Reverse(1, 0,0);LCD12864_Reverse(2, 0,0);LCD12864_Reverse(3, 0,0);LCD12864_Reverse(4, 0,0);LCD12864_Reverse(5, 0,0);break;
- case 1:LCD12864_Reverse(1,16,0);LCD12864_Reverse(2,16,0);LCD12864_Reverse(3,16,0);LCD12864_Reverse(4,16,0);LCD12864_Reverse(5,16,0);break;
- case 2:LCD12864_Reverse(1,32,0);LCD12864_Reverse(2,32,0);LCD12864_Reverse(3,32,0);LCD12864_Reverse(4,32,0);LCD12864_Reverse(5,32,0);break;
- case 3:LCD12864_Reverse(1,48,0);LCD12864_Reverse(2,48,0);LCD12864_Reverse(3,48,0);LCD12864_Reverse(4,48,0);LCD12864_Reverse(5,48,0);break;
- default:break;
- }
- }
- void meun(void) //菜单界面
- {
- char n=0,late=7;
-
- LCD12864_datas(0,1," 1.电子时钟");
- LCD12864_datas(0,2," 2.调整时间");
- LCD12864_datas(0,3," 3.设置闹钟");
- LCD12864_datas(0,4," 4.倒计时器");
- Cursor(0); //初始光标位置
- while(1)
- {
- keynum=Key_Scan();
- late=n;
- if(keynum==13) {page=n;break;} //确认键
- else if(keynum>=1&&keynum<=4) n=keynum-1;
- else if(keynum==14) n++;
- else if(keynum==15) n--;
- if(n>3)n=0;if(n<0)n=3;
- if(n!=late)
- {
- Cursor(n);
- Cursor(late);
- }
- }
- }
- void Time_Cursor(char n)
- {
- switch(n) //选光标
- {
- case 0:LCD12864_Reverse(0,16,0);LCD12864_Reverse(1,16,0);break;
- case 1:LCD12864_Reverse(3,16,0);break;
- case 2:LCD12864_Reverse(5,16,0);break;
- case 3:LCD12864_Reverse(1,32,0);break;
- case 4:LCD12864_Reverse(2,32,1);LCD12864_Reverse(3,32,2);break;
- case 5:LCD12864_Reverse(4,32,0);break;
- case 6:LCD12864_Reverse(4,48,0);break;
- case 7:break;
- }
- }
- void Adjust_time(void)
- {
- char n=0,late=7;
- LCD12864_datas(0,1,"----时间设置----");
- LCD12864_datas(2,2,"年");
- LCD12864_datas(4,2,"月");
- LCD12864_datas(6,2,"日");
- LCD12864_datas(2,4,"星期");
- hour=DS1302_ReadData(HOUR);
- min=DS1302_ReadData(MIN);
- sec=DS1302_ReadData(SEC); //读取时间
- year=DS1302_ReadData(YEAR);
- month=DS1302_ReadData(MONTH);
- date=DS1302_ReadData(DATE); //读取年月日
- day=DS1302_ReadData(DAY);
- LCD12864_SetXY(0,2);
- LCD12864_WriteData(yearH/10+'0');
- LCD12864_WriteData(yearH%10+'0');
- LCD12864_WriteData('0'+(year>>4));
- LCD12864_WriteData('0'+(year&0x0f)); //年份
- LCD12864_SetXY(3,2);
- LCD12864_WriteData('0'+(month>>4));
- LCD12864_WriteData('0'+(month&0x0f)); //月份
- LCD12864_SetXY(5,2);
- LCD12864_WriteData('0'+(date>>4));
- LCD12864_WriteData('0'+(date&0x0f)); //日期
- LCD12864_SetXY(1,3);
- LCD12864_WriteData((hour>>4)+'0');
- LCD12864_WriteData((hour&0x0f)+'0'); //小时
- LCD12864_WriteData(':'); //冒号
- LCD12864_WriteData((min>>4)+'0');
- LCD12864_WriteData((min&0x0f)+'0'); //分钟
- LCD12864_WriteData(':'); //冒号
- LCD12864_WriteData((sec>>4)+'0');
- LCD12864_WriteData((sec&0x0f)+'0'); //秒针
-
- LCD12864_datas(4,4,Weekday[day]); //星期
- Time[0].num=(year>>4)*10+(year&0x0f);
- Time[1].num=(month>>4)*10+(month&0x0f);
- Time[2].num=(date>>4)*10+(date&0x0f);
- Time[3].num=(hour>>4)*10+(hour&0x0f);
- Time[4].num=(min>>4)*10+(min&0x0f);
- Time[5].num=(sec>>4)*10+(sec&0x0f);
- Time[6].num=day; //将BCD码转换为十进制数
- Time_Cursor(0); //初始光标位置
-
- while(1)
- {
- LCD12864_datas(7,4,"00");
- late=n;
- keynum=Key_Scan();
- if(keynum==13)
- {
- LCD12864_datas(7,4,"01");
- while(1)
- {
- keynum=Key_Scan();
- if(keynum==14) Time[n].num++;
- if(keynum==15) Time[n].num--;
- if(Time[n].num>Time[n].max)Time[n].num=Time[n].min;
- if(Time[n].num<Time[n].min)Time[n].num=Time[n].max;
- if(n==6)
- {
- LCD12864_datas(4,4,Weekday[Time[n].num]); //星期
- }
- else
- {
- LCD12864_SetXY(Time[n].x,Time[n].y);
- if(n==4) LCD12864_WriteData(':'); //冒号
- LCD12864_WriteData('0'+(Time[n].num/10));
- LCD12864_WriteData('0'+(Time[n].num%10));
- if(n==4) LCD12864_WriteData(':'); //冒号
-
- }
- if(keynum==13)
- {
- DS1302_WriteDat(0x8e,0x00); //关闭写保护
- DS1302_WriteDat(DS1302_Addr[n],((Time[n].num/10)<<4)+(Time[n].num%10));
- DS1302_WriteDat(0x8e,0x80); //开启写保护
- break;
- }
- if(keynum==16) break;
- }
- }
- if(keynum==14) n++;
- if(keynum==15) n--;
- if(n>6)n=0;if(n<0)n=6;
- if(n!=late)
- {
- Time_Cursor(n);
- Time_Cursor(late);
- }
- if(keynum==16)
- {
- page=4;
- break;
- }
- }
-
- }
- void Clock_Cursor(char n)
- {
- switch(n) //选光标
- {
- case 0:LCD12864_Reverse(1,16,0);break;
- case 1:LCD12864_Reverse(3,16,0);break;
- case 2:LCD12864_Reverse(3,32,0);break;
- case 3:break;
- }
- }
- void Clock(uchar k)
- {
- char n=0,late=3;
- LCD12864_WriteCom(0x01); //12864清屏
- Time[7].num=Clock_num_hour[k]; //小时
- Time[8].num=Clock_num_min[k]; //分钟
- Time[9].num=Clock_flag[k]; //标志
- LCD12864_datas(0,1,"----闹钟设置----");
- LCD12864_SetXY(2,2);
- LCD12864_WriteData(':'); //冒号
- LCD12864_SetXY(1,2);
- LCD12864_WriteData((Time[7].num>>4)+'0');
- LCD12864_WriteData((Time[7].num&0x0f)+'0'); //小时
- LCD12864_SetXY(3,2);
- LCD12864_WriteData((Time[8].num>>4)+'0');
- LCD12864_WriteData((Time[8].num&0x0f)+'0'); //分钟
- LCD12864_datas(0,3,"闹钟:");
- if(Time[9].num==0) LCD12864_datas(3,3,"关");
- else LCD12864_datas(3,3,"开");
-
- Time[7].num=(Time[7].num>>4)*10+(Time[7].num&0x0f);
- Time[8].num=(Time[8].num>>4)*10+(Time[8].num&0x0f);
- Time[9].num=(Time[9].num>>4)*10+(Time[9].num&0x0f);
- Clock_Cursor(0); //初始光标位置
- while(1)
- {
- LCD12864_datas(7,4,"00");
- keynum=Key_Scan();
- late=n;
- if(keynum==13)
- {
- LCD12864_datas(7,4,"01");
- n=n+7;
- while(1)
- {
- keynum=Key_Scan();
- if(keynum==14) Time[n].num++;
- if(keynum==15) Time[n].num--;
- if(Time[n].num>Time[n].max)Time[n].num=Time[n].min;
- if(Time[n].num<Time[n].min)Time[n].num=Time[n].max;
-
- if(Time[9].num==0) LCD12864_datas(3,3,"关");
- else LCD12864_datas(3,3,"开");
-
- LCD12864_SetXY(1,2);
- LCD12864_WriteData((Time[7].num/10)+'0');
- LCD12864_WriteData((Time[7].num%10)+'0'); //小时
- LCD12864_SetXY(3,2);
- LCD12864_WriteData((Time[8].num/10)+'0');
- LCD12864_WriteData((Time[8].num%10)+'0'); //分钟
- if(keynum==13)
- {
- break;
- }
- if(keynum==16)
- {
- break;
- }
- }
- n=n-7;
- }
- if(keynum==14) n++;
- if(keynum==15) n--;
- if(n>2)n=0;if(n<0)n=2;
- if(n!=late)
- {
- Clock_Cursor(n);
- Clock_Cursor(late);
- }
- if(keynum==16)
- {
- page=2; //返回菜单
- Time[7].num=((Time[7].num/10)<<4)+(Time[7].num%10);
- Time[8].num=((Time[8].num/10)<<4)+(Time[8].num%10);
- Time[9].num=((Time[9].num/10)<<4)+(Time[9].num%10);
- Clock_num_hour[k]=Time[7].num; //小时
- Clock_num_min[k]=Time[8].num; //分钟
- Clock_flag[k]=Time[9].num; //标志
- if(Clock_flag[k]!=0)
- {
- TMOD|=0x01;
- EA=1;
- ET0=1;
- TH0=0x3c;
- TL0=0xb0; //定时50ms
- TR0=1;
- }
- break;
- }
- }
- }
- void Select_Clock_Cursor(uchar n)
- {
- switch(n)
- {
- case 0:LCD12864_Reverse(2,16,0);LCD12864_Reverse(3,16,0);LCD12864_Reverse(4,16,0);LCD12864_Reverse(5,16,0);break;
- case 1:LCD12864_Reverse(2,32,0);LCD12864_Reverse(3,32,0);LCD12864_Reverse(4,32,0);LCD12864_Reverse(5,32,0);break;
- case 2:LCD12864_Reverse(2,48,0);LCD12864_Reverse(3,48,0);LCD12864_Reverse(4,48,0);LCD12864_Reverse(5,48,0);break;
- default:break;
- }
- }
- void Select_Clock(void)
- {
- char n=0,late=4;
- LCD12864_datas(0,1,"----闹钟选择----");
- LCD12864_datas(0,2," 1.闹钟01");
- LCD12864_datas(0,3," 2.闹钟02");
- LCD12864_datas(0,4," 3.闹钟03");
- Select_Clock_Cursor(0); //初始光标位置
- while(1)
- {
- keynum=Key_Scan();
- late=n;
- if(keynum==13) {clock_page=n;page=5;break;} //确认键
- else if(keynum>=1&&keynum<=4) n=keynum-1;
- else if(keynum==14) n++;
- else if(keynum==15) n--;
- else if(keynum==16) {page=4; break;}
- if(n>2)n=0;if(n<0)n=2;
- if(n!=late)
- {
- Select_Clock_Cursor(n);
- Select_Clock_Cursor(late);
- }
- }
- }
- void Countdown(void)
- {
- LCD12864_datas(0,1,"----倒计时器----");
-
- while(1)
- {
- keynum=Key_Scan();
- LCD12864_SetXY(3,3);
- LCD12864_WriteData((M_num/10)+'0');
- LCD12864_WriteData((M_num%10)+'0'); //分钟
- LCD12864_WriteData(':'); //冒号
- LCD12864_WriteData((S_num/10)+'0');
- LCD12864_WriteData((S_num%10)+'0'); //分钟
- if(keynum==13)
- {
- TMOD|=0x10;
- EA=1;
- ET1=1;
- TH1=0x3c;
- TL1=0xb0; //定时50ms
- TR1=1;
- }
- else if(keynum==2) M_num--; //减低分钟
- else if(keynum==3) S_num--; //减低秒针
- else if(keynum==14) //重置计数值
- {
- S_num=59;
- M_num=59;
- }
- else if(keynum==15) //停止计时
- {
- TR1=0;
- }
- else if(keynum==16) {page=4; break;} //退出到菜单页
- if(S_num==0) //判断时间越界
- {
- S_num=59;
- M_num--;
- }
- if(M_num==0&&S_num==0)
- {
- while(1)
- {
- Beep_key();
- Delay10ms(5);
- if(Key_Scan()!=0)
- {
- TR1=0;
- S_num=59;
- M_num=59;
- break;
- }
-
- }
- }
- }
- }
- void time_2(void) interrupt 3
- {
- TH1=0x3c;
- TL1=0xb0; //定时50ms
- counter++;
- if(counter==20)
- {
- counter=0;
- S_num--;
- }
- }
- void main(void)
- {
- CLK_DIV=0x03; //八分频
- LCD12864_Init(); //12864初始化
- LCD12864_CleanScreen(); //12864清屏
- DS1302_Init(); //DS1302初始化
- while(1)
- {
- LCD12864_CleanScreen(); //12864清屏(CGRAM)
- LCD12864_WriteCom(0x01); //12864清屏(DDRAM)
- if(page==0) Timer(); //page=0时,数字钟界面
- else if(page==1) Adjust_time(); //page=1时,调整时间界面
- else if(page==2) Select_Clock(); //page=2时,系统设置界面
- else if(page==3) Countdown(); //page=3时,倒计时器页面
- else if(page==4) meun(); //page=4时,菜单页面
- else if(page==5) Clock(clock_page); //page=4时,菜单页面
- }
-
- }
- void time_1(void) interrupt 1
- {
- uchar i,H,M;
- H=DS1302_ReadData(HOUR);
- M=DS1302_ReadData(MIN);
- TH0=0x3c;
- TL0=0xb0; //定时50ms
- for(i=0;i<3;i++)
- {
- if(Clock_flag[i]==1)
- while(H==Clock_num_hour[i]&&M==Clock_num_min[i])
- {
- Clock_flag[i]=0;
- Beep_key();
- Delay10ms(5);
- if(Key_Scan()!=0) break;
- }
- }
- if(Clock_flag[0]==0&&Clock_flag[1]==0&&Clock_flag[2]==0)
- {
- TR0=0;
- // Time[9].num=0;
- // Clock_flag[0]=1;
- // Clock_flag[1]=1;
- // Clock_flag[2]=1;
- }
- }
复制代码
所有资料51hei提供下载:
带闹钟万年历程序.zip
(117.86 KB, 下载次数: 36)
|