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)
2018-8-1 15:32 上傳
點擊文件名下載附件
加油! 下載積分: 黑幣 -5
|