A. 該資源為基于51單片機的電子時鐘,具有仿真圖和程序源碼; B. 由數碼管作為顯示器,三個按鍵可以設置時間。 資源包內包括仿真
#include <reg51.h> #define uchar unsigned char uchar code tab[12]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90,0xff,0xbf}; //共陽極數碼管顯示"0~9","滅"和"-"的字段碼 //uchar code tab[]={0x3f,0x06,05b,0x4f,0x66,0x6d,07d,0x07,0x7f,0x6f,0x00,0x40};//共陰數碼管 uchar code wetab[8]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80}; //位選 uchar data dis[8]={0x00,0x00,0x0b,0x00,0x00,0x0b,0x00,0x00}; //顯示數據緩沖區,時十、個位、分十、個位、秒十、個位初始為0,0x0b為"-"編碼 uchar data timedat[3]={0x00,0x00,0x00}; //分別為秒、分和小時的計數值(記錄K1和K2次數) uchar data ms50=0x00, num=0x00, n1=0x00, n2=0x00; //定義定時次數變量,調整模式變量,按加1鍵次數變量,按減1鍵次數變量 sbit key0=P1^0 ; //調整鍵--模式 sbit key1=P1^1 ; //加1鍵 sbit key2=P1^2 ; //減1鍵 //--------------------------------------- void delay1ms( unsigned int z ) //定義延時1ms函數 { unsigned int x, y ; for ( x=z; x>0; x-- ) for ( y=120; y>0 ; y-- ) ; } //--------------------------------------- //按鍵處理函數。如果沒有按鍵則時鐘正常走時。當按K0鍵1次→暫停走時進入調小時狀態;再按K0鍵1次→進入調分鐘狀態;再按K0鍵1次→回到正常走時狀態。對于K1和K2鍵,如果正常走時下→按K1K2鍵不起作用;如果進入調時或者調分狀態→按K1鍵可對時或分加1操作,小時加到24則回0,分鐘加到60則回0。按K2鍵可對時或分減1操作,小時減到負則回23,分鐘減到負則回59。 void keyscan( void ) { EA=0; //關中斷 if(timedat[0]==0&timedat[1]==0&timedat[2]==7) {P1=0xff;} if (key0==0) { delay1ms(10); while (key0==0); num++; TR0=0; ET0=0; // 調整鍵K0每按1次--模式變量num加1 if (num>=3) {num=0; ET0=1; TR0=1; } // 啟動T0校時 } if (num!=0) //模式變量不等于0 { if (key1==0) // K1鍵確實按下 { delay1ms(10); while (key1==0); timedat[num]++; //記錄按鍵K1按下次數 if (num==2) n1=24; else n1=60; //模式變量等于小時2--則回遲到一天或60分鐘 if (timedat[num]>=n1) { timedat[num]=0; } } } if (num!=0) { if (key2==0) { delay1ms(10); while (key2==0); timedat[num]--; //記錄按鍵K2按下次數 if (num==2) n2=23;else n2=59; if (timedat[num]<=0) {timedat[num]=n2; } } } EA=1; } //--------------------------------------- //數碼管顯示函數。時間顯示先秒個位計算顯示→秒十位計算顯示→再分個位計算顯示→分十位顯示→再時個位計算顯示→時十位顯示。 void display( void ) { uchar k; if(timedat[0]==0&timedat[1]==0&timedat[2]==7) {P1=0xff;} dis[0]=timedat[0]%10; dis[1]=timedat[0]/10; //秒 dis[3]=timedat[1]%10; dis[4]=timedat[1]/10; //分 dis[6]=timedat[2]%10; dis[7]=timedat[2]/10; //時 for ( k=0; k<8; k++ ) { P0=tab[ dis[k] ]; P2=wetab[k]; delay1ms(1); P2=0x00; } } //--------------------------------------- //主函數,時間顯示先秒個位計算顯示,然后是秒十位計算顯示;再就是分個位計算顯示,然后是分十位顯示;再就是時個位計算顯示,然后是時十位顯示。定時器中斷先檢測1秒是否到→1秒如果到則秒單元加1;1秒如果沒到就檢測1分鐘是否到→1分鐘如果到則分單元加1;如果沒到就檢測1小時是否到→1小時如果到則時單元加1;如果沒到→則顯示時間。 void main( void ) { TMOD=0x01; //T0定時50ms,方式1 EA=1; ET0=1; TR0=1; //開中斷,允許T0中斷,啟動T0 TH0=0x3c; TL0=0xb0; while (1) { display( ) ; keyscan( ) ; } } //定時器/計數器T0中斷服務函數。定時器中斷先檢測1秒是否到→1秒如果到則秒單元加1;1秒如果沒到就檢測1分鐘是否到→1分鐘如果到則分單元加1;如果沒到就檢測1小時是否到→1小時如果到則時單元加1;如果沒到→則顯示時間。 void timer0(void) interrupt 1 { ET0=0; TR0=0; //不許T0中斷也不啟動 TH0=0x3c; TL0=0xb0; TR0=1; //啟動T0 ms50++; P1=0xf7; if(timedat[0]==0&timedat[1]==0&timedat[2]==7) {P1=0xff;} if (ms50==20) { ms50=0x00; timedat[0]++; //變量m回0,且秒加1 if (timedat[0]==60) { timedat[0]=0;timedat[1]++; //秒到60后回0,且分加1 if (timedat[1]==60) { timedat[1]=0;timedat[2]++; //分到60后回0,且時加1 if (timedat[2]==24) { timedat[2]=0; } } } //時到24后回0 } ET0=1; //允許T0中斷
}
|