第6章-中断与数码管动态显示
之前都是开胃菜,这回开始上重点了,难度也开始上来了






课后习题4
#include <reg52.h>
typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long ulong;
sbit ADDR0 = P1 ^ 0;
sbit ADDR1 = P1 ^ 1;
sbit ADDR2 = P1 ^ 2;
sbit ADDR3 = P1 ^ 3;
sbit ENLED = P1 ^ 4;
uchar code LedChar[] = {
0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E};
uchar LedBuff[6] = {0xFF, 0xC0, 0xC0, 0xC0, 0xC0, 0xC0};
bit flag1s = 0;
uint cnt = 0;
void main(void)
{
ulong sec = 980;
ENLED = 0; // 138总开关打开
ADDR3 = 1; // 选138高8路
TMOD = 0x01;
TH0 = 0xFC;
TL0 = 0x66;
TR0 = 1;
EA = ET0 = 1;
while (1)
{
if (flag1s == 1)
{
flag1s = 0;
sec++;
LedBuff[0] = LedChar[sec % 10];
LedBuff[1] = LedChar[sec / 10 % 10];
LedBuff[2] = LedChar[sec / 100 % 10];
LedBuff[3] = LedChar[sec / 1000 % 10];
LedBuff[4] = LedChar[sec / 10000 % 10];
LedBuff[5] = LedChar[sec / 100000 % 10];
}
}
}
void Timer0_ISR(void) interrupt 1
{
static char i = 5; // 从高位开始显示
static bit show = 0; // 1=显示;0=不显示,默认从高位开始不显示
TH0 = 0xFC; // 重装初值
TL0 = 0x66;
if (++cnt >= 200) // 判断1s到了,为了加快测试把1000改成了200
{
cnt = 0;
flag1s = 1;
}
P0 = 0xFF; // 消影,,,,,后面不显示的部分,也利用了这一次的赋值
switch (i)
{
case 0:
ADDR2 = 0;
ADDR1 = 0;
ADDR0 = 0;
i = 5;
P0 = LedBuff[0]; // 永远会显示
show = 0;
break;
case 1:
ADDR2 = 0;
ADDR1 = 0;
ADDR0 = 1;
i--;
if (show || (LedBuff[1] != LedChar[0]))
{
P0 = LedBuff[1];
show = 1;
}
break;
case 2:
ADDR2 = 0;
ADDR1 = 1;
ADDR0 = 0;
i--;
if (show || (LedBuff[2] != LedChar[0]))
{
P0 = LedBuff[2];
show = 1;
}
break;
case 3:
ADDR2 = 0;
ADDR1 = 1;
ADDR0 = 1;
i--;
if (show || (LedBuff[3] != LedChar[0]))
{
P0 = LedBuff[3];
show = 1;
}
break;
case 4:
ADDR2 = 1;
ADDR1 = 0;
ADDR0 = 0;
i--;
if (show || (LedBuff[4] != LedChar[0]))
{
P0 = LedBuff[4];
show = 1;
}
break;
case 5:
ADDR2 = 1;
ADDR1 = 0;
ADDR0 = 1;
i--;
if (LedBuff[5] != LedChar[0])
{
P0 = LedBuff[5];
show = 1;
}
break;
}
}
课后习题5
#include <reg52.h>
typedef unsigned char uchar;
typedef unsigned int uint;
typedef unsigned long ulong;
sbit ADDR0 = P1 ^ 0;
sbit ADDR1 = P1 ^ 1;
sbit ADDR2 = P1 ^ 2;
sbit ADDR3 = P1 ^ 3;
sbit ENLED = P1 ^ 4;
uchar code LedChar[] = {
0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8,
0x80, 0x90, 0x88, 0x83, 0xC6, 0xA1, 0x86, 0x8E};
uchar LedBuff[6] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90};
bit flag1s = 0;
uint cnt = 0;
void main(void)
{
ulong sec = 999999;
ENLED = 0; // 138总开关打开
ADDR3 = 1; // 选138高8路
TMOD = 0x10;
TH1 = 0xFC;
TL1 = 0x66;
TR1 = 1;
EA = ET1 = 1;
while (1)
{
if (flag1s == 1)
{
flag1s = 0;
sec--;
LedBuff[0] = LedChar[sec % 10];
LedBuff[1] = LedChar[sec / 10 % 10];
LedBuff[2] = LedChar[sec / 100 % 10];
LedBuff[3] = LedChar[sec / 1000 % 10];
LedBuff[4] = LedChar[sec / 10000 % 10];
LedBuff[5] = LedChar[sec / 100000 % 10];
}
}
}
void Timer1_ISR(void) interrupt 3
{
static char i = 0;
TH1 = 0xFC; // 重装初值
TL1 = 0x66;
if (++cnt >= 200) // 判断1s到了;为了加快测试把1000改成了200
{
cnt = 0;
flag1s = 1;
}
P0 = 0xFF; // 消影
switch (i)
{
case 0:
ADDR2 = 0;
ADDR1 = 0;
ADDR0 = 0;
i++;
P0 = LedBuff[0];
break;
case 1:
ADDR2 = 0;
ADDR1 = 0;
ADDR0 = 1;
i++;
P0 = LedBuff[1];
break;
case 2:
ADDR2 = 0;
ADDR1 = 1;
ADDR0 = 0;
i++;
P0 = LedBuff[2];
break;
case 3:
ADDR2 = 0;
ADDR1 = 1;
ADDR0 = 1;
i++;
P0 = LedBuff[3];
break;
case 4:
ADDR2 = 1;
ADDR1 = 0;
ADDR0 = 0;
i++;
P0 = LedBuff[4];
break;
case 5:
ADDR2 = 1;
ADDR1 = 0;
ADDR0 = 1;
i = 0;
P0 = LedBuff[5];
break;
}
}