这个首先列一个框架。
- 首先头文件,main函数,数码管段码的定义,HC138(或573)部分的代码以及分配S4S5的地址都是我们通过看题后立马就能知道要用到的东西。以及我们在第二步时会注意到这个地方要求我们根据分-秒-毫秒的格式显示,所以还需要定义三个变量,使其每一次定时后数值都能够变化。
#include <REGX52.H> sbit S4 = P3^3; sbit S5 = P3^2; unsigned char code smgduanma[18]={ 0xC0,0xF9,0xA4,0xB0,0x99,0x92, 0x82,0xF8,0x80,0x90,0x88,0x80, 0xc6,0xc0,0x86,0x8e,0xbf,0x7f }; unsigned char t_fen=0; unsigned char t_s=0; unsigned char t_ms=0; void SELECT_HC138(unsigned char n) { switch(n) { case 4: P2=(P2&0x1f)|0x80; break; case 5: P2=(P2&0x1f)|0xa0; break; case 6: P2=(P2&0x1f)|0xc0; break; case 7: P2=(P2&0x1f)|0xe0; break; } } void main() { while(1) { } }
- 需要数码管显示,所以要有Display函数,通过pos位置和显示值value控制。以及调用Display函数用于显示时间的函数DisplayTime。
void Display(unsigned char value,unsigned char pos) { SELECT_HC138(6); P0 = 0x01 << pos; SELECT_HC138(7); P0 = value; }
void DisplayTime() { Display(smgduanma[t_ms/10],6); Delay(500); Display(smgduanma[t_ms%10],7); Delay(500); Display(smgduanma[16],5); Delay(500); Display(smgduanma[t_s/10],3); Delay(500); Display(smgduanma[t_s%10],4); Delay(500); Display(smgduanma[16],2); Delay(500); Display(smgduanma[t_fen/10],0); Delay(500); Display(smgduanma[t_fen%10],1); Delay(500); }
- 需要独立按键部分,所以要编写一个ScanKey函数实现当S4S5按下时要做的操作。
void ScanKey() { if(S4==0)//秒表暂停/启动 { Delay(100); if(S4==0) { TR0=~TR0; while(S4==0) { DisplayTime(); } } } if(S5 == 0)//秒表清零 { Delay(100); if(S5==0) { t_ms=0; t_s=0; t_fen=0; while(S5==0) { DisplayTime(); } } } }
- 需要定时器模块,这里分为两个函数,一个是初始化函数InitTimer,另一个是中断服务函数SeverTimer0。
void initTimer() { TMOD=0X01; TH0 = (65535 - 50000) / 256; TL0 = (65535 - 50000) % 256; ET0=1; EA=1; TR0=1; } void ServiceTimer0() interrupt 1 { TH0 = (65535 - 50000) / 256; TL0 = (65535 - 50000) % 256; t_ms++; if(t_ms == 20) { t_s++; t_ms = 0; if(t_s == 60) { t_fen++; t_s = 0; } if(t_fen == 99) { t_fen=0; } } }
- 将这些函数放到main函数里循环。
void main() { initTimer(); while(1) { DisplayTime(); ScanKey(); } }