用c51写一个串口通信,pc输入数字,单片机led数码管显示bcd码,用定时器1
时间: 2024-04-30 15:25:02 浏览: 111
c51单片机 ch452芯片 数码管显示 定时器
好的,下面是参考代码:
```C
#include <reg52.h> // 引入51单片机头文件
#define FOSC 11059200L // 定义晶振频率
#define BAUD 9600 // 定义波特率
#define TIMER1_MS 1 // 定义定时器1的中断时间(毫秒)
#define LED_DIGITS P0 // 数码管的控制端口
#define UART_RX P3_0 // 串口接收端口
#define UART_TX P3_1 // 串口发送端口
unsigned char code LED_MAP[] = { // 数码管显示的BCD码映射表
0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f
};
unsigned char data num = 0; // 存储从PC接收到的数字
void initUART() {
TMOD |= 0x20; // 配置定时器1为模式2(自动重载)
TH1 = 256 - FOSC / 12 / 32 / BAUD; // 计算定时器1的初值
TL1 = TH1; // 初始化定时器1的计数值
TR1 = 1; // 启动定时器1
REN = 1; // 允许串口接收
SM0 = 0; // 设置串口为模式1
SM1 = 1;
EA = 1; // 开启总中断
ES = 1; // 开启串口中断
}
void initTimer1() {
TMOD |= 0x10; // 配置定时器1为模式1(16位定时器)
TH1 = -(FOSC / 12 / 1000 * TIMER1_MS) / 256; // 计算定时器1的初值
TL1 = -(FOSC / 12 / 1000 * TIMER1_MS) % 256;
ET1 = 1; // 开启定时器1中断
}
void main() {
initUART(); // 初始化串口
initTimer1(); // 初始化定时器1
while (1) {
LED_DIGITS = LED_MAP[num]; // 在数码管上显示数字
}
}
void UART_ISR() interrupt 4 { // 串口中断服务程序
if (RI) { // 如果收到了数据
num = SBUF; // 保存收到的数字
RI = 0; // 重置接收标志位
}
if (TI) { // 如果发送缓冲区为空
TI = 0; // 重置发送标志位
}
}
void Timer1_ISR() interrupt 3 { // 定时器1中断服务程序
static unsigned int count = 0; // 计数器
TH1 = -(FOSC / 12 / 1000 * TIMER1_MS) / 256; // 重新设置定时器1的初值
TL1 = -(FOSC / 12 / 1000 * TIMER1_MS) % 256;
count++; // 计数器加1
if (count >= 1000 / TIMER1_MS) { // 如果计数器达到1秒
count = 0; // 重置计数器
num++; // 数字加1
if (num > 9) { // 如果数字已经到达9
num = 0; // 重置数字为0
}
}
}
```
上面的代码中,我们使用了定时器1来实现每隔1秒钟自动加1,并在数码管上显示出来。同时,我们也使用了串口接收PC发送的数字,并在数码管上显示出对应的BCD码。
阅读全文