制作好一個(gè)電子時(shí)鐘時(shí),單片機(jī)就差不多學(xué)會(huì)了80%,這個(gè)電子鐘可以顯示時(shí)間并且可以調(diào)節(jié)時(shí)間的秒,分,時(shí)。單片機(jī)主要的作用就是定時(shí)和中斷,如何充分利用好這兩個(gè)方面就是學(xué)習(xí)的重點(diǎn)。首先介紹下中斷,中斷就是指你在執(zhí)行一個(gè)指令的時(shí)候突然要執(zhí)行另一個(gè)指令時(shí)就要先將指令暫停先去執(zhí)行另一個(gè)指令,當(dāng)另一個(gè)指令完成時(shí)再返回完成中斷前的指令。單片機(jī)含有5個(gè)中斷,外部中斷0和1,定時(shí)器/計(jì)數(shù)器中斷0和1,串行口中斷。要執(zhí)行中斷時(shí)就要打開總中斷EA,將EA=1(高電平),在數(shù)字電路中1代表高電平,0代表低電平??傊袛嚅_完后,如果要開定時(shí)器中斷0的話就輸入ET0=1;再將TR0=1;這就開啟了定時(shí)器0的中斷(簡單吧)。中斷條件條件:1,有中斷請求(下面講),開總中斷EA=1,開中斷源中斷(ET0=1)。 關(guān)于中斷的詳細(xì)解說大家可以查看www.單片機(jī)網(wǎng)首頁上的第18課。
定時(shí)器有四種方式,我就用了方式1來寫電子鐘。如何定時(shí)呢?先聲明定時(shí)器工作方式TMOD,定時(shí)器0為低四位,定時(shí)器1為高四位。GATE大多數(shù)情況為 0(不詳細(xì)介紹),C/T為0時(shí)是定時(shí)器,1為計(jì)數(shù)器。我們選工作方式1所以第二位為01,所以TMOD=0x01;后面我們要裝初值也就是要往定時(shí)器 16位中裝初始值,由于單片機(jī)一個(gè)機(jī)器周期約為1微秒,一個(gè)機(jī)器周期定時(shí)器加1個(gè)值,TH0為定時(shí)器0的高8 位,TL0為低八位。大家都知道一個(gè)字節(jié)為最大值為65535,所以假如你要定時(shí)50ms的話就要裝65535-50000的值。只裝滿后就溢出執(zhí)行中斷(我就大概的介紹下)。中斷出去后執(zhí)行一個(gè)中斷函數(shù)大概形勢為
TMOD=0x01; TH0=0x4c; TL0=0x00; EA=1; ET0=1; TR0=1; void timer0() interrupt 1 { TH0=0x4c; TL0=0x00; } 接下來我要寫我電子鐘的程序,這個(gè)程序還沒完全寫好,還差一個(gè)I^2c總線斷電數(shù)據(jù)保存的程序,以后再補(bǔ)充。單片機(jī)不同端口具有不同的作用,當(dāng)我們向端口輸入不同的高低電平時(shí)就有不同的作用,這里我們用到了液晶屏的控制,定時(shí)器,中斷系統(tǒng),鍵盤。以后改進(jìn)會(huì)用到蜂鳴器,I^2c總線。額,電腦要沒電了 #include <reg52.h> #define uchar unsigned char #define uint unsigned int sbit dula=P3^7; sbit wela=P2; sbit rs=P2^5; sbit rw=P2^6; sbit s1=P1^0; sbit s2=P1^1; sbit s3=P1^2; sbit rd=P1^7; sbit lcden=P2^7; uchar count,s1num; char shi,fen,miao; uchar code table[]=" 2013-4-19 FRI" ; uchar code table1[]=" 00:00:00"; void delay(uint z) 延時(shí)函數(shù) delay(5)就是5ms { uint x,y; for(x=z;x>0;x--) for(y=110;y>0;y--); } void write_com(uchar com) { rs=0; rw=0; lcden=0; P0=com; delay(5); lcden=1; delay(5); lcden=0; } void write_data(uchar date) { rs=1; rw=0; lcden=0; P0=date; delay(5); lcden=1; delay(5); lcden=0; } void init() { uchar num; dula=0; lcden=0; rd=0; // fen=59; // miao=53; // shi=23; write_com(0x38); write_com(0x0c); write_com(0x06); write_com(0x01); write_com(0x80); for(num=0;num<15;num++) { write_data(table[num]); delay(5); } write_com(0x80+0x40); for(num=0;num<11;num++) { write_data(table1[num]); delay(5); } TMOD=0x01; TH0=0x4c; TL0=0x00; EA=1; ET0=1; TR0=1; } void write_sfm(uchar add,uchar date) { uchar shi,ge; shi=date/10; ge=date%10; write_com(0x80+0x40+add); write_data(0x30+shi); write_data(0x30+ge);; } void keyscan() { rd=0; if(s1==0) { delay(5); if(s1==0) { s1num++; while(!s1); if(s1num==1) { TR0=0; write_com(0x80+0x40+10); write_com(0x0f); } } if(s1num==2) { write_com(0x80+0x40+7); } if(s1num==3) { write_com(0x80+0x40+4); } if(s1num==4) { s1num=0; write_com(0x0c); TR0=1; } } if(s1num!=0) { if(s2==0) { delay(5); if(s2==0) { while(!s2); if(s1num==1) { miao++; if(miao==60) miao=0; write_sfm(10,miao); write_com(0x80+0x40+10); } if(s1num==2) { fen++; if(fen==60) fen=0; write_sfm(7,fen); write_com(0x80+0x40+7); } if(s1num==3) { shi++; if(shi==24) shi=0; write_sfm(4,shi); write_com(0x80+0x40+4); } } } if(s3==0) { delay(5); if(s3==0) { while(!s3); if(s1num==1) { miao--; if(miao==-1) miao=59; write_sfm(10,miao); write_com(0x80+0x40+10); } if(s1num==2) { fen--; if(fen==-1) fen=59; write_sfm(7,fen); write_com(0x80+0x40+7); } if(s1num==3) { shi--; if(shi==-1) shi=23; write_sfm(4,shi); write_com(0x80+0x40+4); } } } } } void main() { init(); while(1) { keyscan(); } } void timer0() interrupt 1 { TH0=0x4c; TL0=0X00; count++; if(count==18) { count=0; miao++; if(miao==60) { miao=0; fen++; if(fen==60) { fen=0; shi++; if(shi==24) { shi=0; } write_sfm(4,shi); } write_sfm(7,fen); } write_sfm(10,miao); } }
|