由参考资料可知,问题出在同时使用了串口和定时器T0时,无法正常使用定时器T0,需要关闭串口中断即将ES=0。因此,解决该问题的具体步骤如下:
void Uart_Init(void)
{
PCON &= 0x7F;// SMOD=0:波特率不加倍
SCON = 0x50;// UART方式1:8位UART; REN=1:允许接收
TMOD |= 0x20;//T1方式2,八位自动重载,用于UART波特率
TL1 = 0xFD;
TH1 = 0xFD;// UART波特率设置:FDFD,9600;FFFF,57600
TR1 = 1; //启T1计数
ES = 0; //关闭串口中断
EA = 1;
}
void Timer0_Init()
{
TMOD |= 0x05; // 设置T0为16位计数模式
TH0 = 0x03; // 初始化高8位为3
TL0 = 0xE8; // 初始化低8位为0xE8,该值是65535-1000的值
ET0 = 1; // 允许定时器T0中断
TR0 = 1; // 启动定时器T0计数
EA = 1;
}
void DigitalDisplay()
{
show[0] = counter / 100; // 显示百位数
show[1] = (counter / 10) % 10; // 显示十位数
show[2] = counter % 10; // 显示个位数
P2 = 0x01;
P0 = Display[show[0]];
Delay(15);
P2 = 0x02;
P0 = Display[show[1]];
Delay(15);
P2 = 0x04;
P0 = Display[show[2]];
Delay(15);
}
完整代码如下:
#include <regx51.h>
#define uint unsigned int
sbit K = P3 ^ 4;
// 共阳极数码管0-F的字符码
unsigned char Display[] = {
0x3f, // '0'
0x06, // '1'
0x5b, // '2'
0x4f, // '3'
0x66, // '4'
0x6d, // '5'
0x7d, // '6'
0x07, // '7'
0x7f, // '8'
0x6f, // '9'
0x77, // 'A'
0x7c, // 'B'
0x39, // 'C'
0x5e, // 'D'
0x79, // 'E'
0x71 // 'F'
};
uint counter = 0; // 计数器
uint show[3] = {0, 0, 0}; // 显示数码管的值(百位、十位、个位)
void Delay(uint i)
{
while (i--)
;
}
void Uart_Init(void)
{
PCON &= 0x7F; // SMOD=0:波特率不加倍
SCON = 0x50; // UART方式1:8位UART; REN=1:允许接收
TMOD |= 0x20; //T1方式2,八位自动重载,用于UART波特率
TL1 = 0xFD;
TH1 = 0xFD; // UART波特率设置:FDFD,9600;FFFF,57600
TR1 = 1; //启T1计数
ES = 0; //关闭串口中断
EA = 1;
}
void Timer0_Init()
{
TMOD |= 0x05; // 设置T0为16位计数模式
TH0 = 0x03; // 初始化高8位为3
TL0 = 0xE8; // 初始化低8位为0xE8,该值是65535-1000的值
ET0 = 1; // 允许定时器T0中断
TR0 = 1; // 启动定时器T0计数
EA = 1;
}
// 计数器溢出时触发中断
void Timer0Interrupt() interrupt 1
{
TH0 = 0x03; // 初始化高8位为3
TL0 = 0xE8; // 初始化低8位为0xE8,该值是65535-1000的值
counter++; // 每次中断增加计数器的值
counter = counter % 1000; // 保证计数器不溢出,显示范围0~999
// 更新显示的值
show[0] = counter / 100; // 显示百位数
show[1] = (counter / 10) % 10; // 显示十位数
show[2] = counter % 10; // 显示个位数
}
void DigitalDisplay()
{
P2 = 0x01;
P0 = Display[show[0]];
Delay(15);
P2 = 0x02;
P0 = Display[show[1]];
Delay(15);
P2 = 0x04;
P0 = Display[show[2]];
Delay(15);
}
int main()
{
Uart_Init();
Timer0_Init();
while (1)
{
DigitalDisplay();
}
return 0;
}