2. Python串口库基础:pySerial的安装、配置与使用

做嵌入式调试,串口是绕不开的活。我最早用Python操作串口时,也踩过不少坑。今天咱们就把pySerial这个库彻底聊透。

2.1 pySerial的安装与导入

pySerial是Python操作串口的标准库,不是内置的,需要自己装。安装方式很简单:

pip install pyserial

如果你用的是Python 3,建议用pip3:

pip3 install pyserial

装完之后,在代码里导入:

import serial

嗯,这里要注意。有些教程会让你写from serial import *,我个人不建议这么做。串口操作需要精确控制,显式导入更清晰。

小提示: 如果你在Linux下遇到权限问题,记得把用户加到dialout组:sudo usermod -a -G dialout $USER。我刚开始搞的时候,卡在这步半天。

2.2 串口参数配置

串口通信就像两个人约定好怎么说话。参数不对,数据就是乱码。核心参数有四个:

参数 常用值 说明
波特率 9600, 115200, 460800 每秒传输的符号数,双方必须一致
数据位 5, 6, 7, 8 一帧数据中有效数据的位数,常用8位
停止位 1, 1.5, 2 帧结束标志,常用1位
校验位 None, 'E', 'O', 'M', 'S' 无校验、偶校验、奇校验、标记、空格

配置代码长这样:

import serial

ser = serial.Serial(
    port='COM3',          # Windows下是COM口,Linux下是/dev/ttyUSB0
    baudrate=115200,      # 波特率
    bytesize=8,           # 数据位
    parity='N',           # 校验位:N无校验,E偶校验,O奇校验
    stopbits=1,           # 停止位
    timeout=1             # 超时时间,单位秒
)

你想想看,为什么数据位常用8位?因为ASCII字符就是7位,加上一个校验位正好8位。但现在的设备大多直接传二进制数据,所以8位是标配。

避坑指南: 我曾经在一个项目里,波特率设对了,数据位和停止位也对,但就是收不到数据。折腾了半天,发现是校验位没对上——设备用的是偶校验,我设成了无校验。记住:收发双方的四个参数必须完全一致。

2.3 打开与关闭串口

串口操作的核心就三步:打开、读写、关闭。先看打开:

# 方式一:构造时自动打开
ser = serial.Serial('COM3', 115200)

# 方式二:先创建对象,再手动打开
ser = serial.Serial()
ser.port = 'COM3'
ser.baudrate = 115200
ser.open()

我个人习惯用方式一,代码更简洁。但如果你需要动态修改参数,方式二更灵活。

关闭串口也很重要:

ser.close()

为什么强调关闭?因为串口资源是独占的。你不关,别的程序就打不开。我见过有人调试时程序崩溃了,串口没释放,结果只能重启电脑。

最佳实践: 用with语句自动管理串口生命周期:
with serial.Serial('COM3', 115200, timeout=1) as ser:
    # 在这里读写串口
    data = ser.read(10)
    # 退出with块时自动关闭

2.4 检查串口状态

有时候你需要知道串口当前的状态:

# 检查串口是否已打开
if ser.is_open:
    print("串口已打开")

# 获取当前参数
print(f"波特率: {ser.baudrate}")
print(f"数据位: {ser.bytesize}")
print(f"校验位: {ser.parity}")
print(f"停止位: {ser.stopbits}")

这些属性都是可读可写的。你可以在运行时动态修改参数,但修改前最好先关闭串口。

2.5 知识结构总览

下面这张图把pySerial的核心操作串起来了:

pySerial串口操作流程 pip install pyserial import serial 配置参数 波特率 | 数据位 | 停止位 | 校验位 ser.open() ser.close() ⚠ 注意事项 • 参数必须收发一致 • 用完记得关闭串口 • 推荐使用 with 语句

2.6 常见问题与排查

说几个我实际遇到过的问题:

  • SerialException: could not open port —— 端口被占用或权限不足。检查其他程序是否在用,或者加sudo。
  • 读到的数据全是0xFF或乱码 —— 波特率不匹配。用示波器量一下实际波特率,或者换个常用值试试。
  • write()返回0但没报错 —— 串口流控没配好。检查RTS/CTS硬件流控是否开启。
调试技巧: 我习惯在调试时先打印串口参数,确认无误后再开始读写:
print(ser.get_settings())  # 打印所有参数
这行代码能帮你快速定位参数配置问题。