开始玩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)
|