基于51单片机的串口(RS232+485)通信程序设计

张开发
2026/4/21 20:46:09 15 分钟阅读

分享文章

基于51单片机的串口(RS232+485)通信程序设计
一、系统概述基于STC89C52RC单片机8位11.0592MHz晶振实现RS232全双工通信与RS485半双工通信双模式。系统通过UART串口连接MAX232RS232电平转换和MAX485RS485差分转换支持双机通信点对点与总线通信多点具备数据收发、帧格式自定义、收发切换控制功能适用于工业控制、仪器仪表通信等场景。二、硬件设计2.1 核心组件选型模块型号/参数功能说明主控STC89C52RC8KB Flash512B RAMUART通信控制、RS232/RS485模式切换RS232转换MAX232电荷泵电平转换将单片机TTL电平0~5V转换为RS232电平±12VRS485转换MAX485差分收发器将TTL电平转换为RS485差分信号A/B线通信接口DB9RS232、凤凰端子RS485连接PC或工业总线设备2.2 硬件连接图------------------- ------------------- ------------------- | STC89C52RC | | MAX232 | | PC/RS232设备 | | P3.1(TXD) → MAX232|T1IN | T1OUT → DB9-2(RXD) | | DB9-3(TXD) → MAX232|R1IN | | P3.0(RXD) ← MAX232|R1OUT | R1IN ← DB9-3(TXD) | | DB9-2(RXD) ← MAX232|T1OUT | | P3.2(CTRL) → MAX485|DE/RE | | ------------------- | P3.1(TXD) → MAX485|DI | | ------------------- | P3.0(RXD) ← MAX485|RO | | | MAX485总线 | ------------------- ------------------- | A/B线 → 其他节点 | -------------------关键引脚说明MAX232T1IN接单片机TXD、R1OUT接单片机RXD实现RS232电平转换。MAX485DI接单片机TXD发送数据、RO接单片机RXD接收数据、DE/RE方向控制高电平发送低电平接收由单片机P3.2引脚控制。三、软件设计Keil C513.1 开发环境IDEKeil μVision5C51编译器晶振11.0592MHz确保波特率误差1%通信协议8位数据位、1位停止位、无校验位8N1波特率9600bps3.2 核心原理UART初始化配置定时器1为模式28位自动重装作为波特率发生器计算TH1初值11.0592MHz下9600bps对应TH10xFD。RS232通信全双工模式直接通过TXD/RXD收发数据无需方向控制。RS485通信半双工模式发送前置DE/RE1发送模式发送完毕后置DE/RE0接收模式避免总线冲突。3.3 核心代码实现3.3.1 头文件与全局变量#includereg52.h#includeintrins.h// 引脚定义 #defineRS485_DE_REP3_2// RS485方向控制引脚高发送低接收#defineUART_RX_BUF_SIZE16// 接收缓冲区大小#defineUART_TX_BUF_SIZE16// 发送缓冲区大小// 全局变量 unsignedcharuart_rx_buf[UART_RX_BUF_SIZE];// 接收缓冲区unsignedcharuart_tx_buf[UART_TX_BUF_SIZE];// 发送缓冲区unsignedcharrx_cnt0;// 接收计数unsignedchartx_cnt0;// 发送计数bit rx_flag0;// 接收完成标志1接收一帧完成3.3.2 UART初始化定时器1波特率发生器// UART初始化9600bps8N1voidUART_Init(){SCON0x50;// 模式18位UART允许接收REN1TMOD|0x20;// 定时器1模式28位自动重装TH10xFD;// 波特率9600bps11.0592MHz(2^SMOD/32)*(fosc/(12*(256-TH1))) → SMOD0时TH12530xFDTL10xFD;TR11;// 启动定时器1ES1;// 允许串口中断EA1;// 开总中断}3.3.3 RS232发送函数查询模式// RS232发送一个字节voidRS232_SendByte(unsignedchardat){SBUFdat;// 数据写入发送缓冲区while(!TI);// 等待发送完成TI1TI0;// 清除发送中断标志}// RS232发送字符串voidRS232_SendString(unsignedchar*str){while(*str!\0){RS232_SendByte(*str);}}3.3.4 RS485发送函数含方向控制// RS485发送一个字节voidRS485_SendByte(unsignedchardat){RS485_DE_RE1;// 置高电平切换到发送模式DelayUs(10);// 延时10μs确保方向切换完成关键SBUFdat;// 发送数据while(!TI);// 等待发送完成TI0;DelayUs(10);// 延时10μs确保最后一个字节发送完成RS485_DE_RE0;// 置低电平切换到接收模式}// RS485发送字符串voidRS485_SendString(unsignedchar*str){RS485_DE_RE1;// 发送模式DelayUs(10);while(*str!\0){SBUF*str;while(!TI);TI0;}DelayUs(10);RS485_DE_RE0;// 接收模式}3.3.5 串口中断服务函数接收数据// 串口中断接收数据voidUART_ISR()interrupt4{if(RI){// 接收中断标志RI0;// 清除接收标志uart_rx_buf[rx_cnt]SBUF;// 存入接收缓冲区if(rx_cntUART_RX_BUF_SIZE)rx_cnt0;// 缓冲区溢出保护if(SBUF\n)rx_flag1;// 检测到换行符标记接收完成可自定义帧尾}}3.3.6 延时函数微秒级// 微秒延时11.0592MHz晶振1μs≈12个机器周期voidDelayUs(unsignedintus){while(us--){_nop_();_nop_();_nop_();_nop_();// 4个_nop_≈1μs误差±1μs_nop_();_nop_();_nop_();_nop_();}}3.3.7 主函数测试逻辑voidmain(){UART_Init();// 初始化UARTRS485_DE_RE0;// 初始为接收模式RS485while(1){// 示例1RS232接收PC数据并回传Echoif(rx_flag){rx_flag0;RS232_SendString(RS232 Recv: );RS232_SendString(uart_rx_buf);// 回传接收数据rx_cnt0;// 清空缓冲区}// 示例2RS485定时发送数据每2秒发送一次staticunsignedinttimer0;if(timer2000){// 2秒假设主循环1ms一次timer0;RS485_SendString(RS485 Test: Hello!\r\n);// 发送测试字符串}DelayMs(1);// 主循环延时1ms需实现DelayMs函数}}// 毫秒延时粗略voidDelayMs(unsignedintms){unsignedinti,j;for(i0;ims;i)for(j0;j110;j);// 110次循环≈1ms11.0592MHz}参考代码 基于51单片机的串口RS232485通信程序www.youwenfan.com/contentcst/182671.html四、关键问题与解决方案4.1 波特率误差问题51单片机定时器1重载值计算错误导致波特率偏差如12MHz晶振下9600bps误差大。解决使用11.0592MHz晶振可被1.8432MHz整除波特率误差为0计算公式TH1256−fosc12×32×波特率TH1256−\frac{fosc}{12×32×波特率}TH1256−12×32×波特率fosc​9600bps时TH1256 - 11059200/(12×32×9600)256-32530xFD。4.2 RS485收发冲突问题发送未完成时切换为接收模式导致数据丢失。解决发送前后添加10μs延时确保MAX485方向切换完成总线末端并联120Ω终端电阻减少信号反射。4.3 接收数据溢出问题缓冲区过小或中断未及时响应导致数据覆盖。解决增大缓冲区如32字节使用环形缓冲区头指针尾指针避免溢出覆盖。五、测试与验证5.1 RS232测试硬件连接单片机TXD/RXD→MAX232→DB9串口线→PC串口。工具PC端使用串口助手如SSCOM设置波特率9600、8N1。预期结果PC发送“Hello”单片机回传“RS232 Recv: Hello”。5.2 RS485测试硬件连接两台单片机通过MAX485模块连接A-A相连B-B相连终端电阻120Ω。测试步骤主机定时发送“RS485 Test: Hello!”从机接收后通过RS232转发至PC串口助手。预期结果从机串口助手显示主机发送的测试字符串无丢包。六、总结基于51单片机实现了RS232/RS485双串口通信核心是UART初始化、波特率精确控制与RS485方向切换时序。通过模块化设计发送/接收分离、中断处理可扩展为Modbus RTU协议工业总线常用适用于多节点数据采集与控制系统。

更多文章