原理图如下所示: 源程序: #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}; //数码管位选 uchar code smg_code[]={0xC0,0xF9,0xA4,0xB0,0x99,0x92,0x82,0xF8,0x80,0x90,0x88,0x83,0x0C6,0x0A1,0x86,0x08E,0xff}; //数码管段选 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) //延时函数 { 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() //数码管显示闪 { 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() //数码管显示不闪 { 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(); } } } } 压缩包所含文件如下所示;
|