/*************************************************
?* 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> "); // 發送提示符
? ? }
}