精华内容
下载资源
问答
  • Openmv与STM32通信.zip

    2020-05-09 10:28:53
    该文件包括三部分,一个是openmv的官方云台三维模型,可直接打印,一个是openmv的程序,该程序可同时识别三个颜色,本程序中同时识别了红绿蓝,识别后返回颜色顺序,通过串口通信stm32主控,并在LCD屏幕上显示识别...
  • The first generation of OpenMV cameras is based on STM32 ARM Cortex-M Digital Signal Processors (DSPs) and OmniVision sensors. The boards have built-in RGB and IR LEDs, USB FS support for programming ...
  • OPENMV与STM32串口通信

    2021-03-26 10:07:01
    OPENMV与STM32串口通信 openmv串口配置: uart = UART(1, 115200) #串口1,波特率115200 uart.init(115200, bits=8, parity=None, stop=1) #8位数据位,无校验位,1位停止位 openmv数据发送: uart.write(bytearray...

    OPENMV与STM32串口通信
    openmv串口配置:
    uart = UART(1, 115200) #串口1,波特率115200
    uart.init(115200, bits=8, parity=None, stop=1) #8位数据位,无校验位,1位停止位
    openmv数据发送:
    uart.write(bytearray(frame))
    openmv数据接收:
    if uart.any(): #用于接收串口数据
    recvData = uart.readline()

    展开全文
  • Openmv Stm32f407通信

    千次阅读 2020-12-20 12:28:48
    Openmv Stm32f407通信入门学习记录大概思路代码 入门学习记录 学习中接触到了openmv ,发现视觉也挺好玩的,openmv视觉处理的数据经常要传到另一个单片机,这里openmv用的是stm32h7,用的串口为串口3。控制板是stm...

    Openmv 与 Stm32f407通信

    入门学习记录

    学习中接触到了openmv ,发现视觉也挺好玩的,openmv视觉处理的数据经常要传到另一个单片机,这里openmv用的是stm32h7,用的串口为串口3。控制板是stm32f407zgt6,用的串口是串口2。
    目的是将openmv的数据通过串口传到控制板并在oled上面显示。

    大概思路

    两个单片机用串口通信,必须把自己的串口配置好。stm32f407串口2的配置在上一个文章讲了;openmv的串口直接调用。双方约定好波特率就可以通信了。难的是数据的处理,在用单片机与电脑通信的时候会发现有时候得到一些乱码,主要是串口有可能一直在发送数据,这不是我们希望得到的。在电脑串口助手观察十六进制会发现在我们要的信息前面有乱码的十六进制,因此在我们需要的数据前面自己加两个已知的数,接收的时候判断到了这两个数就可以认为接下来的就是我们要的数据,这两个数就是所谓的“帧头”,以帧发送数据比较常用,帧头和数据比较重要,其它可以省略,具体可以百度。
    在这里插入图片描述
    1.配置串口,约定好波特率
    2.IO接线,RX接TX
    3.传数据,收数据。openmv的数据要用 bytearray()函数将数据转化为字节形式传到控制板
    4.数据处理

    代码

    openmv

    import time
    from pyb import UART
    
    uart = UART(3, 115200)  //波特率为115200
    
    while(True):
        FH = bytearray([0xb3,0xb3])  //帧头,控制板接收数据以后判断,转化为字节传送,不能用16进制直接传
        uart.write(FH)    //写到串口
        uart.write("123321")   /// 写数据
        FH = bytearray([0x0d,0x0a])   //结束标志  ,换行和回车的ascll
        uart.write(FH)
        time.sleep(1000)
    

    main.c

    #include "sys.h"     //没有的头文件要删掉
    #include "delay.h"
    #include "usart.h"
    #include "led.h"
    #include "beep.h"
    #include "key.h"
    #include "oled.h"
    
    u8 UsartDisPlay[200];  // oled上面显示的
    
    int main(void)
    { 
    	u8 t,n;
    	u8 len;	
    	u16 times=0; 
    	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);//设置系统中断优先级分组2
    	delay_init(168);		//延迟初始化
    	uart2_init(115200);  //波特率为115200
    	LED_Init();		  	
    	OLED_Init();  //oled初始化
    	while(1)
    	{
    			if(USART2_RX_STA&0x8000)
    		{					   
    			len=USART2_RX_STA&0x3fff;//得到此次接收到的数据长度
    			for(t=0;t<len;t++)
    			{
    				 if(USART2_RX_BUF[t]==0xb3)     //判断帧头,即我们加的两个数
    					 if(USART2_RX_BUF[t+1]==0xb3)
    						  n=t+2;    //记录我们需要数据的位置
    			}
    			for(t=0;n<len;t++,n++)
    				UsartDisPlay[t] = USART2_RX_BUF[n];  // 将我们需要的数据在oled上面显示,便于观察是否正确
    			OLED_ShowString(1,1,UsartDisPlay);
    			USART2_RX_STA=0;
    		}else
    		{
    			times++;
    			if(times%5000==0)
    			{
    			     LED1=!LED1;
    			} 
    			if(times%30==0)LED0=!LED0;  //闪烁LED,提示系统正在运行
    			delay_ms(10);
    		}			
    	}
    }
    

    ![在这里在这里插入图片描述
    stm32f407zgt6串口配置的代码在上一篇文章。

    展开全文
  • 之前用openmv进行颜色识别然后与STM32通过串口通信,但是STM32接收到的图像中心坐标与openmv中的实际坐标有时候会不同。所以想尝试一下openmv与STM32之间到其他通信方式,
  • 超详细OpenMV与STM32单片机通信

    多人点赞 热门讨论 2021-05-04 01:56:49
    最近在做电磁炮,发现题目需要用到颜色跟踪,于是花了一点时间学了一下OpenMV,只学习OpenMV是远远不够的,还需要实现单片机的通信,本以为很简单,在CSDN上找了一些代码,直接拿来修改粘贴,把代码看明白了,这些...

    1.前言(闲话)

    最近在做电磁炮,发现题目需要用到颜色跟踪,于是花了一点时间学了一下OpenMV,只学习OpenMV是远远不够的,还需要实现与单片机的通信,本以为很简单,在CSDN上找了一些代码,直接拿来修改粘贴,把代码看明白了,这些只花了几个小时,本以为自己已经弄明白了二者之间的通信,但是在后期把OpenMV端数据传输到单片机的时候却犯了难。我选择使用OLED显示传输的数据,在这里调试了许久,中间遇到了许多之前的学习漏洞,特在此写下博客记录学习经历。*

    2.硬件连接

    我所用到的材料如下: 四针IIC OLED,OpenMV(OV7725),STM32F103C8T6最小系统板,数据线N条(OpenMV的数据线只能用官方自带的,其他的基本都用不了),杜邦线若干。

    1.OpenMV端:由图知UART_RX—P5 ------ UART_TX—P4
    OpenMV引脚说明图
    2.STM32端:USART_TX—PA9 -----USART_RX—PA10
    STM32F10xC8T63.四针OLED IIC连接:SDA—PA2-----SCL—PA1 由于使用的是模拟IIC而不是硬件IIC,可以根据个人需要修改IO口来控制SDA线和SCL线,只需要简单修改一下代码即可。
    4.STM32的TX(RX)接OpenMV的RX(TX),OLED连接到STM32即可。

    3.软件代码———OpenMV端

    import sensor, image, time,math,pyb
    from pyb import UART,LED
    import json
    import ustruct
    
    sensor.reset()
    sensor.set_pixformat(sensor.RGB565)
    sensor.set_framesize(sensor.QVGA)
    sensor.skip_frames(time = 2000)
    sensor.set_auto_gain(False) # must be turned off for color tracking
    sensor.set_auto_whitebal(False) # must be turned off for color tracking
    red_threshold_01=(10, 100, 127, 32, -43, 67)
    clock = time.clock()
    
    uart = UART(3,115200)   #定义串口3变量
    uart.init(115200, bits=8, parity=None, stop=1) # init with given parameters
    
    def find_max(blobs):    #定义寻找色块面积最大的函数
        max_size=0
        for blob in blobs:
            if blob.pixels() > max_size:
                max_blob=blob
                max_size = blob.pixels()
        return max_blob
    
    
    def sending_data(cx,cy,cw,ch):
        global uart;
        #frame=[0x2C,18,cx%0xff,int(cx/0xff),cy%0xff,int(cy/0xff),0x5B];
        #data = bytearray(frame)
        data = ustruct.pack("<bbhhhhb",      #格式为俩个字符俩个短整型(2字节)
                       0x2C,                      #帧头1
                       0x12,                      #帧头2
                       int(cx), # up sample by 4   #数据1
                       int(cy), # up sample by 4    #数据2
                       int(cw), # up sample by 4    #数据1
                       int(ch), # up sample by 4    #数据2
                       0x5B)
        uart.write(data);   #必须要传入一个字节数组
    
    
    while(True):
        clock.tick()
        img = sensor.snapshot()
        blobs = img.find_blobs([red_threshold_01])
        cx=0;cy=0;
        if blobs:
            	max_b = find_max(blobs)
                #如果找到了目标颜色
                cx=max_b[5]
                cy=max_b[6]
                cw=max_b[2]
                ch=max_b[3]
                img.draw_rectangle(max_b[0:4]) # rect
                img.draw_cross(max_b[5], max_b[6]) # cx, cy
                FH = bytearray([0x2C,0x12,cx,cy,cw,ch,0x5B])
                #sending_data(cx,cy,cw,ch)
                uart.write(FH)
                print(cx,cy,cw,ch)
    

    bytearray([, , ,])组合uart.write()的作用与直接调用sending_data(cx,cy,cw,ch)作用是一样的

    4.软件代码———STM32端

    工程总共包含如下文件:main.c、iic.c、iic.h、oled.c、oled.h、uart.c、uart.h。由于OLED的代码存在版权问题,需要的可以邮箱私发。

    /***** oled.h *****/

    #ifndef __USART_H
    #define __USART_H
    #include "sys.h"
    void USART1_Init(void);//串口1初始化并启动
    #endif
    

    /***** oled.c *****/

    #include "uart.h"
    #include "oled.h"
    #include "stdio.h"
    
    static u8 Cx=0,Cy=0,Cw=0,Ch=0;
    
    void USART1_Init(void)
    {
    	 	//USART1_TX:PA 9   
    		//USART1_RX:PA10
    		GPIO_InitTypeDef GPIO_InitStructure;     //串口端口配置结构体变量
    		USART_InitTypeDef USART_InitStructure;   //串口参数配置结构体变量
    		NVIC_InitTypeDef NVIC_InitStructure;     //串口中断配置结构体变量
    
    		RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);	
    		RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);   //打开PA端口时钟
    
        	//USART1_TX   PA9
        	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9;          		 //PA9
       		GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;  		 //设定IO口的输出速度为50MHz
        	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	   		 //复用推挽输出
        	GPIO_Init(GPIOA, &GPIO_InitStructure);             	 	 //初始化PA9
        	//USART1_RX	  PA10
        	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;             //PA10
        	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;  //浮空输入
        	GPIO_Init(GPIOA, &GPIO_InitStructure);                 //初始化PA10 
    
        	//USART1 NVIC 配置
        	NVIC_InitStructure.NVIC_IRQChannel = USART1_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(USART1, &USART_InitStructure);                     //初始化串口1
    
        	USART_ITConfig(USART1, USART_IT_RXNE, ENABLE); //使能中断
       		USART_Cmd(USART1, ENABLE);                     //使能串口1
    	  	USART_ClearFlag(USART1, USART_FLAG_TC);        //清串口1发送标志
    		
    }
    
    //USART1 全局中断服务函数
    void USART1_IRQHandler(void)			 
    {
    		u8 com_data; 
    		u8 i;
    		static u8 RxCounter1=0;
    		static u16 RxBuffer1[10]={0};
    		static u8 RxState = 0;	
    		static u8 RxFlag1 = 0;
    
    		if( USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET)  	   //接收中断  
    		{
    				USART_ClearITPendingBit(USART1,USART_IT_RXNE);   //清除中断标志
    				com_data = USART_ReceiveData(USART1);
    			
    				if(RxState==0&&com_data==0x2C)  //0x2c帧头
    				{
    					RxState=1;
    					RxBuffer1[RxCounter1++]=com_data;OLED_Refresh();
    				}
    		
    				else if(RxState==1&&com_data==0x12)  //0x12帧头
    				{
    					RxState=2;
    					RxBuffer1[RxCounter1++]=com_data;
    				}
    		
    				else if(RxState==2)
    				{
    					RxBuffer1[RxCounter1++]=com_data;
    
    					if(RxCounter1>=10||com_data == 0x5B)       //RxBuffer1接受满了,接收数据结束
    					{
    						RxState=3;
    						RxFlag1=1;
    						Cx=RxBuffer1[RxCounter1-5];
    						Cy=RxBuffer1[RxCounter1-4];
    						Cw=RxBuffer1[RxCounter1-3];
    						Ch=RxBuffer1[RxCounter1-2];
    
    					}
    				}
    		
    				else if(RxState==3)		//检测是否接受到结束标志
    				{
    						if(RxBuffer1[RxCounter1-1] == 0x5B)
    						{
    									USART_ITConfig(USART1,USART_IT_RXNE,DISABLE);//关闭DTSABLE中断
    									if(RxFlag1)
    									{
    									OLED_Refresh();
    									OLED_ShowNum(0, 0,Cx,3,16,1);
    									OLED_ShowNum(0,17,Cy,3,16,1);
    									OLED_ShowNum(0,33,Cw,3,16,1);
    									OLED_ShowNum(0,49,Ch,3,16,1);
    									}
    									RxFlag1 = 0;
    									RxCounter1 = 0;
    									RxState = 0;
    									USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
    						}
    						else   //接收错误
    						{
    									RxState = 0;
    									RxCounter1=0;
    									for(i=0;i<10;i++)
    									{
    											RxBuffer1[i]=0x00;      //将存放数据数组清零
    									}
    						}
    				} 
    	
    				else   //接收异常
    				{
    						RxState = 0;
    						RxCounter1=0;
    						for(i=0;i<10;i++)
    						{
    								RxBuffer1[i]=0x00;      //将存放数据数组清零
    						}
    				}
    
    		}
    		
    }
    

    解释:OpenMV发送数据包给STM32,STM32利用中断接收数据并把数据存放在RxBuffer1这个数组里,并且在中断中利用OLED显示cx,cy,cw,ch四个坐标。在中断中,有如下函数:

    else if(RxState==2)
    				{
    					RxBuffer1[RxCounter1++]=com_data;
    
    					if(RxCounter1>=10||com_data == 0x5B)       //RxBuffer1接受满了,接收数据结束
    					{
    						RxState=3;
    						RxFlag1=1;
    						Cx=RxBuffer1[RxCounter-5];
    						Cy=RxBuffer1[RxCounter-4];
    						Cw=RxBuffer1[RxCounter-3];
    						Ch=RxBuffer1[RxCounter1-2];
    
    					}
    				}
    

    RxBuffer1是一个装有接收OpenMV数据的数组,RxCounter1起着一个计数器的作用,当RxBuffer[RxCounter1-1]存放的数据为数据包的帧位时,说明已经接收成功整个数据包,此时RxBuffer[RxCounter1-2]存放ch坐标值,RxBuffer[RxCounter1-3]存放cw坐标值,RxBuffer[RxCounter1-4]存放cy坐标值,RxBuffer[RxCounter1-5]存放cx坐标值,此后在RxState=3过程中将这四个坐标显示出来即可。
    特别注意的是:STM32中断每发生一次,只会接收到一字节的数据,因此,进行七次才会接收完一整帧的数据包,这一点需要读者仔细揣摩,结合上文中说的静态变量关键字static,定义了:

    u8 com_data; 
    u8 i;
    static u8 RxCounter1=0;
    static u8 RxBuffer1[10]={0};
    static u8 RxState = 0;	
    static u8 RxFlag1 = 0;
    

    请读者仔细揣摩为什么com_data(端口接收到的数据)、i定义的是动态的(auto),而RxBuffer1(装接收到数据的静态全局数组)、RxState(状态标志变量)、RxFlag1(接受结束标志变量)定义的确实静态的,这一点并不难理解。

    5.利用PC端测试数据数据是否发送接收正常

    在进行OpenMV与STM32的通信测试过程中,我使用了USB转TTL模块,将OpenMV(或STM32单片机)与PC端进行通信确保数据发出或者接收正常。
    OpenMV&&PC
    OpenMV_RX接模块TX
    OpenMV_TX接模块RX
    OpenMV_GND接模块GND
    然后打开OpenMV,在大循环while(True)中使用语句:

    DATA=bytearray[(1,2,3,4,5)]
    uart.write(DATA)
    

    打开PC端串口助手,注意设置一样的波特率、停止位、发送字节数等,查看串口助手是否接受到了数据。
    STM32&&PC
    STM32_RX接模块TX
    STM32_TX接模块RX
    STM32_GND接模块GND
    注意:不管是STM32与PC还是OpenMV与PC还是STM32与OpenMV通信,都要将二者的GND连接在一起。
    在main.c中先调用stdio头文件,大循环中使用如下语句:

    while(1)
    {
    		printf("HelloWorld!");
    }
    

    打开串口助手查看是否接收到了数据。

    6.学习补充 (代码看不懂的时候可以来看一下)

    补充1:static关键字(静态变量)的使用

    static 修饰全局函数和全局变量,只能在本源文件使用。举个例子,比如用以下语句static u8 RxBuffer[10] 定义了一个名为RxBuffer的静态数组,数组元素类型为unsigned char型。在包含Rxbuffer的源文件中,Rxbuffer相当于一个全局变量,任意地方修改RxBuffer的值,RxBuffer都会随之改变。而且包含RxBuffer的函数在多次运行后RxBuffer的值会一直保存(除非重新赋值)。在C语言学习中,利用static关键字求阶乘是一个很好的例子:

    #include“stdio.h”
    long fun(int n);
    void main()
    {
        int i,n;
        printf("input the value of n:");
        scanf("%d",&n);
        for(i=1;i<=n;i++)
        {
            printf("%d! = %1d\n",i,fun(i));
        }
    }
    >long fun(int n)
    {
        static long p=1; 
        p=p*n;
        return p;
    }
    

    效果为依次输出n!(n=1,2,3…n)
    这个例子中,第一次p的值为1,第二次p的值变成了p x n=1 x 2=2,这个值会一直保存,如果p没有定义为静态类型,那么在第一次运算过后p的值会重新被赋值为1,这就是auto型(不声明默认为auto型)与static型的最大区别。

    总结:static关键字定义的变量是全局变量,在static所包含的函数多次运行时,该变量不会被多次初始化,只会初始化一次。

    补充2:extern关键字(外部变量)的使用

    程序的编译单位是源程序文件,一个源文件可以包含一个或若干个函数。在函数内定义的变量是局部变量,而在函数之外定义的变量则称为外部变量,外部变量也就是我们所讲的全局变量。它的存储方式为静态存储,其生存周期为整个程序的生存周期。全局变量可以为本文件中的其他函数所共用,它的有效范围为从定义变量的位置开始到本源文件结束。
    如果整个工程由多个源文件组成,在一个源文件中想引用另外一个源文件中已经定义的外部变量,同样只需在引用变量的文件中用 extern 关键字加以声明即可。下面就来看一个多文件的示例:

    /****max.c****/
    #include <stdio.h>
    /*外部变量声明*/
    extern int g_X ;
    extern int g_Y ;
    int max()
    {
        return (g_X > g_Y ? g_X : g_Y);
    }
    /***main.c****/
    #include <stdio.h>
    /*定义两个全局变量*/
    int g_X=10;
    int g_Y=20;
    int max();
    int main(void)
    {
        int result;
        result = max();
        printf("the max value is %d\n",result);
        return 0;
    }
    运行结果为:
    the max value is 20
    

    对于多个文件的工程,都可以采用上面这种方法来操作。对于模块化的程序文件,可在其文件中预先留好外部变量的接口,也就是只采用 extern 声明变量,而不定义变量,max.c 文件中的 g_X 与 g_Y 就是如此操作的。比如想要在主函数中调用usart.c中的变量x,usart.c中有着这样的定义:static u8 x=0在usart.h中可以这样写:extern u8 x在main.c中包含usart.h头文件,这样在编译的时候就会在main.c中调用x外部变量。

    总结:extern关键字是外部变量,静态类型的全局变量,可以在源文件中调用其他文件中的变量,在多文件工程中配合头文件使用。

    补充3:MicroPython一些库函数的解释

    1.ustruct.pack函数:
    import ustruct,在ustruct中

    data = ustruct.pack("<bbhhhhb",      #格式为俩个字符俩个短整型(2字节)
                       0x2C,                      #帧头1
                       0x12,                      #帧头2
                       int(cx), # up sample by 4   #数据1
                       int(cy), # up sample by 4    #数据2
                       int(cw), # up sample by 4    #数据1
                       int(ch), # up sample by 4    #数据2
                       0x5B)
    

    ""bbhhhhb"简单来说就是要发送数据的声明,bbhhhhb共七个,代表发送七个数据,对照下面的表,可以知道七个数据按时序发送为unsigner char、unsigned char、short、short、short、short、unsigned char。0x2c为数据帧的帧头,即检测到数据流的开始,但是一个帧头可能会出现偶然性,因此设置两个帧头0x2c与0x12以便在中断中检测是否检测到了帧头以便存放有用数据。0x5b为帧尾,即数据帧结束的标志。
    在这里插入图片描述
    2.bytearray([ , , , ])函数:
    用于把十六进制数据以字节形式存放到字节数组中,以便以数据帧的形式发送出去进行通信。

    FH = bytearray([0x2C,0x12,cx,cy,cw,ch,0x5B])
    uart,write(FH)
    

    7.效果展示(可以先来看效果)

    在这里插入图片描述 从上到下依次为CX,CY,CW,CH

    8.参考链接

    [1]extern外部变量参考链接
    [2]星瞳科技OpenMV中文参考手册官方
    [3]MicroPython函数库

    9.完整版代码链接

    完整版代码链接

    展开全文
  • openmvstm32串口通信完成二维码识别

    千次阅读 多人点赞 2021-03-21 22:28:25
    openmv和stm32串口通信完成二维码...openmv4通过串口通信加json与stm32f103完成通信,结果由stm32所连的lcd屏显示 一、所用的硬件: openmv4、正点原子的mini板(stm32f103rct6)、正点原子配套的lcd屏。 示例:panda

    openmv和stm32串口通信完成二维码识别


    前言

    注:我只是个大一的小白,本文只完成基本功能,希望能帮助有困惑的人(我也是刚刚走出谜团,大佬勿喷。)
    工训赛期间,突击学习了二维码识别(基于openmv4)。openmv4通过串口通信加json与stm32f103完成通信,结果由stm32所连的lcd屏显示

    一、所用的硬件:

    openmv4、正点原子的mini板(stm32f103rct6)、正点原子配套的lcd屏。

    二、openmv端

    直接上代码:

    代码如下(示例):

    mport sensor, image, time
    from pyb import UART
    
    uart = UART(3, 115200)
    sensor.reset()
    sensor.set_pixformat(sensor.RGB565)
    sensor.set_framesize(sensor.QQVGA) # can be QVGA on M7...
    sensor.skip_frames(30)
    sensor.set_auto_gain(False) # must turn this off to prevent image washout...
    while(True):
        img = sensor.snapshot()
        img.lens_corr(1.8) # strength of 1.8 is good for the 2.8mm lens.
        for code in img.find_qrcodes():
            print(code)
            FH= bytearray([0xb3,0xb3])
            uart.write(FH)
            uart.write(code.payload())
            FH = bytearray([0x0d,0x0a])
            uart.write(FH)
            time.sleep_ms(1000)
    
    

    注:
    1、openmv4的 p4为TX p5为RX。(不要接错线哦)
    2、FH为帧头用于检验数据发送是否正确。(不懂的可以结合32端代码理解)
    3、 code.payload()函数记录的二维码内的字符。
    4、波特率设置为115200(要和32端保持一致)。
    5、关于二维码识别的详细代码可以去openmv官网查找。

    2.stm32端

    main.c:

    #include "sys.h"
    #include "delay.h"
    #include "usart.h"
    #include "lcd.h"
    
    
     int main(void)
     {		
     	u8 len;
    	u8 t,n;
    	u8 UsartDisPlay[200];
    	uart_init(115200);
    	 delay_init();
    	 LCD_Init();
    	POINT_COLOR=RED; 
    while(1)
    {
       if(USART_RX_STA&0x8000)
       {
           len=USART_RX_STA&0x3fff;
    		 for(t=0;t<len;t++)
    		  { if(USART_RX_BUF[t]==0xb3)
    				 if(USART_RX_BUF[t]==0xb3) n=t+1;
    			}
    			for(t=0;n<len;t++,n++)
    			{UsartDisPlay[t]=USART_RX_BUF[n];
    				delay_ms(3000);
    			 }
    			USART_RX_STA=0;
        }
    	 
    LCD_ShowString(15,50,260,16,16,UsartDisPlay);
    	
    }	
    	  
    

    usart1配置:

    void uart_init(u32 bound){
      //GPIO端口设置
      GPIO_InitTypeDef GPIO_InitStructure;
    	USART_InitTypeDef USART_InitStructure;
    	NVIC_InitTypeDef NVIC_InitStructure;
    	 
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);	//使能USART1,GPIOA时钟
      
    	//USART1_TX   GPIOA.9
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
      GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
       
      //USART1_RX	  GPIOA.10初始化
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
      GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  
    
      //Usart1 NVIC 配置
      NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
    	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//子优先级3
    	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;			//IRQ通道使能
    	NVIC_Init(&NVIC_InitStructure);	//根据指定的参数初始化VIC寄存器
      
       //USART 初始化设置
    
    	USART_InitStructure.USART_BaudRate = bound;//串口波特率
    	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(USART1, &USART_InitStructure); //初始化串口1
      USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
      USART_Cmd(USART1, ENABLE);                    //使能串口1 
    
    }
    

    中断函数:

    if(USART_GetITStatus(USART1, USART_IT_RXNE) != RESET)  //接收中断(接收到的数据必须是0x0d 0x0a结尾)
    		{
    		Res =USART_ReceiveData(USART1);	//读取接收到的数据
    		
    		if((USART_RX_STA&0x8000)==0)//接收未完成
    			{
    			if(USART_RX_STA&0x4000)//接收到了0x0d
    				{
    				if(Res!=0x0a)USART_RX_STA=0;//接收错误,重新开始
    				else USART_RX_STA|=0x8000;	//接收完成了 
    				}
    			else //还没收到0X0D
    				{	
    				if(Res==0x0d)USART_RX_STA|=0x4000;
    				else
    					{
    					USART_RX_BUF[USART_RX_STA&0X3FFF]=Res ;
    					USART_RX_STA++;
    					if(USART_RX_STA>(USART_REC_LEN-1))USART_RX_STA=0;//接收数据错误,重新开始接收	  
    					}		 
    				}
    			}   		 
         } 
    

    注:
    1、PA9为TX,PA10为RX。
    2、openmv和stm32一定要共接GND。


    在这里插入图片描述

    在这里插入图片描述
    在这里插入图片描述

    总结

    要源码的可以评论区留邮箱,本人刚入门,有错欢迎指正。

    展开全文
  • 首先,我使用STM 32单片机有2 年左右的时间了,但是openmv却不足一个月的时间,由于近几天问我关于两者之间...openmv与单片机通讯,大多数时候都不是只发送一两个字符或数字,一般都需要进行大量数据传输,将识别到...
  • openmv for stm32云台.zip

    2019-11-19 12:36:25
    openmv与STM32串口通信解析程序,并附带STM32追物体的云台
  • STM32单片机与Openmv的串口通信

    万次阅读 多人点赞 2019-03-24 21:43:31
    openmv与stm32的串口通信简谈闲话Openmv主要代码STM32单片机的配置运行效果图片如下 简谈闲话 这两天本人利用周末时间粗略的学习一下openmv的使用,目的是用openmv图像处理数据并通过串口发送数据给STM32F103的...
  • OpenMV识别色块并且与STM32串口通信

    千次阅读 多人点赞 2019-10-01 23:11:32
    OpenMV与STM32通信的方式是串口通信,使用openmv简单的串口配置。 因为视觉部分有两个任务,所以用单片机给STM32发送“1”,开始颜色识别,发送“2”,开始特征点识别。不发送则不识别。 识别色块 代码使用了OpenMV...
  • openmv舵机控制,LAB颜色识别,openmv与stm32通信。帧率稳定。
  • Openmv通过串口接收数据、发送数据与stm32通信

    千次阅读 多人点赞 2020-09-04 20:09:17
    目录参考接线星瞳教程openmv传送数据STM32解码程序实践 参考 接线 星瞳教程 发送数据 接收数据 不过我比较奇怪为何它们的uart不需要初始化 openmv传送数据 1、初始化以及uart参数设置 uart = pyb.UART(3, 115200) #...
  • 2020电赛题OPENMV识别形状并与stm32通信

    千次阅读 多人点赞 2020-10-26 13:56:02
    关于openmv与stm32通信的程序在我另一个博客中 openmv的程序很简单,只有两个注意点,1是openmv与主控板之间的通信,2是设置好roi区域 可以避免一些误判。 STM32与OPENMV通信 if(value == 1): # 判断形状及参数发送...
  • 发送数据 接收数据 不过我比较奇怪为何它们的uart不需要初始化 openmv传送数据 1、初始化以及uart参数设置 uart pyb.UART(3, 115200) #串口3 波特率115200uart.init(115目录参考接线星瞳教程openmv传送数据STM32解码...
  • 基于stm32f103的于openmv通信程序。
  • STM32与OpenMV通信的几点注意【小白级】

    万次阅读 多人点赞 2019-04-17 09:25:50
    状况描述:STM32OpenMV都能PC通信,但STM32OpenMV两者之间无法实现,甚至STM32未进入串口中断函数。 1.接线 STM32 OpenMV RXD TXD TXD RXD GND GND 注意:一定要共地 2.串口初始化的配置 1)...

空空如也

空空如也

1 2 3
收藏数 44
精华内容 17
关键字:

openmv与stm32通信