当前位置:   article > 正文

【Python】串口通信详解(serial模块)以可编程电源为例_phython 串口 停止位

phython 串口 停止位

1.什么是串口通信?

串口通信(serial communication)是串口按位(bit)发送和接收字节的一种通信方式。

由于其按位传输,所以速度会比按字节传输的并行通信(parallel communication)的速度慢得多,但是与之对应的,串口通信的数据传输距离通常会比并行通信更远。  

在开始介绍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中的串口通信模块,正式开始代码部分:

pip install serial

以下代码可以使用python进行判断当前串口是否成功连接上设备: 

  1. import time
  2. import serial
  3. import serial.tools.list_ports
  4. com_port = "COM3"
  5. while 1:
  6. # 获取串口列表
  7. ports_list = list(serial.tools.list_ports.comports()) # 获取串口列表,包含所有已连接串口
  8. print(ports_list)
  9. print(ports_list[0])
  10. # 判断串口是否打开
  11. com_flag = False
  12. for comport in ports_list:
  13. if comport[0] == com_port:
  14. com_flag = True
  15. print("成功获取COM3串口")
  16. break
  17. time.sleep(3)

 串口打开

首先导入serial库

import serial

使用Serial()方法,获取串行串口:

ser = serial.Serial()

根据外部设备的通信协议信息来设置串口:

  1. ser.port = "COM3" # 设置端口号
  2. ser.baudrate = 9600 # 设置波特率
  3. ser.bytesize = 8 # 设置数据位
  4. ser.stopbits = 1 # 设置停止位

 使用open()方法打开串口,要找到对的串口号才会成功:

ser.open()

串口写入

成功连接上串口后,我们就可以开始编码发送了,由于python使用的就是utf-8编码,因此我们需要使用encode方法将二进制编码成utf-8格式,使用write()方法即可通过串口发送。

  1. send_data = '<09100000000>' # 可编程电源匹配连接的语句,不懂的话重新看一遍前面通信协议的部分
  2. ser.write(send_data.encode('utf-8')) # utf-8 编码发送

将写入方法直接使用函数封装,后面我们可以直接拿来使用:

  1. def send(send_data):
  2. """发送编码"""
  3. ser.write(send_data.encode('utf-8')) # utf-8 编码发送

类似的,我们可以向可编程电源发送设定电压的语句,调用前面定义的send函数:

send('<01110000000>')  # 设定110V电压

由于第3-5位是数据位,我们发送<01110000000>编码即可设定为110V电压

串口读取

读取时一般需要先发送准备读取的编码,此处我们发送读取当前电流的编码<04003300000>,发送到可编程电源后,电源知道了我们需要他的电流信息,就会通过串口返回,此时我们只需要使用read()方法读取即可:

  1. send("<04003300000>") # 发送电流读取编码,等待电源信息返回
  2. data_read = ser.read(26) # 返回读取的26位信息
  3. current_code = data_read.decode('utf-8') # 将返回的信息进行解码
  4. 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.代码一览

下面的代码块把我前面所讲的东西全部结合在一起,可以浏览一下,帮助来理解整个过程,尽管其他设备可能通信协议不同,但是参考一下大致的结构是差不多的,无非就是打开关闭,读和写。

  1. import serial
  2. import time
  3. def port_open():
  4. """打开串口"""
  5. ser.port = "COM3" # 设置端口号
  6. ser.baudrate = 9600 # 设置波特率
  7. ser.bytesize = 8 # 设置数据位
  8. ser.stopbits = 1 # 设置停止位
  9. ser.open() # 打开串口,要找到对的串口号才会成功
  10. def port_close():
  11. """关闭串口"""
  12. ser.close()
  13. def send(send_data):
  14. """发送编码"""
  15. ser.write(send_data.encode('utf-8')) # utf-8 编码发送
  16. def current_read():
  17. """读取串口返回的编码"""
  18. port_open()
  19. send('<09100000000>') # 连接编码
  20. time.sleep(0.1)
  21. send("<04003300000>") # 读取编码
  22. data_read = ser.read(26)
  23. current_code = data_read.decode('utf-8') # 解码
  24. current_read = current_code[16:22] # 读取16-22位,反映的是电流大小
  25. current = int(current_read)
  26. port_close()
  27. return current_read
  28. def set_voltage(voltage):
  29. """设定电压编码函数"""
  30. # -----------------------电压编码规则----------------------
  31. if 0 <= voltage < 10:
  32. voltage_str = "00" + str(voltage)
  33. elif 10 <= voltage < 100:
  34. voltage_str = "0" + str(voltage)
  35. else:
  36. voltage_str = str(voltage)
  37. # ------------------------连接串口-----------------------
  38. port_open()
  39. # ------------------------发送编码-----------------------
  40. send('<09100000000>') # 连接
  41. time.sleep(0.2)
  42. send('<07000000000>') # 启动电源
  43. time.sleep(0.2)
  44. send('<01' + voltage_str + '000000>') # 设置110V电压
  45. time.sleep(0.2)
  46. send('<09200000000>') # 断开连接
  47. time.sleep(0.2)
  48. # -----------------------断开串口-------------------------
  49. port_close()
  50. # -----------------------结束通信-------------------------
  51. if __name__ == "__main__":
  52. ser = serial.Serial() # 获取串口
  53. set_voltage(110) # 设定110V电压
  54. while True:
  55. print(current_read()) # 循环读取当前电压
  56. time.sleep(1)

感谢各位支持,之后还会继续分享更多有用的知识!想要了解更多可以关注我或关注本专栏。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/爱喝兽奶帝天荒/article/detail/771150
推荐阅读
相关标签
  

闽ICP备14008679号