基于Openmv通信进行数据帧的发送与接收

本文介绍了如何在STM32中使用Python进行UART通信,包括库的导入、UART初始化、发送和接收数据帧的方法,以及状态机在数据解析中的应用。还提到了异常处理步骤,如波特率设置、硬件连接和数据链路层检查。
摘要由CSDN通过智能技术生成

1、首先进行库的调用

import sensor, image, time
from pyb import UART
import json

2、进行UART的初始化定义

uart = UART(3,3000000,timeout_char=1000)   #定义串口3变量
uart.init(3000000, bits=8, parity=None, stop=1) # init with given parameters

 3、定义发送数据帧的函数

def send_data(x,a):
    global uart
    data =ustruct.pack("<bbhhb",
                    0x2c,
                    0x12,
                    int(x),
                    int(a),
                    0x5b
                    )
    uart.write(data)

注意项:

①global函数的作用为使自定义的函数可以改变全局变量的值

②ustruct.pack(fmt,v1,v2,..)函数的作用为根据格式字符串fmt,打包 v1, v2, … 值。返回值为一个解码该值的字节对象

其中对应数据格式有以下情况:(首位符号表示格式声明符号,最后一位表示字节数)

x pad byte no value 1

c char string of length 1 1

b signed char integer 1

B unsigned char integer 1

? _Bool bool 1

h short integer 2

H unsigned short integer 2

i int integer 4

I unsigned int integer or long 4

l long integer 4

L unsigned long long 4

q long long long 8

Q unsigned long long long 8

f float float 4

d double float 8

s char[] string 1

p char[] string 1

P void * long

例如在上面发送程序可以看见依次为b对应0x2c,b对应0x12,h对应int(x),h对应int(a),b对应0x5b。

当接收端进行数据接收时,一字节数据可以直接进行接收显示,但是两字节的数据需要进行处理,需要先明白发送数据时是先发送数据的高位还是数据的地位,然后根据此对接收到的高位数据进行移位操作移动至高位在与低位数据进行相加即可。

例如我用STM32进行接收,当接收到来自openmv端发送来的h型数据,将数据存放至自己定义的Serial_RxPacket[]数组缓冲区中的第一位和第二位则进行如下操作(已经假定先被接收的为数据的低位),方可获得想要的数据。

data = ((Serial_RxPacket[1]<<8)+Serial_RxPacket[0])

③uart.write(data)函数的作用为将data数据进行串口发送

4、定义接收数据帧的函数

state=0  #状态标识
rx_buff=[0]*2   #数据接收缓存区
id_tixu=0x0000  #定义ID号接收缓存区
def read_data():
    global id_tixu;
    global state;
    if uart.any():  #进行串口数据的接收
            #res=uart.read(1)  #表示为读取一个十六进制数,这里的uart必须是例化的
            #state表示处理接收到的第几位数据
            for i in range(5):
                if state == 0:
                    res=uart.read(1)
                    res = ustruct.unpack("B", res)  #表示将res数据按照B格式进行解包
                    res = hex(res)
                    data = res[0:4]
                    if data == '0x2c': #帧头1
                        state = 1
                elif state == 1:
                    res=uart.read(1)
                    res = ustruct.unpack("B", res)
                    res = hex(res)
                    for i in range(4):
                        data = res[0:4]
                    id_tixu=data
                    #print(id_tixu)
                    state = 2
                elif state == 2:
                    res=uart.read(2)
                    res = ustruct.unpack("B", res)
                    res = hex(res)
                    res = int(res)
                    rx_buff[0]=res  #数据1
                    #print(res)
                    state = 3
                elif state == 3:
                    #res=uart.read(1)
                    res=uart.read(2)
                    res = ustruct.unpack("B", res)
                    res = hex(res)      #str
                    res = int(res)
                    rx_buff[1]=res  #数据2
                    #print(res)
                    state = 4
                elif state == 4:
                    res=uart.read(1)
                    res = ustruct.unpack("B", res)
                    res = hex(res)
                    data = res[0:4]
                    if data == '0x5b': #帧尾
                        state = 0
                        #数据处理处
                        #print(rx_buff)
                    else:
                        state = 0

上述代码采用的是状态机的思维方式进行数据帧的接收与解析。

①uart.any()返回等待的字节数量,表示接收到了数据

②uart.read(n)表示读取了n个字节的数据,1就表示读取了一个字节,2就表示读取了两个字节

③ustruct.unpack(fmt,data)表示根据格式字符串 fmt 对数据进行解压。返回值为一个解压值元组。

④对数据解压后就可以进行数据的处理。res = hex(res)表示将res数据转换成hex形式,即16进制的形式。数据帧已经接收完毕,对于数据的处理方式不再过多进行阐述。

5、关于函数的调用

可以用下面的代码自行参悟

while(True):
    clock.tick()
    img = sensor.snapshot()
    read_data()
    send_da(1,55,11)
    print(id_tixu)
    print(rx_buff)

6、关于数据发送接收异常的处理办法

①首先检查UART的初始化设置,例如波特率等是否设置正确

②检查硬件串口接线是否连接正确,是否有共地

③使用串口模块与串口助手进行数据链路层的数据上的发送与接收,查看是否数据发送和接收有异常,若无异常显示不正确的数据,则可能是数据处理逻辑代码有问题,若异常则可能是①、②的原因,可以仔细检查,当然也有可能是时钟晶振本身存在的误差导致,若如此可以采取换一个高精度符合要求的晶振。

④若以上原因都不符合还是会出现异常数据,可能是电气特性导致,可以用示波器或者逻辑分析仪检查传输信息是波形及电平的多少,发送端和接收端电平是否一致,若不一致可以参考RS232或者RS485协议。

  • 8
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

洛铁生花

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

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

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

打赏作者

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

抵扣说明:

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

余额充值