原理圖如下所示:
原理圖
源程序: #include <reg52.h> #define uint unsigned int #define uchar unsigned char sbit led=P1^5; //定義led燈,每秒閃爍一次,當秒表使用。 sbit led1=P1^4; //定義led燈,每秒閃爍一次,當秒表使用。 sbit speaker= P1^6; //定義蜂鳴器 uchar smg_buf[]={0,0,0,0}; uchar code keycode_tab[]={0xee,0xed,0xeb,0xe7,0xde,0xdd,0xdb,0xd7,0xbe,0xbd,0xbb,0xb7,0x7e,0x7d,0x7b,0x77}; //鍵盤 uchar code smg_sel[]={0xf7,0xfb,0xfd,0xfe}; //數(shù)碼管位選 uchar code smg_code[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0x0C6,0x0A1,0x86,0x08E,0xff}; //數(shù)碼管段選 uchar n=0,keycode; uchar count=0; uint hour=0,min=0,second=0; uint T50ms=20; uint t_set=0; bit key_flag=0; void delay500us(unsigned char X) //延時函數(shù) { unsigned char i,j; for(i=X;i>0;i--) for(j=248;j>0;j--); } void timechange() //時間變量改變 { second++; if(second>59) { second=0; min++; if(min>59) { min=0; hour++; if(hour>23) hour=0; } } } void init_timer1() //設置T1工作方式1 定時器 50ms { TMOD=0x10; TH1=(65536-46083)/256; TL1=(65536-46083)%256; TR1=1; } void display() //數(shù)碼管顯示閃 { smg_buf[0]=hour/10; smg_buf[1]=hour%10; smg_buf[2]=min/10; smg_buf[3]=min%10; if(count==1) //LED閃爍,每秒閃爍一次,當秒表使用。 { P0|=0xfe; P2=smg_sel[count]; P0=smg_code[smg_buf[count]]; if(T50ms==1) led=0,led1=0; } If (count!=1) { P0=0xff; P2=smg_sel[count]; P0=smg_code[smg_buf[count]]; if(T50ms==11) led=1,led1=1; } count++; if(count==4) count=0; } void display1() //數(shù)碼管顯示不閃 { smg_buf[0]=hour/10; //小時十位 smg_buf[1]=hour%10; //小時各位 smg_buf[2]=min/10; //分鐘十位 smg_buf[3]=min%10; //分鐘各位 P0|=0xfe; P2=smg_sel[count]; P0=smg_code[smg_buf[count]]; led=1,led1=1; count++; if(count==4) count=0; } void keyscan() //識別鍵盤 { ucharkeycode_L,keycode_H,i; P3=0xf0; keycode_H=P3&0xf0; if(keycode_H!=0xf0) { delay500us(20); if(keycode_H!=0xf0) { //while(P3!=0xf0); keycode_H=P3&0xf0; } } P3=0x0f; keycode_L=P3&0x0f; if(keycode_L!=0x0f) { delay500us(20); if(keycode_L!=0x0f) { // while(P3!=0x0f); key_flag=1; //按下標志 keycode_L=P3&0x0f; } } keycode=keycode_H|keycode_L; P3=0xf0; while((P3&0XF0)!=0XF0); //判彈起 for(i=0;i<16;i++) { if(keycode==keycode_tab) n=i; } } void timer1_int() interrupt 3 //中斷計時 { TH1=(65536-46083)/256; //46083為50000的修正值 TL1=(65536-46083)%256; t_set++; T50ms--; if(T50ms==0) { timechange(); T50ms=20; } } void modmin() //調整分鐘 { while(t_set<100) { display1(); keyscan(); if(key_flag==1) { key_flag=0; t_set=0; if(n==14) { min++; if(min>59) { min=0; } } if(n==15) { if(min==0) { min=59; } else min--; } if(n==0|n==1|n==2|n==3|n==1|n==4|n==5|n==6|n==7|n==8|n==9) { smg_buf[2]=smg_buf[3]; smg_buf[3]=n; min=smg_buf[2]*10+n; if(min>59) min=0; } } } } void modhour() //調整小時 { while(t_set<100) { display1(); keyscan(); if(key_flag==1) { key_flag=0; t_set=0; if(n==14) { hour++; if(hour>23) { hour=0; } } if(n==15) { if(hour==0) { hour=23; } else hour--; } if(n==0|n==1|n==2|n==3|n==1|n==4|n==5|n==6|n==7|n==8|n==9) { smg_buf[0]=smg_buf[1]; smg_buf[1]=n; hour=smg_buf[0]*10+n; if(hour>23) { hour=0; } } } } } void main() { init_timer1(); T50ms=20; ET1=1; EA=1; while(1) { if(min==0&&second<2) {speaker=0; delay500us(1850);speaker=1;delay500us(1); } //整點提示,蜂鳴器響2秒 if(min==30&&second<0.5) {speaker=0;delay500us(1850); speaker=1;delay500us(1); } //半點提示,蜂鳴器響0.5秒 display(); keyscan(); t_set=0; if(key_flag==1) { t_set=0; key_flag=0; if(n==11) { modmin(); } if(n==10) { modhour(); } } } } 壓縮包所含文件如下所示;
壓縮包所含文件
|