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