参考:(文中部分图/文字/代码来自以下文章,部分内容由于时间久远已经找不到原作者,可联系注明或删除)
PYTHON串口数据打包发送STM32接收数据解析
openmv中文文档

这里以openmv循迹代码为例
main.py

THRESHOLD = (74, 100, -128, 127, -128, 127) # 识别白线
import sensor, image, time
from pyb import LED,UARTuart = UART(3, 115200)
uart.init(115200, bits=8, parity=None, stop=1)  # 定义串口
sensor.reset()
sensor.set_vflip(True)
sensor.set_hmirror(True)
sensor.set_pixformat(sensor.RGB565)
sensor.set_framesize(sensor.QQQVGA)
clock = time.clock()def sending_data(rho_err,theta_error):    #发送函数global uartdata = ustruct.pack("<bbhhb",  # 解释见下文0x2C,0x12,int(rho_err),int(theta_error),0x5B)uart.write(data);while(True):clock.tick()img = sensor.snapshot().binary([THRESHOLD])line = img.get_regression([(100,100)], robust = True)if (line):rho_err = abs(line.rho())-img.width()/2theta_error = line.theta()if (line.theta()>90):theta_error = line.theta()-180print('rho:', rho_err, 'theta:', theta_error)img.draw_line(line.line(), color = 127)sending_data(rho_err, theta_error)  # 发送数据,这里发送了两个数据time.sleep_ms(10)

关于struct.pack:
函数原型:struct.pack(fmt, v1, v2, …)

  • fmt是格式字符串
  • v1,v2是要转换的python值,详情见下表

注1.q和Q只在机器支持64位操作时有意思;
注2.每个格式前可以有一个数字,表示个数;
注3.s格式表示一定长度的字符串,4s表示长度为4的字符串,但是p表示的是pascal字符串;
注4.P用来转换一个指针,其长度和机器字长相关;
注5.最后一个可以用来表示指针类型的,占4个字节;
为了同c中的结构体交换数据,还要考虑有的c或c++编译器使用了字节对齐,通常是以4个字节为单位的32位系统,故而struct根据本地机器字节顺序转换.可以用格式中的第一个字符来改变对齐方式.定义如下:

大端和小端的区别:
小端:较高的有效字节存放在较高的的存储器地址,较低的有效字节存放在较低的存储器地址。
大端:较高的有效字节存放在较低的存储器地址,较低的有效字节存放在较高的存储器地址。
例如0x12345678 ,在大端模式的排列:0x01(低地址),0x23,0x45,0x67,0x89(高地址)。
在小端模式的排列:0x89(低地址),0x67,0x45,0x23,0x01(高地址)。


在stm32中的代码如下:
openmv.c

#include "openmv.h"
#include "stm32f10x.h"void USART2_Init(void){ //串口2初始化并启动//GPIO端口设置GPIO_InitTypeDef GPIO_InitStructure; //串口端口配置结构体变量USART_InitTypeDef USART_InitStructure; //串口参数配置结构体变量NVIC_InitTypeDef NVIC_InitStructure;//串口中断配置结构体变量RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);  //打开串口复用时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);   //打开PC端口时钟//USART2 TX  PA2;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA2GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//设定IO口的输出速度为50MHzGPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    //复用推挽输出GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA2//USART2 RX  PA3;GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //PA3GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA3//Usart1 NVIC 配置NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0 ;//抢占优先级0NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;        //子优先级2NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;         //IRQ通道使能NVIC_Init(&NVIC_InitStructure);    //根据指定的参数初始化VIC寄存器//USART 初始化设置USART_InitStructure.USART_BaudRate = 115200;//串口波特率为115200USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;   //收发模式USART_Init(USART2, &USART_InitStructure); //初始化串口1USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启ENABLEUSART_Cmd(USART2, ENABLE);   //使能串口1//如下语句解决第1个字节无法正确发送出去的问题USART_ClearFlag(USART2, USART_FLAG_TC);       //清串口2发送标志
}//串口2中断处理函数
void USART2_IRQHandler(void)               //串口2全局中断服务函数
{u8 temp;if( USART_GetITStatus(USART2,USART_IT_RXNE)!=RESET ){USART_ClearITPendingBit(USART2,USART_IT_RXNE);//清除中断标志temp = USART_ReceiveData(USART2);Openmv_Receive_Data(temp);//openmv数据处理函数}
}u8 RxCounter1 = 0;//接受OpenMV数据里用到的
u8 RxBuffer1[18];//接受OpenMV数据里用到的数组
u16 rho_err = 0,theta_err = 0;//rho偏差和theta偏差//接收OpenMV传过来的数据
void Openmv_Receive_Data(int16_t data)
{static u8 state = 0;if(state==0&&data==0x2C){state=1;RxBuffer1[RxCounter1++]=data;}else if(state==1&&data==18){state=2;RxBuffer1[RxCounter1++]=data;}else if(state==2){RxBuffer1[RxCounter1++]=data;if(RxCounter1>19||data == 0x5B) state=3;   //最后字符是openmv[19]}else if(state==3)       //state == 3  检测是否接受到结束标志{if(RxBuffer1[RxCounter1-1] == 0x5B){state = 0;USART_ITConfig(USART2,USART_IT_RXNE,DISABLE);//关闭DTSABLE中断rho_err = RxBuffer1[3]<<8 | RxBuffer1[2];   //这时已经赋值给rho_err和theta_errtheta_err = RxBuffer1[5]<<8 | RxBuffer1[4];RxCounter1 = 0;USART_ITConfig(USART2,USART_IT_RXNE,ENABLE);//开启ENABLE中断}else   //错误{state = 0;RxCounter1=0;}}    else  //错误{state = 0;RxCounter1=0;}
}
//这段代码的原稿是一位博主贡献的,由于时间久远已经找不到原文章,侵删或联系注明

openmv.h

#ifndef __OPENMV_H_
#define __OPENMV_H_
#include "stm32f10x.h"extern u16 USART1_RX_STA;               //接受状态标记
extern u8 RxCounter1;    //接受OpenMV数据里用到的
extern u8 RxBuffer1[18];   //接受OpenMV数据里用到的数组extern u16 rho_err;
extern u16 theta_err;extern u8 state;void USART2_Init(void);//串口2初始化并启动
void Openmv_Receive_Data(int16_t data);//接收OpenMV传过来的数据
#endif

【嵌入式】openmv与stm32的串口通信相关推荐

  1. 【星曈科技】OpenMv笔记——利用OpenMV与STM32进行串口通信

    利用OpenMV与STM32进行串口通信 OpenMV端的程序 # Untitled - By: dell - 周一 7月 19 2021# Blob Detection and uart trans ...

  2. 嵌入式STM32入门之STM32基础串口通信

    STM32基础串口通信 一.前言 二.串口协议 (1)浅谈设备通信方式 (2)具体串口协议 (3)STM32的串口通信 (4)RS-232通信协议 (5)USB To TTL(CH340) 5.1 C ...

  3. 嵌入式学习笔记——STM32的USART通信概述

    文章目录 前言 常用通信协议分类及其特征介绍 通信协议 通信协议分类 1.同步异步通信 2.全双工/半双工/单工 3.现场总线/板级总线 4. 串行/并行通信 5. 有线通信.无线通信 STM32通信 ...

  4. openmv与stm32之间的通信学习(数字识别)

    前提:软件安装与学习视频讲解 在我们使用openmv中的神经网络时,在新的版本里是没有nn的库给你调用的,需要在老版本里才有,百度云链接:https://pan.baidu.com/s/1bgLiLM ...

  5. STM32 —— STM32 的串口通信

    STM32 -- STM32 的串口通信 STM32的串口通信接口有两种,分别是:UART(通用异步收发器).USART(通用同步异步收发器).而对于大容量 STM32F10x 系列芯片,分别有 3 ...

  6. Ardunio下实现STM32的串口通信及其与Stduino的区别

    摘要 本文介绍了在Ardunio下配置STM32并进行STM32的串口通信:之后我将介绍一下国人MCU开发平台Stduino与现在所使用的Arduino进行比较. 文章目录 摘要 :man_stude ...

  7. 单片机与PC机的交流———基于STM32的串口通信

    STM32之串口通信程序 前言: 一.串口通信要求 二.串口通信准备 1.硬件准备 2.软件准备 三.下载程序进入STM32 1.下载之前相关配置 2.下载 四.最终效果展示 总结: 前言: 本文主要 ...

  8. K210学习笔记(三) K210与STM32进行串口通信,K210发STM收

    文章目录 前言 一.以/r/n为结尾 二.K210端代码 三.STM32端 3.1 main函数 四.测试结果 4.1当收到1时 4.2当收到2时 4.3 测试视频 总结 前言 前面我们讲了STM32 ...

  9. 基于STM32实现串口通信输出hello windows!

    文章目录 前言 一.介绍 1.串口协议和RS-232.485标准 2.RS232.485电平与TTL电平的区别 3.USB/TTL转232模块的工作原理 二.安装 1.安装STM32CubeMX 2. ...

最新文章

  1. HDU2642(二维的树状数组)
  2. 开始测试React Native App(下篇)
  3. 跳出圈子易,再入围城难,重新学编程,且学且珍惜
  4. 360无痕浏览器_浏览器如何开启老板键?
  5. Tensorflow 错误总结:NameError: name 'core' is not defined
  6. 【slighttpd】基于lighttpd架构的Server项目实战(7)—http-parser
  7. 【转】JS windows.open()详解
  8. JAVA Java多线程与并发库
  9. LeetCode 268 缺失数字
  10. php 执行多个文件,PHP提高执行多个查询时读取一千行文件的性能
  11. 一文掌握常用的机器学习模型(免费课程+送书福利)
  12. LaTex ——P2 源文件的基本结构
  13. 搭建nuxtjs程序 —— 用户信息 or token怎么不丢失
  14. 〖Linux〗Ubuntu13.10搭建文件共享Samba服务器
  15. 聊一下《技术力量-一线技术团队成功启示录》
  16. 王思聪吃热狗 - 飞机大战小游戏
  17. linux下通过V4L2驱动USB摄像头
  18. Android开发之小程序-秒表
  19. PNG、IconFont、SVG图标使用
  20. 如何提升语音识别技术的识别能力?

热门文章

  1. locust入门:单机使用locust运行压力测试
  2. Texlive安装与环境变量配置
  3. docker安装Mysql5.7以及远程登陆链接配置
  4. C++核心编程(三)
  5. 一阶逻辑与二阶逻辑的区别一元谓词多元谓词
  6. GeneratorSqlMapCustom(mybatis逆向工程)
  7. Android数据持久化:SharePreference
  8. LeetCode简单题之二进制表示中质数个计算置位
  9. 使用PCAST检测散度以比较GPU和CPU结果
  10. ADAS系统长篇综述(下)