网络上的大多数例程序只有倒计时秒 , 一眼就看不出还剩多少时间,所以考试计时器不实用。
所以,写一个 分钟,秒分离版,方便考生时间控制。
/*================================================================== 编写时间: 2022.04.21 设计目标: 四个共阴极数码管, 前两个是分钟,后两个是秒。 设定时间为90分钟,开机后开始倒计时。 硬件电路设计: 使用4个数字管NPN三极管驱动,基极通过1K电阻连接STC89C51的 P1.0-P1.4 口。集电极接数码管阴极,发射极共地。 数字管数据位分别通过电阻限流STC89C51的P0口连接。 单片机晶振11.0592Mhz。 软件逻辑设计: 1.利用T0中断函数,计数到200次,发送1秒标志Flage, 2.数字管驱动函数(LedDriver)在接收到 Flage倒计时计算后,将数据传输给显示函数(LedShow)。 3.显示函数(LedShow)接收时间数据后,将数据分离并写入数字管缓存。 4.数字管刷新函数(LedScan)使用数字管缓存数据刷新动态显示。 Others You Need To Know: 确保准确性, 机器周期除去的最小值5ms 得出TMOD 16位寄存器的初始值:60928 设定值:0xEE00; ================================================================*/ #include<reg52.h> //头文件配置寄存器。 sbit LEDS1 = P1 ^ 0; sbit LEDS2 = P1 ^ 1; sbit LEDS3 = P1 ^ 2; sbit LEDS4 = P1 ^ 3; unsigned int Tcount = 5400; //时间计数 设定90分钟 5400秒 bit Flage = 0; unsigned char code LedChar[] = {0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71}; unsigned char LedBuf[] = {0x00, 0x00, 0x00, 0x00}; void LedCharDriver(); void LedScan(); void LedShow(unsigned int i); void main() { /*====================== 初始数码管 =======================*/ LEDS1 = 0; LEDS2 = 0; LEDS3 = 0; LEDS4 = 0; /*======================= 配置定时器 ========================*/ EA = 1; TMOD = 0x01; TH0 = 0xEE; TL0 = 0x00; ET0 = 1; TR0 = 1; while(1) { LedCharDriver(); } } /*================================== 数码管驱动函数,倒计时,传递数据 ===================================*/ void LedCharDriver() { if(Flage == 1) { Flage = 0; Tcount--; if(Tcount <= 0) //设定时间90分钟, 5400秒。 { Tcount = 5400; } LedShow(Tcount); ///将剩余时间传输到显示函数 } } /*============================================ 数字管显示函数,递数据分离并写入缓存LedBuf中 =============================================*/ void LedShow(unsigned int i) { unsigned char j, k; unsigned char min = 0; unsigned char sec = 0; min = i / 60; sec = i % 60; for(j = 0; j < 2; j ) { LedBuf[j] = LedChar[sec % 10]; sec = sec / 10; } for(k = 2; k < 4; k ) { LedBuf[k] = LedChar[min % 10]; min = min / 10; } } /*================================== 动态刷新数字管,带消隐 ==================================*/ void LedScan() { static unsigned char i = 0; P0 = 0x00; switch (i) { case 0: LEDS4 = 0; LEDS1 = 1; i ; P0 = LedBuf[0]; break; case 1: LEDS1 = 0; LEDS2 = 1; i ; P0 = LedBuf[1]; break; case 2: LEDS2 = 0; LEDS3 = 1; i ; P0 = LedBuf[2]; break; case 3: LEDS3 = 0; LEDS4 = 1; i=0; P0 = LedBuf[3]; break; default : break; } } /*================================= 中断函数,用于计时,同时刷新数码管 ===================================*/ void InterruputTimer0() interrupt 1 { static unsigned char cnt = 0; TH0 = 0xEE; TL0 = 0x00; cnt ; if(cnt >= 200) { cnt = 0; Flage = 1; } LedScan(); }