1. UART基础通信

UART基础通信 学习卡片

任务说明

本案例实现Python通过串口与外部设备(或另一串口)进行基础数据收发。目标为:发送指定字节序列,接收对方返回的数据,并验证收发内容一致,从而确认串口链路通信正常。

实现方案

使用pyserial库操作串口。程序打开指定串口后,发送一组十六进制数据,随后读取串口接收缓冲区中的响应数据,并将收发内容打印对比。为便于独立验证,本案例同时提供回环测试模式:将串口的TX与RX短接(或使用USB转串口模块的自发自收测试),即可在无外部设备情况下完成验证。

代码实现

import serial
import serial.tools.list_ports
import time

def list_serial_ports():
    """列出当前可用串口"""
    ports = serial.tools.list_ports.comports()
    if not ports:
        print("未检测到可用串口")
        return []
    for i, port in enumerate(ports):
        print(f"[{i}] {port.device} - {port.description}")
    return [port.device for port in ports]

def uart_basic_communication(port_name, baudrate=115200, timeout=2):
    """
    串口基础收发验证
    发送数据帧: 0x01 0x03 0x00 0x00 0x00 0x01
    预期接收:  外部设备返回的数据(回环模式下与发送一致)
    """
    # 待发送数据帧(Modbus RTU 读保持寄存器示例帧)
    tx_data = bytes([0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x84, 0x0A])
    
    try:
        # 打开串口
        ser = serial.Serial(
            port=port_name,
            baudrate=baudrate,
            bytesize=serial.EIGHTBITS,
            parity=serial.PARITY_NONE,
            stopbits=serial.STOPBITS_ONE,
            timeout=timeout
        )
        print(f"串口 {port_name} 已打开,参数: {baudrate}bps, 8N1")
        
        # 清空接收缓冲区
        ser.reset_input_buffer()
        
        # 发送数据
        ser.write(tx_data)
        print(f"发送 {len(tx_data)} 字节: {tx_data.hex(' ').upper()}")
        
        # 等待接收
        time.sleep(0.1)
        rx_data = ser.read(ser.in_waiting if ser.in_waiting > 0 else 1)
        
        if rx_data:
            print(f"接收 {len(rx_data)} 字节: {rx_data.hex(' ').upper()}")
            
            # 验证收发数据是否一致(回环模式)
            if rx_data == tx_data:
                print("验证通过: 接收数据与发送数据完全一致")
                return True
            else:
                print("验证结果: 接收数据与发送数据不一致(可能外部设备有响应帧)")
                print("若为回环测试,请检查TX/RX是否短接正确")
                return False
        else:
            print("接收超时: 未收到任何数据")
            print("请检查:")
            print("  1. 串口号是否正确")
            print("  2. TX/RX是否已短接(回环测试)")
            print("  3. 波特率等参数是否与对端一致")
            return False
            
    except serial.SerialException as e:
        print(f"串口错误: {e}")
        return False
    finally:
        if 'ser' in locals() and ser.is_open:
            ser.close()
            print("串口已关闭")

if __name__ == "__main__":
    print("=== UART基础通信测试 ===")
    available_ports = list_serial_ports()
    
    if available_ports:
        # 默认选择第一个串口,也可手动指定
        port = available_ports[0]
        print(f"使用串口: {port}")
        uart_basic_communication(port)
    else:
        print("请连接串口设备后重试")

运行与验证

依赖安装:

pip install pyserial

硬件准备(回环测试):将USB转串口模块的TX引脚与RX引脚用杜邦线短接。

运行:

python uart_basic.py

判定标准:

  • 程序输出“串口已打开”且无异常;
  • 发送字节数与接收字节数均为8字节;
  • 回环模式下,接收数据与发送数据完全一致,输出“验证通过”。
UART基础通信验证拓扑 PC (Python) pyserial 发送: 8字节帧 接收: 回环数据 USB转串口模块 CH340 / CP2102 TX ———— RX (杜邦线短接) 外部设备 (可选替代回环) MCU/传感器 返回响应帧 USB UART TX/RX 发送 接收 验证点: 发送帧与接收帧完全一致 → 通信正常

预期输出(回环模式)

=== UART基础通信测试 ===
[0] COM3 - USB-SERIAL CH340
使用串口: COM3
串口 COM3 已打开,参数: 115200bps, 8N1
发送 8 字节: 01 03 00 00 00 01 84 0A
接收 8 字节: 01 03 00 00 00 01 84 0A
验证通过: 接收数据与发送数据完全一致
串口已关闭

若连接外部设备,接收数据为设备返回的响应帧(非回环数据),此时程序会提示“接收数据与发送数据不一致”,但通信链路已建立,可通过观察接收到的响应帧内容判断通信是否正常。