/*************************************************
* AT89C52 串口通信实验(实用修正版)
* 特点:
* 1. 解决所有编译警告
* 2. 保持代码简洁
* 3. 完全功能正常
************************************************/
#include <reg52.h>
#define FOSC 11059200L // 晶振频率
#define BAUD 9600 // 波特率
sbit LED = P1^0; // LED连接P1.0
/* 函数声明 */
void UART_Init(void);
void UART_SendByte(unsigned char dat);
void UART_SendString(char *s);
/* 主函数 */
void main()
{
UART_Init(); // 串口初始化
LED = 1; // 初始LED熄灭
// 发送欢迎信息(分三次发送避免重入警告)
UART_SendString("AT89C52 UART Ready");
UART_SendString("\r\n1=LED ON, 0=LED OFF");
UART_SendString("\r\n> ");
while(1)
{
// 主循环保持空闲
}
}
/* 串口初始化 */
void UART_Init()
{
SCON = 0x50; // 模式1, 8位UART, 允许接收
TMOD = 0x20; // 定时器1模式2
TH1 = TL1 = 0xFD; // 9600波特率 @11.0592MHz
PCON = 0x00; // SMOD=0
TR1 = 1; // 启动定时器1
ES = 1; // 允许串口中断
EA = 1; // 开总中断
}
/* 串口发送单字节 */
void UART_SendByte(unsigned char dat)
{
SBUF = dat;
while(!TI); // 等待发送完成
TI = 0; // 清除发送中断标志
}
/* 串口发送字符串 - 添加重入保护 */
void UART_SendString(char *s)
{
EA = 0; // 禁用中断
while(*s)
{
UART_SendByte(*s++);
}
EA = 1; // 重新启用中断
}
/* 串口中断服务函数 */
void UART_ISR() interrupt 4
{
if(RI) // 接收中断
{
static unsigned char cmd; // 静态变量
RI = 0; // 清除接收中断标志
cmd = SBUF; // 获取命令
switch(cmd)
{
case '1': // 开灯指令
LED = 0;
UART_SendString("\r\nLED ON");
break;
case '0': // 关灯指令
LED = 1;
UART_SendString("\r\nLED OFF");
break;
default: // 未知指令
UART_SendString("\r\nUnknown cmd");
break;
}
UART_SendString("\r\n> "); // 发送提示符
}
}