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语言中,我们可以很方便地用struct
、union
来处理字节,以及字节和int
,float
的转换。
好在Python
提供了一个struct
模块来解决bytes
和其他二进制数据类型的转换。
struct
的pack
函数把任意数据类型变成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)