概観
しばらく前にプロジェクトを作成しました。システムはシリアルポートを使用してMCUと対話します。システム側のコードは、双方が合意したデータパケットプロトコルに従ってデータを解析および送信するためのコードを記述していますが、MCU側はコードを完了していないため、それらを待つことができませんコードのデバッグが完了すると、オンラインで関連情報を参照した後、プロジェクトの進行が遅れます。最後に、Pythonスクリプトを使用してシミュレーションテストのデータ分析とパッケージ化を完了することにしました。また、インターネットで多くの情報を確認し、最終的にシミュレーションデータを実現してコードのデバッグを完了しました。このスクリプトは、主にPythonシリアル(シリアルポート操作)の2つのモジュールを使用しますそして、構造体(C言語のバイト文字列にパックされます)。いくつかの簡単な説明:
シリアルモジュール
メインユーザーのシリアルポート操作、ネットワークにはたくさんの情報があります、ここにコメント用のコードがあります
class ComThread:
def __init__(self, Port='COM56'): #打开COM56
self.l_serial = None
self.alive = False
self.waitEnd = None
self.port = Port
self.ID = None
self.data = None
def waiting(self):
if not self.waitEnd is None:
self.waitEnd.wait()
def SetStopEvent(self):
if not self.waitEnd is None:
self.waitEnd.set()
self.alive = False
self.stop()
def start(self):
self.l_serial = serial.Serial()
self.l_serial.port = self.port
self.l_serial.baudrate = 115200 #串口波特率
self.l_serial.timeout = 2 #超时时间
self.l_serial.open()
if self.l_serial.isOpen():
self.waitEnd = threading.Event()
self.alive = True
self.thread_read = None
self.thread_read = threading.Thread(target=self.FirstReader)
self.thread_read.setDaemon(1)
self.thread_read.start()
return True
else:
return False
def SendDate(self,i_msg,send):
#lmsg = ''
isOK = False
#发送数据到相应的处理组件
print(i_msg)
send_buf = nwy_create_send_msg(i_msg, send)
self.l_serial.write(send_buf)
print("send success")
return True
def FirstReader(self):
while self.alive:
time.sleep(0.1)
data = ''
data = data.encode('utf-8')
n = self.l_serial.inWaiting()
if n:
data = data + self.l_serial.read(n)
print(len(data))#打印收到的数据
print(data.hex()) #按照十六进制打印
def stop(self):
self.alive = False
self.thread_read.join()
if self.l_serial.isOpen():
self.l_serial.close()
def quit(signum, frame):
print("Bye Bye!")
sys.exit(0)
#调用串口,测试串口
def main():
rt = ComThread()
rt.sendport = '**1*80*'
try:
if rt.start():
signal.signal(signal.SIGINT, quit)
print(rt.l_serial.name)
#rt.waiting()
#print("The data is:%s,The Id is:%s"%(rt.data,rt.ID))
#t.stop()
else:
pass
except Exception as se:
print(str(se))
print ('End OK .')
return rt
if __name__ == '__main__':
mSerial = main()
while True:
time.sleep(1)
構造体モジュール
シリアルデータ分析。ここでは、分析にアンパックを使用していません。これは、現在の定義による分析です。
def parse_read_data(data, len):
print(data)
print(len)
#check head
if 0x0F != data[0]:#判断数据头
print ("head is not 0x0F data head is " + hex(data[0]))
return False
#get msg id
msg_id = data[1] << 8 | data[2] #获取消息ID
msg_len = data[3] << 8 | data[4] #获取数据长度
data_crc = data[7+msg_len] #获取数据的校验和
Cal_crc = Calculation_crc(data[1:len-2]) #计算数据的校验和
if data_crc != Cal_crc: #判断数据的校验和
print ("crc error ")
return False
print ("data is good")
#do something
#处理数据
return True
送信するデータを固定形式のバイト文字列にパックします。具体的なパッキングは、実際のプロトコルに従ってパックする必要があります。strcutの詳細な説明は多すぎるため、ここでは繰り返しません。
def create_send_msg(i_msg, send):
msg_len = len(send)
msg_len_2 = ~msg_len
#下面就类似于c预言的printf 不过可以查查struct中对应的类型
# !表示大端
# H unsigned short
# h singned short 这里用h主要是长度的反码如果有无符号会提示存不下,所以用有符号
# %ds 这个比较特殊,s为字节串,长度为%d
# B byte
psh = struct.pack('!HHh%ds'%len(send), i_msg, msg_len, msg_len_2,send)
# 计算crc
crc = Calculation_crc(psh)
# c语言的结构体定义如下
# struct{
# unsigned char header
# unsigned short msgid
# unsigned short msglen
# signed short unmsglen
# char *data
# unsigned char crc
# unsigned char end
# }
pshhh = struct.pack('!BHHh%dsBB' %len(send), MSG_HEADER, i_msg, msg_len, msg_len_2,send, crc, MSG_END)
return pshhh
完全なサンプルコードは次のとおりです
import struct
import binascii
import sys
import signal
import threading
import time
import serial
import random
MSG_HEADER=0x0F
MSG_END=0xF0
MCU_MSG_ID=0x0001
def create_send_msg(i_msg, send):
msg_len = len(send)
msg_len_2 = ~msg_len
#下面就类似于c预言的printf 不过可以查查struct中对应的类型
# !表示大端
# H unsigned short
# h singned short 这里用h主要是长度的反码如果有无符号会提示存不下,所以用有符号
# %ds 这个比较特殊,s为字节串,长度为%d
# B byte
psh = struct.pack('!HHh%ds'%len(send), i_msg, msg_len, msg_len_2,send)
# 计算crc
crc = Calculation_crc(psh)
# c语言的结构体定义如下
# struct{
# unsigned char header
# unsigned short msgid
# unsigned short msglen
# signed short unmsglen
# char *data
# unsigned char crc
# unsigned char end
# }
pshhh = struct.pack('!BHHh%dsBB' %len(send), MSG_HEADER, i_msg, msg_len, msg_len_2,send, crc, MSG_END)
return pshhh
def send_mcu_data(data):
msg = "FF000000FFECFFD7FC03000000000000"; #模拟的一包数据
by = binascii.a2b_hex(msg)
mSerial.SendDate(MCU_MSG_ID, by)
return
#计算校验和
def Calculation_crc(data):
crc = 0
for i in range(len(data)):
crc ^= data[i]
return crc
def parse_read_data(data, len):
print(data)
print(len)
#check head
if 0x0F != data[0]:#判断数据头
print ("head is not 0x0F data head is " + hex(data[0]))
return False
#get msg id
msg_id = data[1] << 8 | data[2] #获取消息ID
msg_len = data[3] << 8 | data[4] #获取数据长度
data_crc = data[7+msg_len] #获取数据的校验和
Cal_crc = Calculation_crc(data[1:len-2]) #计算数据的校验和
if data_crc != Cal_crc: #判断数据的校验和
print ("crc error ")
return False
print ("data is good")
#do something
#处理数据
return True
class ComThread:
def __init__(self, Port='COM56'):
self.l_serial = None
self.alive = False
self.waitEnd = None
self.port = Port
self.ID = None
self.data = None
def waiting(self):
if not self.waitEnd is None:
self.waitEnd.wait()
def SetStopEvent(self):
if not self.waitEnd is None:
self.waitEnd.set()
self.alive = False
self.stop()
def start(self):
self.l_serial = serial.Serial()
self.l_serial.port = self.port
self.l_serial.baudrate = 230400
self.l_serial.timeout = 2
self.l_serial.open()
if self.l_serial.isOpen():
self.waitEnd = threading.Event()
self.alive = True
self.thread_read = None
self.thread_read = threading.Thread(target=self.FirstReader)
self.thread_read.setDaemon(1)
self.thread_read.start()
return True
else:
return False
def SendDate(self,i_msg,send):
send_buf = create_send_msg(i_msg, send)
self.l_serial.write(send_buf)
print("send success")
return True
def FirstReader(self):
while self.alive:
time.sleep(0.1)
data = ''
data = data.encode('utf-8')
n = self.l_serial.inWaiting()
if n:
data = data + self.l_serial.read(n)
#print(len(data))
#print(data.hex())
parse_read_data(data, len(data))
def stop(self):
self.alive = False
self.thread_read.join()
if self.l_serial.isOpen():
self.l_serial.close()
def quit(signum, frame):
print("Bye Bye!")
sys.exit(0)
#调用串口,测试串口
def main():
rt = ComThread()
rt.sendport = '**1*80*'
try:
if rt.start():
signal.signal(signal.SIGINT, quit)
print(rt.l_serial.name)
else:
pass
except Exception as se:
print(str(se))
print ('End OK .')
return rt
if __name__ == '__main__':
mSerial = main()
while True:
time.sleep(1)
#发送给系统数据
send_mcu_data(mSerial)
上記は私の共有です、あなたが探索する必要がある場合は、qq 991410485を追加できます