PySerial实现DB9 RS232串口流控请求:XonXoff/RTSCTS/DSRDTR示例
PySerial 串口流控实现指南(适配13字节接收阈值)
嘿,刚好对PySerial的串口流控这块熟得很,来给你详细讲讲XonXoff、RTS/CTS、DSR/DTR这三种方式的用法,完美适配你那“接收超13字节就触发流控”的需求~
先快速给你区分下三者的核心差异:
- Xon/Xoff(软件流控):纯软件逻辑,靠发送特定控制字符让发送端停/发,不用额外硬件引脚,适合缺硬件流控引脚的场景。
- RTS/CTS(硬件流控):靠串口的RTS、CTS引脚电平变化来控制,硬件层面实现,可靠性拉满,工业场景常用。
- DSR/DTR(硬件流控):原本是用来检测设备是否就绪的引脚,偶尔也能当流控用,但不如RTS/CTS普遍,优先级靠后。
1. Xon/Xoff 软件流控(无硬件依赖首选)
这种方式不用折腾硬件引脚,靠发送XOFF(0x13)告诉发送端“别发了”,发送XON(0x11)告诉它“继续发”。PySerial可以自动处理,但如果你要严格卡13字节的阈值,手动控制会更精准。
手动控制示例(精准适配13字节阈值)
import serial import time # 初始化串口,记得替换成你的串口号 ser = serial.Serial( port='COM3', baudrate=9600, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_1, bytesize=serial.EIGHTBITS, xonxoff=False # 关闭自动控制,手动发XON/XOFF ) received_data = b'' threshold = 13 # 你的13字节阈值 try: while True: # 检查有没有待接收的数据 if ser.in_waiting > 0: chunk = ser.read(ser.in_waiting) received_data += chunk print(f"当前已接收: {len(received_data)} 字节") # 达到阈值就触发流控 if len(received_data) >= threshold: print("⚠️ 达到13字节阈值,发送XOFF让发送端停止") ser.write(b'\x13') # 发送XOFF控制字符 # 这里加你的数据处理逻辑,比如解析、存储 time.sleep(2) # 模拟处理耗时 # 处理完恢复接收 print("✅ 数据处理完成,发送XON让发送端继续") ser.write(b'\x11') # 发送XON控制字符 received_data = b'' # 清空接收缓冲区 finally: # 程序结束记得关闭串口 ser.close()
如果你不想手动控制,也可以直接开xonxoff=True,PySerial会自动在接收缓冲区快满时发XOFF,但没法精准卡13字节的阈值,看你需求选就行。
2. RTS/CTS 硬件流控(高可靠性首选)
这种是硬件层面的流控,靠DB9串口的第7脚(RTS)和第8脚(CTS)来通信:我们拉低RTS电平,发送端检测到CTS变低就停止发送;拉高RTS,发送端就继续。
手动控制示例(精准卡阈值)
import serial import time ser = serial.Serial( port='COM3', baudrate=9600, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_1, bytesize=serial.EIGHTBITS, rtscts=False # 关闭自动控制,手动操作RTS ) received_data = b'' threshold = 13 try: ser.setRTS(True) # 初始状态:允许发送端发送 while True: if ser.in_waiting > 0: chunk = ser.read(ser.in_waiting) received_data += chunk print(f"当前已接收: {len(received_data)} 字节") if len(received_data) >= threshold: print("⚠️ 达到阈值,拉低RTS停止接收") ser.setRTS(False) # 拉低RTS引脚,通知发送端停发 # 处理数据逻辑 time.sleep(2) print("✅ 处理完成,拉高RTS恢复接收") ser.setRTS(True) received_data = b'' finally: ser.close()
⚠️ 注意:用这个方式必须确保你的串口设备(包括发送端)支持RTS/CTS引脚,而且发送端也要配置成RTS/CTS流控模式,不然没用哦。
3. DSR/DTR 流控(特殊场景备选)
DSR是发送端的引脚(表示发送端就绪),DTR是我们这边的引脚(表示我们就绪)。原本是用来检测设备是否在线的,偶尔也能当流控用,但不如RTS/CTS靠谱,除非你设备只支持这个。
手动控制示例
import serial import time ser = serial.Serial( port='COM3', baudrate=9600, parity=serial.PARITY_NONE, stopbits=serial.STOPBITS_1, bytesize=serial.EIGHTBITS, dsrdtr=False # 关闭自动控制 ) received_data = b'' threshold = 13 try: ser.setDTR(True) # 初始告诉发送端:我们就绪,可以发 while True: if ser.in_waiting > 0: chunk = ser.read(ser.in_waiting) received_data += chunk print(f"当前已接收: {len(received_data)} 字节") if len(received_data) >= threshold: print("⚠️ 达到阈值,拉低DTR停止接收") ser.setDTR(False) # 告诉发送端:我们忙,别发了 # 处理数据 time.sleep(2) print("✅ 处理完成,拉高DTR恢复接收") ser.setDTR(True) received_data = b'' finally: ser.close()
同样,这个需要发送端监听DSR引脚的状态,当DSR变低就停发,得提前和发送端的逻辑匹配好。
最后给你个选择建议
- 要是你的串口设备没硬件流控引脚(比如便宜的USB转串口模块),直接选Xon/Xoff软件流控。
- 要是追求稳定、实时性,优先选RTS/CTS硬件流控,工业场景都是用这个。
- DSR/DTR尽量只用来检测设备就绪,除非特殊情况,别当流控用。
内容的提问来源于stack exchange,提问作者take_it_easy_159
相关产品推荐
相关产品推荐

