【嵌入式】openmv与stm32的串口通信

这篇具有很好参考价值的文章主要介绍了【嵌入式】openmv与stm32的串口通信。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

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

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

THRESHOLD = (74, 100, -128, 127, -128, 127) # 识别白线
import sensor, image, time
from pyb import LED,UART

uart = 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 uart
    data = 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()/2
        theta_error = line.theta()
        if (line.theta()>90):
            theta_error = line.theta()-180
        print('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值,详情见下表
    stm32与openmv串口通信,stm32,openmv,串口通信

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

大端和小端的区别:
小端:较高的有效字节存放在较高的的存储器地址,较低的有效字节存放在较低的存储器地址。
大端:较高的有效字节存放在较低的存储器地址,较低的有效字节存放在较高的存储器地址。
例如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; //PA2
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//设定IO口的输出速度为50MHz
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
    GPIO_Init(GPIOA, &GPIO_InitStructure); //初始化PA2
    //USART2 RX  PA3;
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3; //PA3
    GPIO_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 ;//抢占优先级0
	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;		//子优先级2
	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器

    //USART 初始化设置
	USART_InitStructure.USART_BaudRate = 115200;//串口波特率为115200
	USART_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); //初始化串口1

    USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启ENABLE
    USART_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_err
			theta_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文章来源地址https://www.toymoban.com/news/detail-620220.html

#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的串口通信的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 嵌入式学习笔记——STM32的USART收发字符串及串口中断

    上一篇中,介绍了串口收发相关的寄存器,通过代码实现了一个字节的收发,本文接着上面的内容,通过功能函数实现字符串的收发,然后引入中断解决收发过程中while()死等的问题。 根据昨天的字符发送函数,只需要稍作修改即可实现发送函数了,一个字符串的结尾会有一

    2024年02月03日
    浏览(75)
  • 嵌入式学习笔记——STM32的USART通信概述

    上两篇文章中,已经实现了GPIO的通用输出以及通用输出模式,从本文开始,笔者将开始有关GPIO的复用功能的介绍,首先是最常用复用功能——串口,本文主要是介绍一些关于通信以及串口的基本概念。 通信协议:通信双方进行信息交换(接收或发送)要满足的规则,而这个规

    2023年04月08日
    浏览(55)
  • 嵌入式开发--STM32用DMA+IDLE中断方式串口接收不定长数据

    之前讲过用 利用IDLE空闲中断来接收不定长数据 ,但是没有用到DMA,其实用DMA会更加的高效,MCU也可以腾出更多的性能去处理应该做的事情。 IDLE顾名思义,就是空闲的意思,即当监测到串口空闲超过1个串口的数据帧时,会使状态寄存器(SR或ISR)的IDLE位置位,如果此时控制

    2024年04月17日
    浏览(60)
  • [嵌入式软件][启蒙篇][仿真平台] STM32F103实现串口输出输入、ADC采集

    上一篇:[嵌入式软件][启蒙篇][仿真平台] STM32F103实现LED、按键 学C语言时,使用的printf()函数,就是通过串口打印出来的。 跟外部器件通信,比如GPS模块、蓝牙模块、wifi模块; 两个开发板之间通信,制定私有协议。 PC电脑通信,使用上位机显示数据或控制下位机。 操作:打

    2024年01月22日
    浏览(65)
  • 通信工程毕设 Stm32酒驾检查系统 - 单片机 嵌入式 物联网

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月19日
    浏览(131)
  • 通信工程毕设 Stm32单片机的音乐播放器设计 - 物联网 嵌入式

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月19日
    浏览(52)
  • 通信工程毕设 stm32智能运动计步系统 - 物联网 嵌入式 单片机

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月21日
    浏览(120)
  • 通信工程毕设 基于Stm32的便携体测仪(心率 体温) - 单片机 嵌入式 物联网

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年02月20日
    浏览(53)
  • 【嵌入式基础】串口通信操作实例

    本文主要介绍流水灯实验和串口通信的实验过程,对串口协议和RS-232标准,RS232电平与TTL电平的区别,以及\\\"USB/TTL转232\\\"模块(以CH340芯片模块为例)的工作原理这些知识也有了一定的涉及。 目录 一、了解串口协议以及\\\"USB/TTL转232\\\"模块的工作原理 1、串口协议 2、RS-232标准 3、

    2024年02月01日
    浏览(61)
  • 通信工程毕设 单片机自动写字机器人设计与实现 - 物联网 嵌入式 stm32

    🔥 这两年开始毕业设计和毕业答辩的要求和难度不断提升,传统的毕设题目缺少创新和亮点,往往达不到毕业答辩的要求,这两年不断有学弟学妹告诉学长自己做的项目系统达不到老师的要求。 为了大家能够顺利以及最少的精力通过毕设,学长分享优质毕业设计项目,今天

    2024年01月15日
    浏览(65)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包