51单片机的电子时钟,闹钟。无DS1302仅仅用定时器,LCD1602做成的闹钟,星期跟日期可以分开写的,但无润平年之分和无月份天数区分。
单片机源程序如下:
- #include"reg52.h"
- typedef unsigned char u8;
- typedef unsigned int u16;
- #define datapins P0
- sbit E=P2^7;
- sbit RW=P2^5;
- sbit RS=P2^6;
- sbit beep=P1^5;
- sbit k1=P1^4; //时钟功能键
- sbit k2=P1^3; //增大键
- sbit k3=P1^2; //减小键
- sbit k4=P1^1; //闹钟功能键
- u8 k1num,knnum,shi,fen,miao,nian,yue,ri,nshi,nfen,nmiao,nnian,nyue,nri,i,count,we,nwe;
- void delay(u16 c); //延时函数 误差 0us
- void LcdWriteCom(u8 com); //LCD1602写入8位命令子函数
- void LcdWriteData(u8 dat); //LCD1602写入8位数据子函数
- void init(); //初始化程序
- void keyscan(); //按键程序
- void di(); //发声函数
- void write_sfm(u8 add,u8 date); //时间调节
- void write_sfm1(u8 add,u8 date); //时间调节
- void write_nyr(u8 add,u8 date); //时间调节
- void write_nyr1(u8 add,u8 date); //时间调节
- void lcd_init(); //LCD1602初始化函数
- void delay(u16 c) //延时 误差 0us
- {
- u16 a,b;
- for (;c>0;c--)
- {
- for(b=199;b>0;b--)
- {
- for(a=1;a>0;a--);
- }
- }
- }
- void lcd_init() //lcd初始化函数
- {
- E=0;
- RW=0;
- RS=0;
- LcdWriteCom(0x38); //开显示
- LcdWriteCom(0x0c); //开显示不显示光标
- LcdWriteCom(0x06); //写一个指针加1
- LcdWriteCom(0x80); //设置数据指针起点
- }
- void di() //发出di声
- {
- beep=0;
- delay(100);
- beep=1;
- }
- void LcdWriteCom(u8 com) //写入命令
- {
-
- datapins=com; //放入命令
- delay(1); //等待数据稳定
- E=1; //写入时序
- delay(5); //保持时间
- E=0;
- }
- void LcdWriteData(u8 dat) //写入数据
- {
- E=0; //使能清零
- RS=1; //选择输入数据
- RW=0; //选择写入
- datapins=dat; //写入数据
- delay(1);
- E = 1; //写入时序
- delay(5); //保持时间
- E = 0;
- }
- void write_sfm(u8 add,u8 date) //时间调节
- {
- u16 sh,ge;
- sh=date/10;
- ge=date%10;
- lcd_init();
- LcdWriteCom(0x80+0x40+add);
- LcdWriteData(0x30+sh);
- LcdWriteData(0x30+ge);
- }
- void write_sfm1(u8 add,u8 date) //定时器用时间调节
- {
- u16 sh,ge;
- sh=date/10;
- ge=date%10;
- if(knnum==0)
- {
- lcd_init();
- LcdWriteCom(0x80+0x40+add);
- LcdWriteData(0x30+sh);
- LcdWriteData(0x30+ge);
- }
- }
- void write_nyr(u8 add,u8 date) //时间调节
- {
- u16 sh,ge;
- sh=date/10;
- ge=date%10;
- lcd_init();
- LcdWriteCom(0x80+add);
- LcdWriteData(0x30+sh);
- LcdWriteData(0x30+ge);
- }
- void write_nyr1(u8 add,u8 date) //定时器用时间调节
- {
- u16 sh,ge;
- sh=date/10;
- ge=date%10;
- if(knnum==0)
- {
- lcd_init();
- LcdWriteCom(0x80+add);
- LcdWriteData(0x30+sh);
- LcdWriteData(0x30+ge);
- }
- }
- void write_week(u8 we)
- {
- LcdWriteCom(0x80+13);
- switch(we)
- {
- case 1:LcdWriteData('M');delay(5);
- LcdWriteData('O');delay(5);
- LcdWriteData('N');
- break;
- case 2:LcdWriteData('T');delay(5);
- LcdWriteData('U');delay(5);
- LcdWriteData('E');
- break;
- case 3:LcdWriteData('W');delay(5);
- LcdWriteData('E');delay(5);
- LcdWriteData('D');
- break;
- case 4:LcdWriteData('T');delay(5);
- LcdWriteData('H');delay(5);
- LcdWriteData('U');
- break;
- case 5:LcdWriteData('F');delay(5);
- LcdWriteData('R');delay(5);
- LcdWriteData('T');
- break;
- case 6:LcdWriteData('S');delay(5);
- LcdWriteData('A');delay(5);
- LcdWriteData('T');
- break;
- case 7:LcdWriteData('S');delay(5);
- LcdWriteData('U');delay(5);
- LcdWriteData('N');
- break;
- }
- }
- void write_week1(u8 nwe)
- {
- LcdWriteCom(0x80+13);
- switch(nwe)
- {
- case 1:LcdWriteData('M');delay(5);
- LcdWriteData('O');delay(5);
- LcdWriteData('N');
- break;
- case 2:LcdWriteData('T');delay(5);
- LcdWriteData('U');delay(5);
- LcdWriteData('E');
- break;
- case 3:LcdWriteData('W');delay(5);
- LcdWriteData('E');delay(5);
- LcdWriteData('D');
- break;
- case 4:LcdWriteData('T');delay(5);
- LcdWriteData('H');delay(5);
- LcdWriteData('U');
- break;
- case 5:LcdWriteData('F');delay(5);
- LcdWriteData('R');delay(5);
- LcdWriteData('T');
- break;
- case 6:LcdWriteData('S');delay(5);
- LcdWriteData('A');delay(5);
- LcdWriteData('T');
- break;
- case 7:LcdWriteData('S');delay(5);
- LcdWriteData('U');delay(5);
- LcdWriteData('N');
- break;
- }
- }
- void init() //初始化程序
- {
- E=0;
- RW=0;
- RS=0;
- shi=23;
- fen=59;
- miao=55;
- nian=18;
- yue=7;
- ri=30;
- we=1;
- nwe=2;
- k1num=0; //时钟k1计数
- knnum=0; //闹钟k4计数
- nshi=0;
- nfen=0;
- nmiao=5;
- nnian=18;
- nyue=8;
- nri=1;
- LcdWriteCom(0x38); //开显示
- LcdWriteCom(0x0c); //开显示不显示光标
- LcdWriteCom(0x06); //写一个指针加1
- LcdWriteCom(0x01); //清屏
- LcdWriteCom(0x80); //设置数据指针起点
- delay(5);
- RW=0;
- RS=0;
- E=0;
- LcdWriteCom(0x38); //开显示
- LcdWriteCom(0x0c); //写一个指针加1
- LcdWriteCom(0x80+0x40); //开显示不显示光标
- LcdWriteCom(0x06); //显示时钟标志
- LcdWriteData('S');
- LcdWriteData('H');
- LcdWriteData('I');
- RW=0;
- RS=0;
- E=0;
- LcdWriteCom(0x80+0x40+9);
- LcdWriteData(':');
- RW=0;
- RS=0;
- E=0;
- LcdWriteCom(0x80+0x40+6);
- LcdWriteData(':');
- RW=0;
- RS=0;
- E=0;
- LcdWriteCom(0x80+2);
- LcdWriteData('2');
- LcdWriteData('0');
- RW=0;
- RS=0;
- E=0;
- LcdWriteCom(0x80+6);
- LcdWriteData('-');
- RW=0;
- RS=0;
- E=0;
- LcdWriteCom(0x80+9);
- LcdWriteData('-');
-
- RW=0;
- RS=0;
- E=0;
- LcdWriteCom(0x80+13);
- write_week(we);
-
- write_sfm(4,shi);
- write_sfm(7,fen);
- write_sfm(10,miao);
- write_nyr(4,nian);
- write_nyr(7,yue);
- write_nyr(10,ri);
- write_week(we);
- TMOD|=0x01; //设置定时器0工作模式1
- TH0=(65536-50000)/256; //定时器初装
- TL0=(65536-50000)%256;
- EA=1; //打开总中断
- ET0=1; //打开定时器0中断
- TR0=1; //启动定时器0
- }
- void keyscan() //按键调节
- {
- if(k4==0&&k1num==0) //进入闹钟调节
- {
- delay(5);
- if(k4==0)
- {
- knnum++;
- while(!k4); //检查按键松开
- di();
- if(knnum==1)
- {
- E=0;
- RS=0;
- RW=0;
- LcdWriteCom(0x80+0x40); //显示闹钟标志
- LcdWriteData('N');
- LcdWriteData('A');
- LcdWriteData('O');
- E=0;
- RS=0;
- RW=0;
- LcdWriteCom(0x80+0x40+6); //在时分之间显示":"
- LcdWriteData(':');
- delay(5);
- E=0;
- RS=0;
- RW=0;
- LcdWriteCom(0x80+0x40+9); //在分秒之间显示":"
- LcdWriteData(':');
- delay(5);
- write_sfm(4,nshi);
- write_sfm(7,nfen);
- write_sfm(10,nmiao);
- write_nyr(4,nian);
- write_nyr(7,yue);
- write_nyr(10,ri);
- write_week(we);
- E=0;
- RS=0;
- RW=0;
- LcdWriteCom(0x80+0x40+4); //光标指向时
- LcdWriteCom(0x0f); //开启光标
- }
- if(knnum==2)
- {
- LcdWriteCom(0x80+0x40+7); //光标移动到fen
- }
- if(knnum==3)
- {
- LcdWriteCom(0x80+0x40+10) ; //光标移动到miao
- }
- if(knnum==4)
- {
- LcdWriteCom(0x80+4) ; //光标移动到nian
- }
- if(knnum==5)
- {
- LcdWriteCom(0x80+7) ; //光标移动到yue
- }
- if(knnum==6)
- {
- LcdWriteCom(0x80+10) ; //光标移动到ri
- }
- if(knnum==7)
- {
- LcdWriteCom(0x80+13); //光标移动到week
- }
- if(knnum==8)
- {
- knnum=0; //按键次数清零
- LcdWriteCom(0x0c); //取消光标闪烁
- TR0=0;
- E=0;
- RS=0;
- RW=0;
- write_sfm(4,shi);
- write_sfm(7,fen);
- write_sfm(10,miao);
- write_nyr(4,nian);
- write_nyr(7,yue);
- write_nyr(10,ri);
- write_week(we);
- TR0=1;
- E=0;
- RS=0;
- RW=0;
- LcdWriteCom(0x80+0x40); //显示时钟标志
- LcdWriteData('S');
- LcdWriteData('H');
- LcdWriteData('I');
- }
- }
- }
- /**********************闹钟增大**********************************/
- if(knnum!=0)
- {
- if(k2==0)
- {
- delay(5);
- if(k2==0)
- {
- while(!k2); //确认按键释放
- di();
- if(knnum==1)
- {
- nshi++; //shi加1
- if(nshi==24) //shi满24清零
- nshi=0;
- write_sfm(4,nshi);
- E=0;
- RW=0;
- RS=0;
- LcdWriteCom(0x0f);
- LcdWriteCom(0x80+0x40+4); //显示重新回到调节处
-
- }
- if(knnum==2)
- {
- nfen++;
- if(nfen==60)
- nfen=0;
- write_sfm(7,nfen);
- RW=0;
- RS=0;
- E=0;
- LcdWriteCom(0x0f);
- LcdWriteCom(0x80+0x40+7); //显示重新回到调节处
- }
- if(knnum==3)
- {
- nmiao++;
- if(nmiao==60)
- nmiao=0;
- write_sfm(10,nmiao);
- RW=0;
- RS=0;
- E=0;
- LcdWriteCom(0x0f);
- LcdWriteCom(0x80+0x40+10); //显示重新回到调节处
- }
- if(knnum==4)
- {
- nnian++; //nian减1
- if(nnian==21) //nian小于零回到最大
- nnian=10;
- write_nyr(4,nnian);
- RW=0;
- RS=0;
- E=0;
- LcdWriteCom(0x0f);
- LcdWriteCom(0x80+4); //显示重新回到调节处
- }
- if(knnum==5)
- {
- nyue++;
- if(nyue==13)
- nyue=1;
- write_nyr(7,nyue);
- RW=0;
- RS=0;
- E=0;
- LcdWriteCom(0x0f);
- LcdWriteCom(0x80+7); //显示重新回到调节处
- }
- if(knnum==6)
- {
- nri++;
- if(nri==31)
- nri=1;
- write_nyr(10,nri);
- RW=0;
- RS=0;
- E=0;
- LcdWriteCom(0x0f);
- LcdWriteCom(0x80+10); //显示重新回到调节处
- }
- if(knnum==7)
- {
- nwe++;
- if(nwe==8)
- nwe=1;
- write_week1(nwe);
- RW=0;
- RS=0;
- E=0;
- LcdWriteCom(0x0f);
- LcdWriteCom(0x80+13); //显示重新回到调节处
- }
- }
- }
- /************************闹钟减小*********************************/
- if(k3==0)
- {
- delay(5);
- if(k3==0)
- {
- while(!k3); //确认按键释放
- di();
- if(knnum==1)
- {
- nshi--; //nshi减1
- if(nshi==-1) //nshi等于-1回到最大
- nshi=23;
- write_sfm(4,nshi);
- RW=0;
- RS=0;
- E=0;
- LcdWriteCom(0x0f);
- LcdWriteCom(0x80+0x40+4); //显示重新回到调节处
- }
- if(knnum==2)
- {
- nfen--; //nfen减1
- if(nfen==-1) //nfen等于-1回到最大
- nfen=59;
- write_sfm(7,nfen);
- RW=0;
- RS=0;
- E=0;
- LcdWriteCom(0x0f);
- LcdWriteCom(0x80+0x40+7); //显示重新回到调节处
- }
- if(knnum==3)
- {
- nmiao--; //nmiao减1
- if(nmiao==-1) //nmiao等于-1回到最大
- nmiao=59;
- write_sfm(10,nmiao);
- RW=0;
- RS=0;
- E=0;
- LcdWriteCom(0x0f);
- LcdWriteCom(0x80+0x40+10); //显示重新回到调节处
- }
- if(knnum==4)
- {
- nnian--; //nian减1
- if(nnian==9) //nian小于零回到最大
- nnian=20;
- write_nyr(4,nnian);
- RW=0;
- RS=0;
- E=0;
- LcdWriteCom(0x0f);
- LcdWriteCom(0x80+4); //显示重新回到调节处
- }
- if(knnum==5)
- {
- nyue--;
- if(nyue==0)
- nyue=12;
- write_nyr(7,nyue);
- RW=0;
- RS=0;
- E=0;
- LcdWriteCom(0x0f);
- LcdWriteCom(0x80+7); //显示重新回到调节处
- }
- if(knnum==6)
- {
- nri--;
- if(nri==0)
- nri=30;
- write_nyr(10,nri);
- RW=0;
- RS=0;
- E=0;
- LcdWriteCom(0x0f);
- LcdWriteCom(0x80+10); //显示重新回到调节处
- }
- if(knnum==7)
- {
- nwe--;
- if(nwe==0)
- nwe=7;
- write_week1(nwe);
- RW=0;
- RS=0;
- E=0;
- LcdWriteCom(0x0f);
- LcdWriteCom(0x80+13); //显示重新回到调节处
- }
- }
- }
- }
-
- /****************************************************************/
- if(k1==0&&knnum==0) //进入时钟调节
- {
- delay(5);
- if(k1==0)
- {
- k1num++;
- while(!k1);
- di();
- if(k1num==1)
- {
- TR0=0; //关闭定时器
- E=0;
- RW=0;
- RS=0;
- LcdWriteCom(0x80+0x40+4); //光标移动到shi
- LcdWriteCom(0x0f); //光标闪烁
- }
- if(k1num==2)
- {
- LcdWriteCom(0x80+0x40+7); //光标移动到fen
- }
- if(k1num==3)
- {
- LcdWriteCom(0x80+0x40+10); //光标移动到miao
- }
- if(k1num==4)
- {
- LcdWriteCom(0x80+4) ; //光标移动到nian
- }
- if(k1num==5)
- {
- LcdWriteCom(0x80+7) ; //光标移动到yue
- }
- if(k1num==6)
- {
- LcdWriteCom(0x80+10) ; //光标移动到ri
- }
- if(k1num==7)
- {
- LcdWriteCom(0x80+13); //光标移动到week
- }
- if(k1num==8)
- {
- k1num=0; //按键次数清零
- LcdWriteCom(0x0c); //取消光标闪烁
- TR0=1; //计时启动
- }
- }
- }
- /**********************增大***************************************/
- if(k1num!=0)
- {
- if(k2==0)
- {
- delay(5);
- if(k2==0)
- {
- while(!k2); //确认按键释放
- di();
- if(k1num==1)
- {
- shi++; //shi加1
- if(shi==24) //shi满24清零
- shi=0;
- write_sfm(4,shi);
- RW=0;
- RS=0;
- E=0;
- LcdWriteCom(0x0f);
- LcdWriteCom(0x80+0x40+4); //显示重新回到调节处
-
- }
- if(k1num==2)
- {
- fen++;
- if(fen==60)
- fen=0;
- write_sfm(7,fen);
- RW=0;
- RS=0;
- E=0;
- LcdWriteCom(0x0f);
- LcdWriteCom(0x80+0x40+7); //显示重新回到调节处
- }
- if(k1num==3)
- {
- miao++;
- if(miao==60)
- miao=0;
- write_sfm(10,miao);
- RW=0;
- RS=0;
- E=0;
- LcdWriteCom(0x0f);
- LcdWriteCom(0x80+0x40+10); //显示重新回到调节处
- }
- if(k1num==4)
- {
- nian++; //nian减1
- if(nian==21) //nian小于零回到最大
- nian=10;
- write_nyr(4,nian);
- RW=0;
- RS=0;
- E=0;
- LcdWriteCom(0x0f);
- LcdWriteCom(0x80+4); //显示重新回到调节处
- }
- if(k1num==5)
- {
- yue++;
- if(yue==13)
- yue=1;
- write_nyr(7,yue);
- RW=0;
- RS=0;
- E=0;
- LcdWriteCom(0x0f);
- LcdWriteCom(0x80+7); //显示重新回到调节处
- }
- if(k1num==6)
- {
- ri++;
- if (ri==31)
- ri=1;
- write_nyr(10,ri);
- RW=0;
- RS=0;
- E=0;
- LcdWriteCom(0x0f);
- LcdWriteCom(0x80+10); //显示重新回到调节处
- }
- if(k1num==7)
- {
- we++;
- if(we==8)
- we=1;
- write_week(we);
- RW=0;
- RS=0;
- E=0;
- LcdWriteCom(0x0f);
- LcdWriteCom(0x80+13); //显示重新回到调节处
- }
- }
- }
- /************************减小*********************************/
- if(k3==0)
- {
- delay(5);
- if(k3==0)
- {
- while(!k3); //确认按键释放
- di();
- if(k1num==1)
- {
- shi--; //shi减1
- if(shi==-1) //shi小于零回到最大
- shi=23;
- write_sfm(4,shi);
- RW=0;
- RS=0;
- E=0;
- LcdWriteCom(0x0f);
- LcdWriteCom(0x80+0x40+4); //显示重新回到调节处
- }
- if(k1num==2)
- {
- fen--;
- if(fen==-1)
- fen=59;
- write_sfm(7,fen);
- RW=0;
- RS=0;
- E=0;
- LcdWriteCom(0x0f);
- LcdWriteCom(0x80+0x40+7); //显示重新回到调节处
- }
- if(k1num==3)
- {
- miao--;
- if (miao==-1)
- miao=59;
- write_sfm(10,miao);
- RW=0;
- RS=0;
- E=0;
- LcdWriteCom(0x0f);
- LcdWriteCom(0x80+0x40+10); //显示重新回到调节处
- }
- if(k1num==4)
- {
- nian--; //nian减1
- if(nian==9) //nian小于零回到最大
- nian=20;
- write_nyr(4,nian);
- RW=0;
- RS=0;
- E=0;
- LcdWriteCom(0x0f);
- LcdWriteCom(0x80+4); //显示重新回到调节处
- }
- if(k1num==5)
- {
- yue--;
- if(yue==0)
- yue=12;
- write_nyr(7,yue);
- RW=0;
- RS=0;
- E=0;
- LcdWriteCom(0x0f);
- LcdWriteCom(0x80+7); //显示重新回到调节处
- }
- if(k1num==6)
- {
- ri--;
- if (ri==0)
- ri=30;
- ……………………
- …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码
所有资料51hei提供下载:
新建文件夹.zip
(54.31 KB, 下载次数: 53)
|