找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3|回复: 0
收起左侧

STC32单片机的4串口通信程序

[复制链接]
ID:90212 发表于 2026-11-8 23:17 | 显示全部楼层 |阅读模式
开始玩STC32了,首先拿串口练手,示例有1串口、2串口,没有3串口、4串口。其次是示例使用的快速扫描边收边发,不适合一帧收完再发,TTL全双工没有问题,遇到RS485线路就丢包了。

集成了4串口,同时接收改为"整帧缓存 + 接收超时":每个串口先把收到的数据缓存起来, 当连续 RX_TIMEOUT_MS(单位 ms) 没有新数据到达(或缓存满)时,再把整帧原样一次性回发。适合工控环境!
================================================================
STC32G8K64 4 串口中断收发测试程序 — 功能说明(统一波特率 / 接收超时版)
================================================================
【程序来源】
参考 "15W4K-4串口中断收发" 范例(4 串口各自独立、各自回环) 与
本目录下 4 个独立的 STC32 串口程序(UART1~UART4 单口例程),
合并改写为 STC32G8K64 的 4 串口同时工作例程。

【相对上一版的主要改动】
1. 4 个串口统一波特率(全部 115200)。UART1 通过 S1BRT=1 改用 Timer2,
   UART2 本就使用 Timer2,两者共用同一个定时器,波特率必然一致。
2. 接收改为"整帧缓存 + 接收超时":每个串口先把收到的数据缓存起来,
   当连续 RX_TIMEOUT_MS(单位 ms) 没有新数据到达(或缓存满)时,再把整帧
   原样一次性回发。
3. 因 UART1 不再占用 Timer1,空闲的 Timer1 被用作 1ms 系统节拍
   (中断累加 g_msCount),为接收超时提供时间基准。

【为什么这样能避免 RS485 丢码】
RS485 是半双工总线,收发共用 A/B 线,通常靠 DE/RE 引脚切换方向。
若"收到一字节立刻回一发一字节",会频繁切换方向,极易在每次切换的
边界丢掉字节(丢码)。改为"收齐一帧、超时才整帧回复",只需切换一次
方向即可把整帧发完,从根本上避免 RS485 场景下的丢码。例程内已内置
可选的 RS485 方向控制(USE_RS485),默认关闭,普通 TTL 串口可直接用。

【硬件平台】
主控:STC32G8K64
系统时钟:22.1184 MHz(可在 main.c 顶部 MAIN_Fosc 修改)

【功能】
4 个串口均以中断方式全双工工作,收到一帧数据后延迟 RX_TIMEOUT_MS 毫秒
再整帧原样回发(回环测试)。上电后每个串口先发送一行识别字符串,便于
确认通讯正常。

【波特率与引脚分配】
  UART1 : 115200 bps  波特率发生器 = Timer2(与UART2共用)  引脚 P3.0/RxD1  P3.1/TxD1
  UART2 : 115200 bps  波特率发生器 = Timer2(与UART1共用)  引脚 P4.6/RxD2  P4.7/TxD2 (S2_S=1)
  UART3 : 115200 bps  波特率发生器 = Timer3                引脚 P5.0/RxD3  P5.1/TxD3 (S3_S=1)
  UART4 : 115200 bps  波特率发生器 = Timer4                引脚 P0.2/RxD4  P0.3/TxD4 (S4_S=0)
  系统节拍: 1ms        定时器 = Timer1(因 UART1 改用 Timer2 而空闲出来)

说明:
  - UART1 波特率源由 S1BRT 选择(Timer1 / Timer2),本版选 Timer2;
  - UART2 波特率源固定为 Timer2;两者共用 Timer2,故波特率必然一致;
  - UART3 波特率源由 S3ST3 选择(Timer2 / Timer3),本版选 Timer3;
  - UART4 波特率源由 S4ST4 选择(Timer2 / Timer4),本版选 Timer4;
  - 需要改波特率时只改 main.c 顶部 BAUDRATE 一个宏,4 个串口同时变化。

【测试接线】
用 4 个 USB 转串口模块,按下表交叉连接(MCU 的 TxD 接模块 RxD,
MCU 的 RxD 接模块 TxD,并与模块共地):

  模块A(UART1,115200) → P3.1(TxD1) 接 RxD,P3.0(RxD1) 接 TxD
  模块B(UART2,115200) → P4.7(TxD2) 接 RxD,P4.6(RxD2) 接 TxD
  模块C(UART3,115200) → P5.1(TxD3) 接 RxD,P5.0(RxD3) 接 TxD
  模块D(UART4,115200) → P0.3(TxD4) 接 RxD,P0.2(RxD4) 接 TxD

在串口助手以 115200 发送一串数据,应延迟 RX_TIMEOUT_MS(默认 20) 毫秒后
收到完全相同的整帧回发数据(发送后稍等即可看到回显)。

【关键参数(main.c 顶部宏)】
  BAUDRATE       = 115200   统一波特率(4 个串口一致)
  RX_TIMEOUT_MS  = 20       接收超时(ms):连续这么久无新数据即视为一帧结束并整帧回复
  FRAME_BUF_LEN  = 128      每串口帧缓存长度;超过则立即整帧发出以免溢出
  USE_RS485      = 0        置 1 启用 RS485 方向控制(需在宏内填写各串口 DE 引脚)

【RS485 接线提示】
若启用 USE_RS485=1,请按实际接线修改 RS485_DE1~4 宏指向的引脚
(默认示例用 P3.2~P3.5 作 DE/RE,高电平=发送),并把它们接至对应
RS485 收发器的 DE/RE(可短接)。程序会在发送前拉高、发完后拉低,且
发送期间不会因超时再次触发,避免方向抖动。

【工程建立】
本例使用 Keil C251 编译,Memory Model 推荐 XSmall(默认变量放 edata,
访问速度快);接收缓冲区使用了 xdata 关键字以节省 edata 空间。
需把 COMM 目录下的 STC32G.H 加入工程包含路径(例程已用
"..\comm\STC32G.h" 的相对路径包含)。下载时选择 STC32G8K64 芯片型号。


下载 STC32G8K64-4串口中断收发测试.rar (62.58 KB, 下载次数: 0)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的奖励!

查看全部评分

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表