4.3.5练习提升
1、固定使用2位数码管显示60s倒计时,高位数码管熄灭。
2、数码管最高位显示固定字符U,固定使用2位数码管显示60s倒计时,高位数码管熄灭。倒计时结束5s后,重新开始 倒计时。计时过程中指示灯L1点亮,L2熄灭,计时结束后L1熄灭,L2以0.1s为间隔切换亮灭状态。其余指示灯均处于 熄灭状态。
![实例要求](https://i-blog.csdnimg.cn/direct/620de66d95e94ea88067f8ef5891c1fa.png#pic_center)
#include "stc15f2k60s2.h"
#include "intrins.h"
typedef unsigned char uint8_t;
uint8_t Led2Info = 0xFD;
uint8_t ledInfo;
uint8_t basicTimerCounter = 0;
uint8_t Sec1TimerCounter = 0;
uint8_t sec5GapTimerCounter = 0;
uint8_t boolCounterDot1s = 0;
uint8_t boolCounter1s = 0;
uint8_t boolCounter5sGap = 0;
uint8_t secStatus = 0;
uint8_t countDownStatus = 0;
#define lightLED(x) \
{ \
P2 = P2 & 0x1f | 0x80; \
P0 = x; \
P2 &= 0x1f; \
}
#define lightSEG(x) \
{ \
P0 = x; \
P2 = P2 & 0x1f | 0xe0; \
P2 &= 0x1f; \
}
#define lightCOM(x) \
{ \
P0 = x; \
P2 = P2 & 0x1f | 0xc0; \
P2 &= 0x1f; \
}
#define Buzz(x) \
{ \
P0 = x; \
P2 = P2 & 0x1F | 0xA0; \
P2 &= 0x1F; \
}
#define L1 0xFE
#define L2 0xFD
code unsigned char Seg_Table[] =
{
0xc0,
0xf9,
0xa4,
0xb0,
0x99,
0x92,
0x82,
0xf8,
0x80,
0x90,
0x88,
0x83,
0xc6,
0xa1,
0x86,
0x8e,
0xc1,
0xff
};
void Timer0_Init(void)
{
AUXR |= 0x80;
TMOD &= 0xF0;
TL0 = 0xA0;
TH0 = 0x15;
TF0 = 0;
TR0 = 1;
ET0 = 1;
EA = 1;
}
void Delay1ms()
{
unsigned char i, j;
i = 2;
j = 239;
do
{
while (--j)
;
} while (--i);
}
void lightL1()
{
lightLED(L1);
}
uint8_t blinkStatus;
void blinkL2()
{
ledInfo = Led2Info;
switch (blinkStatus)
{
case 0:
if (boolCounterDot1s)
{
lightLED(ledInfo);
blinkStatus = 1;
boolCounterDot1s = 0;
}
break;
case 1:
if (boolCounterDot1s)
{
ledInfo ^= ~Led2Info;
lightLED(ledInfo);
blinkStatus = 0;
boolCounterDot1s = 0;
}
break;
default:
blinkStatus = 0;
break;
}
}
void showU()
{
lightCOM(0x01);
lightSEG(Seg_Table[16]);
Delay1ms();
Delay1ms();
}
void showSec10(uint8_t sec10)
{
lightCOM(0x40);
lightSEG(Seg_Table[sec10]);
Delay1ms();
}
void showSec1(uint8_t sec1)
{
lightCOM(0x80);
lightSEG(Seg_Table[sec1]);
Delay1ms();
}
void showSeconds(uint8_t seconds)
{
switch (secStatus)
{
case 0:
showU();
lightL1();
secStatus = 1;
break;
case 1:
showSec10(seconds / 10);
secStatus = 2;
break;
case 2:
showSec1(seconds % 10);
secStatus = 0;
break;
default:
secStatus = 0;
break;
}
}
void secCountDown(uint8_t seconds)
{
switch (countDownStatus)
{
case 0:
while (1)
{
showSeconds(seconds);
if (boolCounter1s)
{
seconds--;
boolCounter1s = 0;
if (seconds == -1)
break;
}
}
countDownStatus = 1;
boolCounter5sGap = 0;
break;
case 1:
if (!boolCounter5sGap)
{
showU();
blinkL2();
}
else
{
countDownStatus = 0;
}
break;
}
}
void main()
{
Timer0_Init();
lightLED(0xff);
while (1)
{
secCountDown(60);
}
}
void Timer0_Isr(void) interrupt 1
{
if (basicTimerCounter++ == 20)
{
basicTimerCounter = 0;
boolCounterDot1s = 1;
if (Sec1TimerCounter++ == 10)
{
Sec1TimerCounter = 0;
boolCounter1s = 1;
if (sec5GapTimerCounter++ == 6)
{
sec5GapTimerCounter = 0;
boolCounter5sGap = 1;
}
}
}
}