Python串口操作

本文介绍了Python中使用serial库进行串口通信,包括如何发送16进制数据,并展示了struct库在处理二进制数据时的作用,如打包和解包数据。示例代码演示了如何发送字符串以及如何将数据转换为不同进制。同时,文章讲解了struct的对齐方式和格式符,帮助理解如何与C语言结构体进行交互。
摘要由CSDN通过智能技术生成

1.Python串口

1).serial

(1)串口发送16进制
    def data_send(self):
        if self.ser.isOpen():
            # 数据帧
            input_s = '68 AA AA AA AA AA AA 68 11 04 34 37 33 37 B6 16'

            # 简单的发送16进制字符
            # ser.write(b'\xFE\xFE\xFE')
            # 但是上面的方法不够优雅,需要自己添加\x,非常麻烦,于是使用下面这个方法
            input_s = bytes.fromhex(input_s)
            
            if input_s != "":
                # ascii发送
                # input_s = (input_s + b'FF')

                num = self.ser.write(input_s)
                self.data_num_send += num
        else:
            pass
想要发送字符串就直接字符串发送就行

2).struct

用来将数据进行转换

按照指定格式将Python数据转换为字符串,该字符串为字节流,如网络传输时,不能传输int,此时先将int转化为字节流,然后再发送;
按照指定格式将字节流转换为Python指定的数据类型;
处理二进制数据,如果用struct来处理文件的话,需要用’wb’,’rb’以二进制(字节流)写,读的方式来处理文件;
处理c语言中的结构体;

struct模块中的函数
函数	return返回的数据类型	explain

pack(fmt,v1,v2…)	string	按照给定的格式(fmt),把数据转换成字符串(字节流),并将该字符串返回.

pack_into(fmt,buffer,offset,v1,v2…)	None	按照给定的格式(fmt),将数据转换成字符串(字节流),并将字节流写入以offset开始的buffer中.(buffer为可写的缓冲区,可用array模块)

unpack(fmt,v1,v2…..)	tuple	按照给定的格式(fmt)解析字节流,并返回解析结果

pack_from(fmt,buffer,offset)	tuple	按照给定的格式(fmt)解析以offset开始的缓冲区,并返回解析结果

calcsize(fmt)	size of fmt	计算给定的格式(fmt)占用多少字节的内存,注意对齐方式

当打包或者解包的时,需要按照特定的方式来打包或者解包.该方式就是格式化字符串,它指定了数据类型,除此之外,还有用于控制字节顺序、大小和对齐方式的特殊字符.

发送字符串

mSerial.send_data(struct.pack('5s', 'hello'.encode('utf-8')))
#必须要转换成utf-8才能打包成二进制
(1)对齐方式
为了同c中的结构体交换数据,还要考虑c或c++编译器使用了字节对齐,通常是以4个字节为单位的32位系统,故而struct根据本地机器字节顺序转换.可以用格式中的第一个字符来改变对齐方式.定义如下

在这里插入图片描述

(2)格式符

在这里插入图片描述

_Bool在C99中定义,如果没有这个类型,则将这个类型视为char,一个字节;
q和Q只适用于64位机器;
每个格式前可以有一个数字,表示这个类型的个数,如s格式表示一定长度的字符串,4s表示长度为4的字符串;4i表示四个int;
P用来转换一个指针,其长度和计算机相关;
f和d的长度和计算机相关;
进制转化:

获取用户输入十进制数

dec = int(input("输入数字:"))

print("十进制数为:", dec)
print("转换为二进制为:", bin(dec))
print("转换为八进制为:", oct(dec))
print("转换为十六进制为:", hex(dec))
16进制转10进制: int('0x10', 16)  ==>  16

Python没有专门处理字节的数据类型。但由于b'str’可以表示字节,所以,字节数组=二进制str。而在C语言中,我们可以很方便地用structunion来处理字节,以及字节和intfloat的转换。

好在Python提供了一个struct模块来解决bytes和其他二进制数据类型的转换。

structpack函数把任意数据类型变成bytes

import struct
struct.pack('>I', 10240099)
b'\x00\x9c@c'
pack的第一个参数是处理指令,'>I'的意思是:
表示字节顺序是big-endian,也就是网络序,I表示4字节无符号整数。

后面的参数个数要和处理指令一致。

unpack把bytes变成相应的数据类型:

struct.unpack('>IH', b'\xf0\xf0\xf0\xf0\x80\x80')
(4042322160, 32896)
根据>IH的说明,后面的bytes依次变为I:4字节无符号整数和H:2字节无符号整数。

所以,尽管Python不适合编写底层操作字节流的代码,但在对性能要求不高的地方,利用struct就方便多了。

log = 0

class SerialPort:
    def __init__(self, port, buand):
        self.serial_port = serial.Serial(port,buand,bytesize=8)
        if not self.serial_port.isOpen():
            self.serial_port.open()
        print(self.serial_port.is_open)  # 检验串口是否打开

    def port_open(self):
        if not self.serial_port.isOpen():
            self.serial_port.open()


    def port_close(self):
        self.serial_port.close()

    def send_data(self, send_datas):
        self.serial_port.write(send_datas)

    def read_data(self, byte_num):
        data = self.serial_port.read(byte_num)
        return data

#初始化串口类
serialPort = 'COM3'  # 串口
baudRate = 115200  # 波特率
mSerial = SerialPort(serialPort, baudRate)

while (1):
    #读取数据
    s=mSerial.read_data(5)
    #转化为字符串
    s = struct.unpack('>ccccc', s)[4]
    # mSerial.send_data(struct.pack('5s', 'hello'.encode('utf-8')))


    log += 1  # 传输次数记录+1

    print(log, s)
  • 0
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

wzhhn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值