找回密码
 会员注册
查看: 25|回复: 0

Python串口通信详解(serial模块)以可编程电源为例

[复制链接]

32

主题

0

回帖

97

积分

注册会员

积分
97
发表于 2024-9-6 14:39:21 | 显示全部楼层 |阅读模式
1.什么是串口通信?串口通信(serialcommunication)是串口按位(bit)发送和接收字节的一种通信方式。由于其按位传输,所以速度会比按字节传输的并行通信(parallelcommunication)的速度慢得多,但是与之对应的,串口通信的数据传输距离通常会比并行通信更远。  在开始介绍python串口通信的相关知识之前,我们先来了解一些相关概念。 波特率波特率的大小主要反映的是传输速率,常见的波特率包括9600,115200等,这里的数字含义是串口每秒传输的二进制位数。需要注意的是,波特率不是随便设定的,需要通信的双方拥有相同的波特率,两者才能成功进行通信,因此很多设备都会使用类似于9600,115200这样的波特率。帧结构在串口通信时信息一般以帧传输,串口通信时的一帧通常包括多个不同功能的位:起始位:标志一个帧的开始数据位:包含着帧中承载的信息校验位:一般是数据位后的一位,用于判断信息传输是否正常,没有校验位当然也可以停止位:标志一个帧的结束RS232传输标准RS232是一种常见的串口传输标准,通常以9引脚或25引脚的形式出现。大部分计算机上都有包含RS232标准的串口,是计算机系统与外部设备传输的标准接口,因其兼容性很好,使用广泛,本文中使用的也是RS232传输标准。此外常见的传输标准还有RS485标准。2.可编程电源通信协议了解完概念之后我们来结合实例加深对概念的理解,首先我们来阅读该款外部设备的通信协议:从文件中我们可以得知该设备与计算机进行通信的波特率、帧结构以及更加详细的功能位信息,其波特率为9600,有1个起始位,1个停止位和8个数据位,无校验位。了解这些信息可以让我们知道如何在后续使用python进行通信。同时,文件还告诉我们传输时前一消息与后一消息之间需要间隔3.5个字符时间,假如我们想要先读取电压,然后再设置电压,需要先后传输两个信息,那么读取电压之后我们需要设置时间间隔,否则读取电压和设置电压的信息会被视为同一信息,从而无法达到预想的目标。3.python串口通信基本操作查看串口状态我们来了解一些计算机串口通信的基本操作: 打开电脑的设备管理器,在设备管理器中可以查看所有已通过串口连接的设备:在此可以确定外部连接设备的串口号,本文中使用的可编程电源锁定COM3串口,若COM3口被占用会自动后移至COM4口,因此后面的串口通信代码部分均使用COM3口。接下来,需要安装python中的串口通信模块,正式开始代码部分:pipinstallserial以下代码可以使用python进行判断当前串口是否成功连接上设备: importtimeimportserialimportserial.tools.list_portscom_port="COM3"while1:#获取串口列表ports_list=list(serial.tools.list_ports.comports())#获取串口列表,包含所有已连接串口print(ports_list)print(ports_list[0])#判断串口是否打开com_flag=Falseforcomportinports_list:ifcomport[0]==com_port:com_flag=Trueprint("成功获取COM3串口")breaktime.sleep(3) 串口打开首先导入serial库importserial使用Serial()方法,获取串行串口:ser=serial.Serial()根据外部设备的通信协议信息来设置串口:ser.port="COM3"#设置端口号ser.baudrate=9600#设置波特率ser.bytesize=8#设置数据位ser.stopbits=1#设置停止位 使用open()方法打开串口,要找到对的串口号才会成功:ser.open()串口写入成功连接上串口后,我们就可以开始编码发送了,由于python使用的就是utf-8编码,因此我们需要使用encode方法将二进制编码成utf-8格式,使用write()方法即可通过串口发送。send_data=''#可编程电源匹配连接的语句,不懂的话重新看一遍前面通信协议的部分ser.write(send_data.encode('utf-8'))#utf-8编码发送将写入方法直接使用函数封装,后面我们可以直接拿来使用:defsend(send_data):"""发送编码"""ser.write(send_data.encode('utf-8'))#utf-8编码发送'运行运行类似的,我们可以向可编程电源发送设定电压的语句,调用前面定义的send函数:send('')#设定110V电压由于第3-5位是数据位,我们发送编码即可设定为110V电压串口读取读取时一般需要先发送准备读取的编码,此处我们发送读取当前电流的编码,发送到可编程电源后,电源知道了我们需要他的电流信息,就会通过串口返回,此时我们只需要使用read()方法读取即可:send("")#发送电流读取编码,等待电源信息返回data_read=ser.read(26)#返回读取的26位信息current_code=data_read.decode('utf-8')#将返回的信息进行解码current_read=current_code[16:22]#在返回的信息中取有用的几位,此处取16-22位反映的是电流大小关闭串口一切操作完成后,我们使用ser.close语句即可关闭串口,结束通信ser.close()常用的串口指令一览ser.open()打开串口ser.isOpen()判断串口是否打开ser.close()关闭串口ser.write("xxxx")写入数据ser.read()串口读取ser.readline()读取一行数据ser.read_all()串口接收全部数据4.代码一览下面的代码块把我前面所讲的东西全部结合在一起,可以浏览一下,帮助来理解整个过程,尽管其他设备可能通信协议不同,但是参考一下大致的结构是差不多的,无非就是打开关闭,读和写。importserialimporttimedefport_open():"""打开串口"""ser.port="COM3"#设置端口号ser.baudrate=9600#设置波特率ser.bytesize=8#设置数据位ser.stopbits=1#设置停止位ser.open()#打开串口,要找到对的串口号才会成功defport_close():"""关闭串口"""ser.close()defsend(send_data):"""发送编码"""ser.write(send_data.encode('utf-8'))#utf-8编码发送defcurrent_read():"""读取串口返回的编码"""port_open()send('')#连接编码time.sleep(0.1)send("")#读取编码data_read=ser.read(26)current_code=data_read.decode('utf-8')#解码current_read=current_code[16:22]#读取16-22位,反映的是电流大小current=int(current_read)port_close()returncurrent_readdefset_voltage(voltage):"""设定电压编码函数"""#-----------------------电压编码规则----------------------if0')#连接time.sleep(0.2)send('')#启动电源time.sleep(0.2)send('')#设置110V电压time.sleep(0.2)send('')#断开连接time.sleep(0.2)#-----------------------断开串口-------------------------port_close()#-----------------------结束通信-------------------------if__name__=="__main__":ser=serial.Serial()#获取串口set_voltage(110)#设定110V电压whileTrue:print(current_read())#循环读取当前电压time.sleep(1)感谢各位支持,之后还会继续分享更多有用的知识!想要了解更多可以关注我或关注本专栏。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-10 05:38 , Processed in 1.478959 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表