項(xiàng)目:簡(jiǎn)單的時(shí)鐘(2015-2-23)
設(shè)計(jì)要求:帶冒號(hào)的4位數(shù)碼管顯示時(shí)間(MT05643DR)、按鍵設(shè)置時(shí)間


分析:本例是簡(jiǎn)單的時(shí)鐘,因此采用單片機(jī)定時(shí)器提供時(shí)鐘源。時(shí)間設(shè)置采用按鍵調(diào)節(jié),用兩個(gè)按鍵,一個(gè)負(fù)責(zé)小時(shí)的增加設(shè)置,另一個(gè)負(fù)責(zé)分鐘的增加。
單片機(jī)用STC12C2052AD20腳,晶振采用12M。
引腳分配:P1.0----P1.7 a b c d e f g :
P3.0 按鍵1 數(shù)碼管小時(shí)加1按鍵 P3.1 按鍵2 數(shù)碼管上分鐘加1設(shè)置按鍵 P3.2----P3.5 4位數(shù)碼管 程序流程:
- #include <reg52.h>
- sbit Key1=P3^0; //定義2個(gè)按鍵用于調(diào)整時(shí)間
- sbit Key2=P3^1;
- sbit Wei1=P3^2; //四位數(shù)碼管定義端口
- sbit Wei2=P3^3; //
- sbit Wei3=P3^4;
- sbit Wei4=P3^5;
-
- unsigned char code LEDchar[]={
- 0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90}; //數(shù)碼管0-9真值表
- unsigned charLedBuff[4]={0xff,0xff,0xff,0xff}; //4位數(shù)碼管顯示數(shù)字緩存
- unsigned int ms=0;//定義毫秒全局變量
- unsigned char miao=0,fen=59,shi=23;//秒,分,時(shí) 全局變量
- bit keyst1=1;
- bit keyst2=1;
- bit backup1=1;
- bit backup2=1;
- void Time0int()//
- {
- TMOD=0x01; //定時(shí)模式1,16位定時(shí)器
- TH0=0xF8;//初值計(jì)算公式 65536-(定時(shí)時(shí)間(2ms=2000us)/1us(晶振12M的計(jì)數(shù)周期時(shí)間))=63536
- TL0=0x30;//63536轉(zhuǎn)換為16進(jìn)制為 F830H 分配給定時(shí)器TH0 TL0 就可以了
- EA=1;//開(kāi)總中斷
- ET0=1;//打開(kāi)定時(shí)器0中斷
- TR0=1;//定時(shí)器0開(kāi)始運(yùn)行
- }
-
- void ShowNumber(unsigned int num) //顯示數(shù)字函數(shù),參數(shù)是1個(gè)短整形的數(shù)字num
- {
- signedchar i; //定義變量i用于循環(huán)數(shù)的位數(shù)
- unsignedchar buf[4]; //定義一個(gè)數(shù)組用于保存分離出來(lái)各位的數(shù)據(jù)
-
- for(i=0;i<4; i++)
- {
- buf[i]= num % 10;
- num= num / 10;
- } //上面2個(gè)語(yǔ)句就是循環(huán)4次,把1個(gè)4位數(shù)進(jìn)行按位分離后存放在數(shù)組buf中
-
- for(i=3;i>=1; i--) //進(jìn)行首位是零,不顯示
- {
- if(buf[i]== 0) //如果首位是零,則把數(shù)碼管顯示緩存數(shù)據(jù)為0XFF,由于是共陽(yáng)極數(shù)碼管,如果數(shù)據(jù)是0xff 則數(shù)碼管不顯示
- {
- LedBuff[i]= 0xFF;
- }
- else //如果首位不是零,則跳出循環(huán)
- break;
- }
-
- for(;i>=0; i--) //i繼承了上面語(yǔ)句的數(shù)值,把該位的數(shù)字通過(guò)Ledchar[buf[i]]數(shù)組,進(jìn)行轉(zhuǎn)換為該數(shù)字的顯示數(shù)據(jù)并賦值給數(shù)碼管顯示緩存
- {
- LedBuff[i]= LEDchar[buf[i]];
- }
-
- }
-
- unsigned int num(unsigned charhour,unsigned char minute) //2個(gè)8位數(shù)據(jù)類型變量,合并連接為16位數(shù)據(jù)來(lái)信變量
- {
- unsignedint date;
- date=100*hour+minute;
- returndate;
- }
-
- void main()
- {
- P1=LEDchar[0];
- Time0int();//定時(shí)器初始化
- while(1)
- {
- ShowNumber(num(shi,fen));
- if(keyst1!=backup1)
- {
- if(keyst1==0)
- {
- shi++;
- }
- backup1=Key1;
- }
- if(keyst2!=backup2)
- {
- if(keyst2==0)
- {
- fen++;
- }
- backup2=Key2;
- }
- }
-
- }
-
- void interruptTimer0() interrupt 1
- {
- staticunsigned char i;
- staticunsigned char keybuf1=0xff;
- staticunsigned char keybuf2=0xff;
- TH0=0xf8; //定時(shí)器初值重新賦值
- TL0=0x30;
- ms++; //利用2毫秒定時(shí)器中斷來(lái)進(jìn)行時(shí)間的累計(jì)并把累計(jì)次數(shù)賦值給時(shí)間變量
- if(ms>=500)
- {
- ms=0;
- miao++;
- }
- if(miao>=60)
- {
- miao=0;
- fen++;
- }
- if(fen>=60)
- {
- fen=0;
- shi++;
- }
- if(shi>=24)
- {
- shi=0;
- }
- switch(i)//每次進(jìn)入中斷進(jìn)行1位數(shù)碼管的顯示刷新,5次耗時(shí)10ms
- {
- case0: Wei4=1;Wei3=1;Wei1=0;i++;P1=LedBuff[3];break;
- case1: Wei1=1;Wei2=0;i++;P1=LedBuff[2];break;
- case 2:Wei2=1;Wei3=0;i++;P1=LedBuff[1];break;
- case3: Wei3=1;Wei4=0;i++;P1=LedBuff[0];break;
- case4:
- {
- Wei3=0;i=0;
- if(ms<=250)
- P1=0x7F; //顯示數(shù)碼管上的冒號(hào)
- else
- P1=0xff; //關(guān)閉冒號(hào)
- break;
- }
- default:break;
- }
- keybuf1=(keybuf1<<1)|Key1; //按鍵掃描利用中斷每2ms檢測(cè)1次按鍵狀態(tài),把狀態(tài)值放入keybuf變量中
- if(keybuf1==0x00) //經(jīng)過(guò)8次中斷,如果keybuf變量時(shí)0x00,則按鍵為按下?tīng)顟B(tài),
- keyst1=0;
- elseif(keybuf1==0xff) //經(jīng)過(guò)8次中斷,如果keybuf變量時(shí)0xff,則按鍵為彈起狀態(tài),
- keyst1=1;
- keybuf2=(keybuf2<<1)|Key2;
- if(keybuf2==0x00)
- keyst2=0;
- elseif(keybuf2==0xff)
- keyst2=1;
-
- }
復(fù)制代碼

|