Python 在 Windows 下的串口通信:超详细编程指南与实例139
---
嘿,各位技术探索者们!欢迎来到我的技术博客。今天,我们要一起解锁一项非常实用的技能——使用Python在Windows操作系统下进行串口通信。你可能会问,都2023年了,串口还在用吗?答案是肯定的!无论是连接各种单片机(Arduino, ESP32)、工业控制器、GPS模块,还是读取各种传感器数据,串口都扮演着重要的角色。Python凭借其强大的生态和易用性,成为了进行串口编程的绝佳选择。本篇文章将带你从零开始,手把手教你如何在Windows环境下,利用Python进行高效、稳定的串口数据收发!
为了让大家能更好地理解和实践,我将从串口的基础知识讲起,然后详细介绍Python中进行串口通信的利器——PySerial库,并提供详尽的代码实例。话不多说,让我们直接进入主题吧!
一、串口通信基础:理解你的“硬件之桥”
在开始编程之前,我们首先需要对串口通信有一个基本的认识。串口,顾名思义,就是数据一位一位地进行传输。它主要涉及以下几个核心概念:
COM端口号(COM Port):在Windows系统中,每个物理或虚拟串口都会被分配一个COM端口号,例如COM1、COM2、COM3等等。这是我们程序中用来指定目标串口的唯一标识。
波特率(Baud Rate):表示每秒传输的位数,是衡量数据传输速度的单位。发送方和接收方的波特率必须一致,否则会产生乱码。常见的波特率有9600、19200、38400、115200等。
数据位(Data Bits):表示一次传输中实际数据位的数量,通常为7位或8位。最常用的是8位。
停止位(Stop Bits):用于标识一个数据帧的结束,通常为1位、1.5位或2位。最常用的是1位。
奇偶校验位(Parity Bits):用于数据传输的错误检测。可以是无校验(None)、奇校验(Odd)、偶校验(Even)、标志位校验(Mark)或空格位校验(Space)。最常用的是无校验。
在实际操作中,你可能需要一个USB转串口模块(例如CH340、CP2102芯片的转换器),将设备的TTL/RS232/RS485信号转换为电脑可识别的USB信号,并模拟成一个COM端口。确保你的设备已正确连接,并且驱动已安装,才能在设备管理器中看到对应的COM端口号。
二、Python串口通信的利器:PySerial库
Python中进行串口通信主要依赖于一个强大的第三方库——PySerial。它是一个跨平台的库,支持Windows、Linux、macOS等多种操作系统,提供了统一的API接口。使用PySerial,我们可以非常方便地打开、关闭串口,发送和接收数据。
2.1 安装PySerial
安装PySerial非常简单,只需要在你的命令行(CMD或PowerShell)中执行以下命令即可:pip install pyserial
如果你使用了虚拟环境,请确保在激活的虚拟环境中安装。
2.2 查找可用的COM端口
在Windows下,确定哪个COM端口是你的设备所连接的端口,是进行串口通信的第一步。PySerial提供了一个工具模块`.list_ports`来列出当前系统中所有可用的串口。这对于避免硬编码端口号,增加程序的通用性非常有帮助。import .list_ports
def find_serial_ports():
ports = ()
if not ports:
print("未找到任何串口设备!")
return []
available_ports = []
print("当前可用的串口设备:")
for port, desc, hwid in sorted(ports):
print(f" 端口号: {port}, 描述: {desc}, 硬件ID: {hwid}")
(port)
return available_ports
if __name__ == "__main__":
com_ports = find_serial_ports()
if com_ports:
print(f"你可以尝试连接以下串口中的一个:{com_ports[0]}")
else:
print("请检查设备是否连接或驱动是否安装。")
运行这段代码,它会列出你的电脑上所有被识别的串口。你可以根据`描述`或`硬件ID`来判断哪个是你想要连接的设备。例如,一个USB转串口模块通常会显示`USB-SERIAL CH340`或`CP2102 USB to UART Bridge`等字样。
三、PySerial核心功能与编程实例
了解了基础和工具,现在我们来看看如何使用PySerial进行实际的数据收发。
3.1 打开与关闭串口
使用`()`构造函数来打开一个串口。在创建`Serial`对象时,你需要指定端口号、波特率等参数。为了确保资源被正确释放,我们强烈推荐使用`with`语句来管理串口对象,这样无论程序是否出错,串口都会自动关闭。import serial
import time
# 串口配置参数
PORT = 'COM3' # 请替换为你的实际串口号
BAUDRATE = 9600
BYTESIZE = 8
STOPBITS = 1
PARITY = 'N' # N代表无校验
TIMEOUT = 1 # 读取超时时间,单位秒
try:
# 使用with语句打开串口,确保无论如何都会关闭
with (PORT, BAUDRATE, BYTESIZE, PARITY, STOPBITS, timeout=TIMEOUT) as ser:
print(f"成功打开串口: {}")
# 在这里进行数据收发操作
# 串口打开后的一些属性
print(f" 端口号: {}")
print(f" 波特率: {}")
print(f" 是否打开: {ser.is_open}")
# 示例:等待5秒
(5)
print(f"串口 {PORT} 已关闭。")
except as e:
print(f"串口错误: {e}")
print(f"请检查端口 '{PORT}' 是否存在、是否被占用,或参数是否正确。")
except Exception as e:
print(f"发生未知错误: {e}")
重要提示: 请将代码中的`PORT = 'COM3'`替换为你实际的串口号。如果你不确定,请使用上面提到的`find_serial_ports()`函数来查找。
3.2 写入数据(发送)
向串口写入数据非常简单,使用`()`方法即可。需要注意的是,`write()`方法接收的是字节(bytes)类型的数据,而不是字符串。因此,如果你要发送一个字符串,需要先对其进行编码(encode)。# 假设ser对象已成功打开
# (data_in_bytes)
# 示例:发送字符串 "Hello Serial!"
message = "Hello Serial!" # 注意:有些设备可能需要换行符作为命令结束标志
(('utf-8')) # 使用UTF-8编码将字符串转为字节
print(f"已发送数据: {()}")
# 示例:发送十六进制数据 (例如:一个控制命令 0xAA 0x01 0x02)
hex_data = b'\xAA\x01\x02'
(hex_data)
print(f"已发送十六进制数据: {()}")
`encode()`方法将字符串转换为字节串,常用的编码方式是`'utf-8'`。如果你的设备使用其他编码(如`'ascii'`或`'gbk'`),请相应调整。
3.3 读取数据(接收)
从串口读取数据有几种常用方法:
`(size)`:读取指定数量的字节。如果`timeout`设置大于0,它会等待直到读取到`size`个字节或超时。
`()`:读取直到接收到换行符``(或者遇到超时),返回包含换行符的字节串。
`ser.read_until(expected=LF)`:读取直到接收到指定的字节序列`expected`(默认为换行符``)。
`ser.in_waiting`:返回输入缓冲区中等待读取的字节数。这可以用来判断是否有数据可读。
读取到的数据也是字节类型,通常我们需要对其进行解码(decode)才能得到可读的字符串。# 假设ser对象已成功打开
# data_received_bytes = (size)
# data_received_line_bytes = ()
# 示例1:读取固定数量的字节
if ser.in_waiting >= 10: # 检查缓冲区是否有至少10个字节
received_bytes = (10)
print(f"接收到10个字节: {('utf-8')}")
# 示例2:读取一行数据(直到换行符)
print("尝试读取一行数据...")
received_line_bytes = ()
if received_line_bytes:
print(f"接收到一行数据 (原始字节): {received_line_bytes}")
print(f"接收到一行数据 (解码后): {('utf-8').strip()}")
else:
print("未接收到数据或已超时。")
# 示例3:持续监听并读取所有可用数据
print("开始持续监听串口数据 (按Ctrl+C停止)...")
try:
while True:
if ser.in_waiting > 0:
received_data_bytes = (ser.in_waiting) # 读取所有可用数据
print(f"接收到: {('utf-8', errors='ignore').strip()}")
(0.1) # 短暂等待,避免CPU空转
except KeyboardInterrupt:
print("停止监听。")
`decode()`方法将字节串转换为字符串。`errors='ignore'`参数可以在解码失败时忽略错误字符,避免程序崩溃。
3.4 完整收发实例:模拟设备交互
现在,我们将把上述知识整合起来,编写一个完整的Python程序,模拟向串口发送命令并接收其响应的场景。这在控制嵌入式设备或传感器时非常常见。import serial
import time
import .list_ports
# --- 配置参数 ---
PORT = 'COM3' # * 务必修改为你的实际串口号!*
BAUDRATE = 9600
BYTESIZE = 8
STOPBITS = 1
PARITY = 'N'
TIMEOUT = 1 # 串口读取超时时间(秒)
WRITE_ENCODING = 'utf-8' # 发送数据编码
READ_DECODING = 'utf-8' # 接收数据解码
def find_first_com_port():
"""查找第一个可用的COM端口"""
ports = ()
if ports:
return ports[0].device
return None
def main():
global PORT
# 如果PORT是默认值且未找到任何串口,尝试自动查找
if PORT == 'COM3': # 假设COM3是默认占位符,你可以改成''或None
found_port = find_first_com_port()
if found_port:
PORT = found_port
print(f"自动检测到并使用串口: {PORT}")
else:
print("未找到任何可用串口。请手动指定正确的COM端口或连接设备。")
return
print(f"尝试连接串口:{PORT},波特率:{BAUDRATE}...")
try:
# 使用with语句确保串口自动关闭
with (PORT, BAUDRATE, BYTESIZE, PARITY, STOPBITS, timeout=TIMEOUT) as ser:
if not ser.is_open:
print("串口打开失败!")
return
print(f"成功打开串口:{}")
print("------------------------------------------")
print("输入命令(或'exit'退出),按Enter发送。")
print("注意:发送数据后,程序会尝试读取设备响应。")
print("------------------------------------------")
while True:
try:
user_input = input("请输入要发送的命令 (例如: GET_TEMP\): ")
if () == 'exit':
print("程序退出。")
break
# 1. 准备并发送数据
# 很多设备需要换行符来结束命令,这里默认加上
send_data = (user_input + "").encode(WRITE_ENCODING)
(send_data)
print(f"--> 已发送: {(WRITE_ENCODING).strip()}")
# 2. 等待并读取设备响应
print("等待设备响应...")
received_bytes = b''
start_time = ()
# 持续读取直到超时或读到换行符
while () - start_time < TIMEOUT:
if ser.in_waiting > 0:
# 每次只读一个字节,检查是否是换行符,模拟readline
byte = (1)
received_bytes += byte
if byte == b'': # 如果接收到换行符,认为一行数据接收完毕
break
(0.01) # 短暂延时,避免CPU占用过高
if received_bytes:
try:
decoded_response = (READ_DECODING).strip()
print(f"
2025-10-20

Perl 在 Windows 环境:深度剖析常用命令与脚本技巧
https://jb123.cn/perl/70102.html

JavaScript正则表达式:从入门到精通,玩转文本匹配的瑞士军刀!
https://jb123.cn/javascript/70101.html

脚本语言的‘隐身术’:哪些语言最常活跃在系统深处而不易察觉?
https://jb123.cn/jiaobenyuyan/70100.html

编程小白到高手:2024年十大热门脚本语言选择指南与深度解析
https://jb123.cn/jiaobenyuyan/70099.html

Perl DBI:玩转数据库的强大模块,从入门到高效实战!
https://jb123.cn/perl/70098.html
热门文章

Python 编程解密:从谜团到清晰
https://jb123.cn/python/24279.html

Python编程深圳:初学者入门指南
https://jb123.cn/python/24225.html

Python 编程终端:让开发者畅所欲为的指令中心
https://jb123.cn/python/22225.html

Python 编程专业指南:踏上编程之路的全面指南
https://jb123.cn/python/20671.html

Python 面向对象编程学习宝典,PDF 免费下载
https://jb123.cn/python/3929.html