單片機(jī)萬年歷實(shí)訓(xùn)
《單片機(jī)萬年歷實(shí)訓(xùn)》由會員分享,可在線閱讀,更多相關(guān)《單片機(jī)萬年歷實(shí)訓(xùn)(28頁珍藏版)》請?jiān)谘b配圖網(wǎng)上搜索。
1、 單片機(jī)萬年歷實(shí)訓(xùn) 單片機(jī)萬年歷實(shí)訓(xùn) 仿真圖: +4.5 C5 RV1 30pF U2 X2 19 39 CRYSTAL XTAL1 P0.0/AD0 38 C6 P0.1/AD1
2、 37 18 P0.2/AD2 36 C4 XTAL2 P0.3/AD3 單片機(jī)復(fù)位鍵 35 10k P0.4/AD4 34 30pF P0.5/AD5 10uF 33 P0.6/AD6 9 32 RST P0.7/AD7 P2.0/A8 21
3、 22 R2 P2.1/A9 23 P2.2/A10 29 24 10k PSEN P2.3/A11 30 25 ALE P2.4/A12 31 26 EA P2.5/A13 27 mean P2.6/A14 鍵 key_mean 28 mean 1 P2.7/A15 10
4、 2 P1.0 P3.0/RXD 11 P1.1 P3.1/TXD 3 12 ok P1.2 P3.2/INT0 確定鍵 key_ok 4 13 P1.3 P3.3/INT1 5 P1.4 P3.4/T0 14 6 15 7 P1.5 P3.5/T1 16 set P1.6 P3.6/WR 增加鍵 key_set 8 17 80C51 P3.7/RD
5、 P1.7 Q1 2N3390 LCD1 LM016L S D E S D E V V V 1 2 3 S W 0 1 2 3 4 5 6 7 R R E DDDDDDDD 4 5 6 7 8 9 0 1 2 3 4 1 1 1 1 1 原理圖:
6、 2 程序: 3
7、
/**************************************** **
使用 LCD1602 與單片機(jī)實(shí)現(xiàn)的時鐘與日
期
顯示年、月、日、時、分、秒( 24 小時
制)
時間可調(diào), 年份 2000 —— 9999
2012年 10月 9 日
*************************************
******/
#include
8、t key_ok =P1^1; sbit key_set =P1^2; sbit RS =P1^5; //LCD 控制端口 sbit RW =P1^6; sbit E =P1^7; sfr PORT =0xa0; char flag_sec=0; // 值為 20 代表 1s 4 char flag_en_ok=0; char flag_en_key=0; // 值為 1 表示鍵盤 有效,否則無效 char flag_ok=0; //key_up 與 key_down 的功能選擇
9、 char flag_mean=0; char flag_set=0; //key_up 與 key_down 的功能標(biāo)識 char flag_year_leap=0; // 短語 //code char string_time[]= "Setting time ? \0"; code char string_year[]= "Setting year ? \0"; code char string_month[]= "Setting month ? \0"; code char string_mday[]= "Setti
10、ng day ? \0"; code char string_week[]= "Setting week ? \0"; code char string_hour[]= "Setting hour ? \0"; 5 code char string_minute[]="Setting minute? \0"; code char string_second[]="Setting second? \0"; // 年月日時分秒的定義 struct DATA_TIME { short year;
11、 // 待選 char month; char mday ; char week ; char hour ; char minute; char second; }time; struct time_char //time 的字符型 { char ch_year[4]; char ch_month[2]; char ch_mday[2]; char ch_week[1]; char ch_hour[2]; 6 char ch_minute[2]; char ch_
12、second[2]; }time_ch; /*************** 子 函 數(shù) ****************/ //LCD 的延時程序 void LCD_delay(void) { char i,j; for(i=100;i>=0;i--)for(j=0;j<20;j++); } // 向 LCD 寫指令函數(shù) void wcmd(char cmd ) { RS=0; RW=0; E=1; LCD_delay(); PORT
13、=cmd; 7 LCD_delay(); E=0; } // 向 LCD 寫數(shù)據(jù)函數(shù) void wdata(char DATA) { RS=1; RW=0; E=1; LCD_delay(); PORT=DATA; LCD_delay(); E=0; } // 寫字符串 void wstring(char *pt,char i)// i 為字符的 個數(shù),不帶 \0 { char j; for(j=0;j
14、 { 8 wdata(pt[j]); } } // 時間數(shù)據(jù)的格式轉(zhuǎn)換 void tran_2_ch(char *pt,char DATA) { pt[0]=DATA/10+0x30; pt[1]=DATA-pt[0]*10+0x10; } void tran_4_ch(char *pt,int DATA) { pt[0]=DATA/1000; pt[1]=DATA/100-pt[0]*10; pt[2]=DATA/10-pt[0]*100-pt[1]*10; pt[3]=D
15、ATA-pt[0]*1000-pt[1]*100-pt[2]*10; pt[0]+=0x30; pt[1]+=0x30; pt[2]+=0x30; pt[3]+=0x30; } // 格式轉(zhuǎn)換的實(shí)現(xiàn) 9 void tran_ch(void) { tran_4_ch(time_ch.ch_year ,time.year ); tran_2_ch(time_ch.ch_month,time.month); tran_2_ch(time_ch.ch_mday ,tim
16、e.mday ); //tran_2_ch(time_ch.ch_week ,time.week*10+1 ); time_ch.ch_week[0]=time.week+0x30; tran_2_ch(time_ch.ch_hour ,time.hour ); tran_2_ch(time_ch.ch_minute,time.minute); tran_2_ch(time_ch.ch_second,time.second); } // 是否是閏年 char leep_year(int y
17、ear)// 如果 是閏 年則 flag_year_leep=1, 否則 =0
{
10
if((year%400==0)||year%4==0&&year%10
0!=0)return 1;
else return 0;
}
// 星期的判斷
void de_week(void)
{
int i,j,day=0;
char mweek;
for(i=2000;i 18、 day+=365;
}
for(j=1;j 19、day;
mweek=day%7;
switch(mweek)
{
case 0:time.week=5;break;
case 1:time.week=6;break;
case 2:time.week=7;break;
case 3:time.week=1;break;
case 4:time.week=2;break;
case 5:time.week=3;break;
case 6:time.week=4;break;
}
time_ch.ch_week[0]=time.week+0x30;
}
20、
// 月份的進(jìn)位處理
void time_carry_mon_year(void)
12
{
flag_year_leap=leep_year(time.year);// 判 斷 閏年
if(time.mday>=30)
{
if(time.month==1||time.month==3||time.m onth==5||time.month==7\
||time.month==8||time.month==10||time.
month==12)
21、
// 天
數(shù)為 31 天的月, 1、3、5、7、8、10、12
{
if(time.mday==32)
{time.mday=1;time.month++;}
}
if(time.month==4||time.month==6||time.m onth==9||time.month==11)
13
{
if(time.month==31)
{time.mday=1;time.month++;}
}
tran_ch();
}
22、
if(time.month==2&&time.mday>=28)
{
if(flag_year_leap&&(time.mday==30))
{ time.mday=1;time.month++;}
if((!flag_year_leap)&&(time.mday==29))
{ time.mday=1;time.month++;} tran_ch();
}
if(time.month==13)
14
23、
{time.month=1;time.year++;tran_ch();}// 年 的
進(jìn)位
}
// 時間的進(jìn)位
void time_carry(void)
{
if(time.second==60) {time.minute++;time.second=0;}
if(time.minute==60) {time.hour++ ;time.minute=0;} if(time.hour ==24)
{time.mday++ ;time.hour=0 ;time_carry_m on_year();de_w 24、eek();}
}
// 屏幕的顯示函數(shù)
void dsp(void)
{
if(flag_en_key==0)// 非設(shè)置模式下的
顯示
15
{
tran_ch();
wcmd(0x02);//return cursor
wstring(time_ch.ch_hour,2);
wdata(':');
wstring(time_ch.ch_minute,2);
wdata(':');
wstring(time_ch.ch_second,2);
wst 25、ring(" ",3);
wcmd(0x80+0x40);
wstring(" ",3);
wstring(time_ch.ch_year,4);
wdata('-');
wstring(time_ch.ch_month,2);
wdata('-');
wstring(time_ch.ch_mday,2);
wstring(" W",2);
wdata(time_ch.ch_week[0]);
}
if(flag_en_key==1)// 設(shè)置模式下的顯
示
{
16
if(f 26、lag_set<=2)
{
tran_ch();
wcmd(0x02);//return cursor
wstring(time_ch.ch_year,4);
wdata('-');
wstring(time_ch.ch_month,2);
wdata('-');
wstring(time_ch.ch_mday,2);
}
if(flag_set>2)
{
tran_ch();
wcmd(0x02);//return cursor
wstring(time_ch.ch_hour,2);
27、
wdata(':');
wstring(time_ch.ch_minute,2);
wdata(':');
wstring(time_ch.ch_second,2);
17
wstring(" ",3);
}
}
}
// 顯示字符串 string_
void dsp_string(char *pt)
{
char i=0;
wcmd(0x80+0x40);// 將光標(biāo)調(diào)整至第
二行
while(pt[i])
28、
{
wdata(pt[i]);
i++;
}
}
// 退出按鍵模式
void exit_key(void)
{
char i;
flag_en_key=0;
18
flag_en_ok=0;
flag_ok=0;
flag_mean=0;
flag_set=0; // 清除所有標(biāo)記
wcmd(0x80+0x40);
for(i=0;i<=16;i++)
wdata('\0');
}
// 按鍵的處理子函數(shù)(由外中斷調(diào)用)
int solve_ 29、key(void)
{
//if(key_mean==0);
if(key_ok==0)// 確定或退出
{
if(flag_ok)
{
exit_key();
time_carry_mon_year();
de_week();
return 0;
}
19
else flag_ok=1;
}
if(key_set ==0)
{
if(flag_ok==0)// 時分秒的選擇
{
flag_set++;
if 30、(flag_set==6)flag_set=0;
switch(flag_set)
{
case
0:dsp_string(string_year);break;
case
1:dsp_string(string_month);break;
case
2:dsp_string(string_mday);break;
case
3:dsp_string(string_hour);break;
case
4:dsp_string(string_minute);break;
case
20
31、
5:dsp_string(string_second);break;
}
}
if(flag_ok==1)// 時分秒的設(shè)置
{
switch(flag_set)
{
case
0:{time.year++ ;if(time.year==10000)time.y ear=2000;break;}
case
1:{time.month++ ;time_carry_mon_year();brea k;}
case
2:{time.mday++ ;time_carry_mon_year();bre ak;}
cas 32、e
3:{time.hour++ ;if(time.hour==24)time.hou r=0;break;}
case
4:{time.minute++;if(time.minute==60)time.m inute=0;break;}
21
case
5:{time.second++;if(time.second==60)time.se cond=0;break;}
}
}
}
if(flag_ok==1)// 是否更改數(shù)據(jù) 是 顯
示OK 否顯示?
{
wcmd(0x 33、80+0x4e);
wdata('O');
wdata('K');
}
else
{
wcmd(0x80+0x4e);
wdata('\0');
wdata('?');
}
return 0;
}
22
//MCU 的秒中斷函數(shù)與顯示函數(shù)的執(zhí)行 void INT_sec() interrupt 1 using 0 {
if(flag_sec==20)//flag_sec==20 代 表
1s
{
flag_sec=0;
TH0=0x 34、3c;
TL0=0xb0+10;// 定時器再次進(jìn)入
0.05s 的中斷
// 加 10 是為了抵消中
斷與前兩個指令消耗的時間 (不精確 )
time.second++;
flag_en_ok=0;// 去掉 key_ok 的特
殊優(yōu)先權(quán)
time_carry();
dsp();
}
else
{
flag_sec++;
23
TH0=0X3C;
TL0=0XB0+10;// 定時器再次進(jìn)入
0.05s 的中斷
}
}
/ 35、/ 外中斷 0,鍵盤中斷
INT_X0(void) interrupt 0 using 0
{
LCD_delay(); // 去抖
TR0=0;// 關(guān)閉定時計(jì)數(shù)器 0
if(key_mean==0)
{
flag_en_ok=1;
flag_ok=0;
dsp_string(string_year);
}
if(flag_en_ok&&key_ok==0) {flag_en_key=1;flag_en_ok=0;} if(flag_en_key==1) {
24
36、
solve_key();
}
TR0=1;// 啟動定時計(jì)數(shù)器 0
}
//LCD 的初始化
void init(void)
{
E=0;// 確定 E 在初始化時為 0
wcmd(0x01);
wcmd(0x06);
wcmd(0x0c);
wcmd(0x38);
}
/************main 函 數(shù)
*****************/
int main()
{
// 單片機(jī)的初始化
EA=1;
ET0=1;// 定時 37、計(jì)數(shù)器 0 的使能
25
EX0=1;// 外中斷 0 的使能
IT0=1;// 下降沿觸發(fā)中斷
IP=0x02;// 定時計(jì)數(shù)器 0 的中斷優(yōu)先級
最高
TMOD=0x01;// 定時計(jì)數(shù)器 0 為工作模
式 1
TH0=0x3c;
TL0=0xb0;// 定時計(jì)數(shù)器參數(shù)為 0x3cb0 ,
0xffff-0x3cb0=50000 ,一個中斷中期為 0.05s
TR0=1;//MCU 初始化后直接啟動定時計(jì)
數(shù)器 0
time.year=2000;// 數(shù)據(jù)的初始 38、化
time.month=1;
time.mday=1;
time.week=6;
time.hour=0;
time.minute=0;
time.second=0;
init(); //LCD 初始化
26
while(1);// 單片機(jī)等待中斷
}
27
- 溫馨提示:
1: 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
2: 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
3.本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
5. 裝配圖網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 6.煤礦安全生產(chǎn)科普知識競賽題含答案
- 2.煤礦爆破工技能鑒定試題含答案
- 3.爆破工培訓(xùn)考試試題含答案
- 2.煤礦安全監(jiān)察人員模擬考試題庫試卷含答案
- 3.金屬非金屬礦山安全管理人員(地下礦山)安全生產(chǎn)模擬考試題庫試卷含答案
- 4.煤礦特種作業(yè)人員井下電鉗工模擬考試題庫試卷含答案
- 1 煤礦安全生產(chǎn)及管理知識測試題庫及答案
- 2 各種煤礦安全考試試題含答案
- 1 煤礦安全檢查考試題
- 1 井下放炮員練習(xí)題含答案
- 2煤礦安全監(jiān)測工種技術(shù)比武題庫含解析
- 1 礦山應(yīng)急救援安全知識競賽試題
- 1 礦井泵工考試練習(xí)題含答案
- 2煤礦爆破工考試復(fù)習(xí)題含答案
- 1 各種煤礦安全考試試題含答案