串口通信控制AT89C52数码管和8个led灯代码
时间: 2024-02-12 21:04:44 浏览: 133
89C52+数码管完整代码
好的,以下是使用AT89C52单片机进行串口通信控制数码管和8个LED灯的代码:
```
#include <reg52.h>
#define FOSC 11059200L // 定义晶振频率
#define BAUD 9600 // 定义波特率
#define TIMER_1MS 1 // 定义1ms定时器的计数值
unsigned char ledData = 0; // 定义用于存储LED灯状态的变量
unsigned char numData = 0; // 定义用于存储数码管显示的数字的变量
void initUart() {
TMOD |= 0x20; // 设置定时器1为8位自动重装模式
SCON = 0x50; // 设置串口为工作模式1(8位数据,无奇偶校验,1位停止位)
TH1 = TL1 = -(FOSC / 12 / 32 / BAUD); // 计算波特率重装值
TR1 = 1; // 启动定时器1
ES = 1; // 开启串口中断
EA = 1; // 开启总中断
}
void initTimer() {
TMOD |= 0x01; // 设置定时器0为16位定时模式
TH0 = (65536 - FOSC / 12 / 1000) / 256; // 计算1ms定时器的重载值
TL0 = (65536 - FOSC / 12 / 1000) % 256;
ET0 = 1; // 开启定时器0中断
TR0 = 1; // 启动定时器0
}
void sendUart(unsigned char dat) {
SBUF = dat; // 发送数据
while(!TI); // 等待发送完成
TI = 0; // 清除发送完成标志位
}
void main() {
initUart(); // 初始化串口
initTimer(); // 初始化定时器
while(1) {
sendUart(numData); // 发送数码管数据
sendUart(ledData); // 发送LED灯数据
}
}
void timer0() interrupt 1 {
static unsigned char cnt = TIMER_1MS;
TH0 = (65536 - FOSC / 12 / 1000) / 256; // 重新设置定时器0的重载值和计数值
TL0 = (65536 - FOSC / 12 / 1000) % 256;
if (--cnt == 0) {
cnt = TIMER_1MS; // 计数器清零
numData++; // 数码管数据加1
ledData++; // LED灯数据加1
}
}
void uart() interrupt 4 {
unsigned char dat;
if (RI) { // 判断是否接收到数据
dat = SBUF; // 读取接收到的数据
RI = 0; // 清除接收标志位
switch (dat) {
case '0': // 接收到0,将LED灯状态清零
ledData = 0;
break;
case '1': // 接收到1,将LED灯状态设置为0xFF
ledData = 0xFF;
break;
default: // 接收到其他数据,不做处理
break;
}
}
}
```
以上代码中,使用定时器0实现了1ms的定时器中断,并在定时器中断中更新数码管和LED灯的状态数据。同时,使用串口中断实现了接收上位机发送的控制命令。当接收到字符'0'时,将LED灯状态清零;当接收到字符'1'时,将LED灯状态设置为0xFF。程序通过串口不断发送数码管和LED灯的状态数据,以实现与上位机的通信。
阅读全文