精华内容
下载资源
问答
  • stm32与openmv串口通信
  • arduino与openmv通信

    2020-06-07 11:56:48
    通信只能运行于arduino上,是arduino与openmv通信工具,与官网上给出的有所不同,是本组队员在遇到麻烦后搜修改的
  • 关于arduino和openmv串口通信的问题

    千次阅读 2020-12-31 10:54:08
    #openmv的代码import sensor, image, timeimport jsonfrom pyb import UART# For color tracking to work really well you should ideally be in a very, very,# very, controlled enviroment where the lighting is...

    #openmv的代码

    import sensor, image, time

    import json

    from pyb import UART

    # For color tracking to work really well you should ideally be in a very, very,

    # very, controlled enviroment where the lighting is constant...

    blue_threshold   = ( 0, 60, -20, 64, -128, 0)

    # You may need to tweak the above settings for tracking green things...

    # Select an area in the Framebuffer to copy the color settings.

    #p4_10,p5_11,gnd_gnd

    sensor.reset() # Initialize the camera sensor.

    sensor.set_pixformat(sensor.RGB565) # use RGB565.

    sensor.set_framesize(sensor.QQVGA) # use QQVGA for speed.

    sensor.skip_frames(10) # Let new settings take affect.

    sensor.set_auto_whitebal(False) # turn this off.

    clock = time.clock() # Tracks FPS.

    uart = UART(3, 115200)

    '''

    扩宽roi

    '''

    def expand_roi(roi):

    # set for QQVGA 160*120

    extra = 5

    win_size = (160, 120)

    (x, y, width, height) = roi

    new_roi = [x-extra, y-extra, width+2*extra, height+2*extra]

    if new_roi[0] < 0:

    new_roi[0] = 0

    if new_roi[1] < 0:

    new_roi[1] = 0

    if new_roi[2] > win_size[0]:

    new_roi[2] = win_size[0]

    if new_roi[3] > win_size[1]:

    new_roi[3] = win_size[1]

    return tuple(new_roi)

    K=680 #the value should be measured

    while(True):

    clock.tick() # Track elapsed milliseconds between snapshots().

    img = sensor.snapshot() # Take a picture and return the image.

    blobs = img.find_blobs([blue_threshold], area_threshold=150)

    if blobs:

    #如果找到了目标颜色

    data=[]

    #print(blobs)

    for blob in blobs:

    #迭代找到的目标颜色区域

    b = blob[0]

    is_circle = False

    max_circle = None

    max_radius = -1

    new_roi = expand_roi(blob.rect())

    Lm = (blob[2]+blob[3])/2

    length = K/Lm

    length = str(length)

    length = float(length)

    for c in img.find_circles(threshold = 2000, x_margin = 10, y_margin = 10, r_margin = 10, roi=new_roi):

    is_circle = True

    # img.draw_circle(c.x(), c.y(), c.r(), color = (255, 255, 255))

    if c.r() > max_radius:

    max_radius = c.r()

    max_circle = c

    if is_circle:

    # 如果有对应颜色的圆形 标记外框

    # Draw a rect around the blob.

    img.draw_rectangle(new_roi) # rect

    img.draw_rectangle(blob.rect()) # rect

    #用矩形标记出目标颜色区域

    img.draw_cross(blob[5], blob[6]) # cx, cy

    img.draw_circle(max_circle.x(), max_circle.y(), max_circle.r(), color = (0, 255, 0))

    img.draw_circle(max_circle.x(), max_circle.y(), max_circle.r() + 1, color = (0, 255, 0))

    data.append((max_circle.x(),max_circle.y(),length))

    #data.append(length)

    data_out = json.dumps(set(data))

    uart.write(data_out +'\n')

    print('you send:',data_out)

    else:

    print("not found!")

    else:

    print("not found!")

    #print(clock.fps()) # Note: Your OpenMV Cam runs about half as fast while

    # connected to your computer. The FPS should increase once disconnected.

    展开全文
  • 附32单片机源码,openmv源码。
  • 超声波测的距离通过串口一用串口监视器看,串口四主要实现openmv和stm32通信
  • STM32单片机与Openmv串口通信

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

    简谈闲话

    这两天本人利用周末时间粗略的学习一下openmv的使用,目的是用openmv图像处理数据并通过串口发送数据给STM32F103的单片机,并且用TFTLCD显示屏打印数据。在学习的过程中遇到了一些问题且成功解决,下面将讲述其中的过程,希望可以帮助需要的朋友,欢迎大家一起交流学习。

    Openmv主要代码

    import sensor, image, time, math
    from pyb import UART
    import json
    
    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
    clock = time.clock()
    
    uart = UART(3,115200)   #定义串口3变量
    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
    ####################################
    #
    #此为颜色处理代码
    #
    ###################################
    #bytearray为可变序列的字节数组 返回一个新的字节数组(将数据转为16进制)
    img_data = bytearray([0x2C,18,X_black_Sign,Y_black_Sign,X_black_relative_displacement,Y_black_relative_displacement,
                               X_red_Sign,Y_red_Sign,X_red_relative_displacement,Y_red_relative_displacement,X_yellow_Sign,
                               Y_yellow_Sign,X_yellow_relative_displacement,Y_yellow_relative_displacement,
                               L_black,L_red,L_yellow,0x5B])
    
    
    uart.write(img_data)
    

    上述代码中引用了感光元件sensor及串口UART.
    先定义了一个寻色块面积最大的函数,然后对目标颜色进行处理,最后通过bytearray对数据进行处理并赋值给变量img_data。

    bytearray为python内字节数组,详情请点击此处

    STM32单片机的配置

    • UART4库函数初始化配置
    void uart4_Init(void)
    {
    	GPIO_InitTypeDef GPIO_InitStructure; //串口端口配置结构体变量
    	USART_InitTypeDef USART_InitStructure;//串口参数配置结构体变量
    	NVIC_InitTypeDef NVIC_InitStructure;//串口中断配置结构体变量
    	//使能 UART4 时钟
    	RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART4, ENABLE);	//打开串口复用时钟
       	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);   //打开PC端口时钟
      
    	//UART4_TX   GPIOC.10
    	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PC.10
      	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//设定IO口的输出速度为50MHz
      	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;	//复用推挽输出
     	 GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIOC.10
       
      	//UART4_RX	  GPIOC.11初始化
      	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;//PC.11
      	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
      	GPIO_Init(GPIOC, &GPIO_InitStructure);//初始化GPIOC.10  
    
     	//Usart1 NVIC 配置
      	NVIC_InitStructure.NVIC_IRQChannel = UART4_IRQn;
    	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2 ;//抢占优先级2
    	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		//子优先级3
    	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(UART4, &USART_InitStructure); //初始化串口4
    	
    	USART_ITConfig(UART4, USART_IT_RXNE, ENABLE);//开启串口接受中断
      
    	USART_Cmd(UART4, ENABLE);                    //使能串口4 
      
     	 //如下语句解决第1个字节无法正确发送出去的问题
       	USART_ClearFlag(UART4, USART_FLAG_TC);       //清串口4发送标志
    }
    
    • UART4的中断函数
    void UART4_IRQHandler(void)			   //串口4全局中断服务函数
    {
    	u8 com_data;
      	//接收中断
    	if( USART_GetITStatus(UART4,USART_IT_RXNE) )
    	{
    		USART_ClearITPendingBit(UART4,USART_IT_RXNE);//清除中断标志
    		com_data = UART4->DR;
    		Openmv_Receive_Data(com_data);//openmv数据处理函数
    	}
    }
    

    本次实验我采用的是STM32F103zet6精英版单片机,具体配置请参考其数据手册。

    • 接收openmv数据
    void Openmv_Receive_Data(int16_t data)//接收Openmv传过来的数据
    {
    	static u8 openmv[18];	//存取数据
    	static u8 state = 0;	
    	static u8 bit_number=0;	
    	if(state==0&&data==0x2C)
    	{
    		state=1;
    		openmv[bit_number++]=data;
    	}
    	else if(state==1&&data==18)
    	{
    		state=2;
    		openmv[bit_number++]=data;
    	}
    	else if(state==2)
    	{
    		openmv[bit_number++]=data;
    		if(bit_number>=17)
    		{
    			state=3;
    		}
    	}
    	else if(state==3)		//检测是否接受到结束标志
    	{
            	if(data == 0x5B)
            	{
                		state = 0;
                		openmv[bit_number++]=data;
            	}
            	else if(data != 0x5B)
            	{
               		 state = 0;
                		for(i=0;i<18;i++)
                		{
                   			 openmv[i]=0x00;
                		}           
            	}
    	}    
    	else
    	{
    		state = 0;
    		bit_number=0;
                	for(i=0;i<18;i++)
                	{
                   		 openmv[i]=0x00;
               	 }
    	}
    }
    

    函数就是数据后先对比帧头是否正确,正确则进行数据存储,否则数据数组一直等待正确帧头的到来。

    • 主函数
    int main(void)
     {		
    	delay_init();	    	 //延时函数初始化	  
    	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
    	uart_init(115200);	 //串口初始化为115200
    	uart4_Init();
     	LED_Init();			     //LED端口初始化
    	KEY_Init();          //初始化与按键连接的硬件接口
    	LCD_Init();
    	POINT_COLOR=RED;
      	while(1) 
    	{	
    		LCD_ShowNum(0,20,200,10,24);
    		LCD_ShowNum(0,40,X_black_data,10,24); 
    		LCD_ShowNum(0,70,Y_black_data,10,24);
    		LCD_ShowNum(0,90,X_red_data,10,24);
     		LCD_ShowNum(0,110,Y_red_data,10,24);		     					 
    		LCD_ShowNum(0,130,X_yellow_data,10,24);	  
    		LCD_ShowNum(0,150,Y_yellow_data,10,24);	    		
    	}  	 
     }
    

    运行效果图片如下

    TFTLCD屏显示openmv串口终端
    帧缓冲区

    • 注意事项
    • 若使用寄存器初始化串口,则应只有USART1使用PCLK2(最高72MHz)。其它USART使用PCLK1(最高36MHz)。
    • openmv的波特率应与接收端单片机串口波特率对应
    • openmv与STM32单片机两个串口的的数据格式应保持一致
    展开全文
  • STM32单片机/OpenMv串口通信部分

    千次阅读 多人点赞 2019-07-17 16:13:02
    博主本人3天前接触OpenMv,有单片机基础,但是串口总也搞不透彻,特抽出时间作此备忘,希望可以和大家互相学习。

    因为博主本人是一个技术初学菜鸟,本文浅谈相关理解,方便自己记忆也分享给大家,文中的错误欢迎读者指正,欢迎交流,互相学习。
    本文描述主要以openmv视角,以单片机视角的部分补充可移步参阅识别特定颜色并将其坐标通过串口打印

    为什么使用串口?

    为什么要用串口呢?
    因为要时候需要把信息(比如数字,坐标,参数……)传给其他MCU,串口简单,通用,基本每一个MCU都会有串口。
    例如: 我想用OpenMv进行图像处理,处理完之后想让其他人去做除了OpenMv之外的事情,所以我可以把他处理出来的结果或者其他有用的信息通过串口传输给其他设备的MCU(如电脑,单片机等)
    openmv部分openmv识别特定颜色且打印坐标到串口

    连接方式

    串口通信(TTL)至少需要3根线,RXD、TXD、GND:
    RXD和TXD互连,GND接地

    MCU1 MCU2 RXD——TXD TXD——RXD MCU1 MCU2

    连接约定

    • 统一波特率
    • 选定固定串口

    传输数据

    这里假设输出识别到的t这个对象的坐标,可使用以下两种方法:

    • Ostr="[%d,%d]" % (t.cx(),t.cy()) #方式1
    • Ostr=json.dumps([t.cx(),t.cy()]) #方式2

    关于json对象

    基本所有的语言都支持json,这里只写两个函数[编解码]:

    函数描述
    json.dumps将 Python 对象编码成 JSON 字符串
    json.loads将已编码的 JSON 字符串解码为 Python 对象

    例(python环境):

    #!/usr/bin/python
    import json
    
    t = [ { 'a' : 1, 'b' : 2, 'c' : 3} ]
    
    json = json.dumps(t)
    print(json)
    

    执行结果为:

    [{"a": 1, "b": 2, "c": 3}]
    

    在keil环境也有了官方的库:——Jansson

    Jansson Pack
    转至: Pack下载.
    详情不再赘述

    注意部分

    • OpenMv使用编程语言为Python,STM32单片机一般使用C1
    • 串口通信一般每次中断只传输1Byte,也就是说要完整传输完1帧,进中断的次数>=8
    • 最简单的每一帧的传输至少要有帧头和数据,当然可以增加数据量、校验和,帧尾等以备其他操作
    • 每个Byte都要以字节方式发送,而不是16进制
      • data = bytearray([x,y])#将x,y作为两个Byte存入data
        uart.write(data)#将data通过串口发送
      • uart.write("%x \r"%x)#将x转换成16进制发送
    • 帧头实际上就是判断数据从哪里开始的标志,一般自定义,为保证安全性,可以采用双帧头的模式,
      例如:
      5A 5A 10 50 1B 00 FF 63 03 0C 这里加粗的是帧头,剩下8个是数据(随便设的,仅举例用)

    1. 说明: Openmv也是个单片机,它的芯片其实也是STM32,底层代码也是C,只是为了方便大众,都用Python直接调用技术团队写的例程直接进行编程 ↩︎

    展开全文
  • OPENMV-STM32串口通信

    千次阅读 2021-10-08 11:27:50
    OPENMV-STM32串口通信 目录标题OPENMV-STM32串口通信前言硬件选择硬件的通信连接OPENMV软件分析效果展示图 前言 最近要准备工巡赛,突然要发现需要进行视觉传动,所以我最近几天又温顾了一下Openmv,以前学习Openmv都...

    OPENMV-STM32串口通信

    前言

    最近要准备工巡赛,突然要发现需要进行视觉传动,所以我最近几天又温顾了一下Openmv,以前学习Openmv都是通过电脑对其进行控制,但是这样学习OpenMV是远远不够的,还需要实现与单片机的通信,本以为很简单,在CSDN,github上找了一些开源代码,然后进行复制与粘贴,原本我以为这就掌握了,但是在后期的传输我犯了许多低级的错误,中间也反映了我的一些不足,我最后通过OLED连进行数据传输,调试后,我特地写下此博客来记录我自己的学习经历。

    硬件选择

    我选择的是openmv4 CamH7智能摄像头,OLED, stm32f104c8t6, ST-JINK, 若干数据线和杜邦线

    硬件的通信连接

    在这里插入图片描述这是openmv4 CamH7智能摄像头,由图可知openmv4 CamH7只有1个串口,USART3,
    由图知UART_RX—P5 UART_TX—P4

    那么在STM32中
    在这里插入图片描述我们选择PB10,PB11,来进行串口选择USART3.

    STM32的TX(RX)接OpenMV的RX(TX),OLED连接到STM32即可

    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)
    
    

    在这里我借鉴了这位博主的代码乌拉
    对于为什么不直接使用send()函数,在这里他是这么认为的
    bytearray([, , ,])组合uart.write()的作用与直接调用sending_data(cx,cy,cw,ch)作用是一样的
    我看来都无所谓,我是使用了send()函数,其实方法都无所谓的,只要能够传输数据就行。

    在这里我们通过openmv对电脑进行串口通信来判断openmv是否通信成功,将openmv与TTL连接,打开串口助手XCOM来进行查看数据是否传输成功
    在这里插入图片描述
    串口通信成功,代码有效

    让我们看看STM32的程序,我们要打开串口的驱动,我们要打开的串口驱动为USART3,

    #include "uart.h"
    #include "show.h"
    #include "gpio.h"
    
     u8 Cx=0,Cy=0,Cw=0,Ch=0;
    
    void uart3_Init(void)
    {
    		//USART3_TX PB10
    		//USART3_RX PB11
    		
    	 GPIO_InitTypeDef GPIO_InitStructure;
    	 USART_InitTypeDef USART_InitStructure;
       NVIC_InitTypeDef NVIC_InitStructure;
    	
    	 RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3,ENABLE);
    	 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
    	 
    	 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;
    	 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;
    	 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    	 GPIO_Init(GPIOB,&GPIO_InitStructure);
    	
    	 GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
    	 GPIO_InitStructure.GPIO_Pin=GPIO_Pin_11;
    	 GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    	 GPIO_Init(GPIOB,&GPIO_InitStructure);  
    	
    	 NVIC_InitStructure.NVIC_IRQChannel=USART3_IRQn;
    	 NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
    	 NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0;
    	 NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;
    	 NVIC_Init(&NVIC_InitStructure);
    	
       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(USART3, &USART_InitStructure);   
    
    		
       USART_ITConfig(USART3, USART_IT_RXNE, ENABLE); //使能中断
       USART_Cmd(USART3, ENABLE);                     //使能串口3
    	 USART_ClearFlag(USART3, USART_FLAG_TC);        //清串口3发送标志 	
    }
    
    void USART3_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(USART3,USART_IT_RXNE)!=RESET)  	   //接收中断  
    		{
    				USART_ClearITPendingBit(USART3,USART_IT_RXNE);   //清除中断标志
    				com_data = USART_ReceiveData(USART3);						 //串口3接收数据
    			
    				if(RxState==0&&com_data==0x2C)  //0x2c帧头开始数据接收处理
    				{
    					RxState=1;
    					RxBuffer1[RxCounter1++]=com_data;
    					OLED_Refresh_Gram();
    //					GPIO_SetBits(GPIOB,GPIO_Pin_4);
    				}
    		
    				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(USART3,USART_IT_RXNE,DISABLE);//关闭DTSABLE中断
    									if(RxFlag1)
    									{
    									OLED_Refresh_Gram();
    									OLED_ShowNumber(0, 0,Cx,3,16);
    									OLED_ShowNumber(0,17,Cy,3,16);
    									OLED_ShowNumber(0,33,Cw,3,16);
    									OLED_ShowNumber(0,49,Ch,3,16);
    									oled_show();
    									}
    									RxFlag1 = 0;
    									RxCounter1 = 0;
    									RxState = 0;
    									USART_ITConfig(USART3,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;      //将存放数据数组清零
    						}
    				}
    
    		}
    		
    }
    
    
    
    
    
    

    代码解析:RxBuffer1[]数组是用来存储数据的,先存储帧头,后存储数据,帧头的数值可以任选,0x2c为数据帧的帧头,即检测到数据流的开始,但是一个帧头可能会出现偶然性,因此设置两个帧头0x2c与0x12以便在中断中检测是否检测到了帧头以便存放有用数据。0x5b为帧尾,即数据帧结束的标志。我们储存数据完毕需要7次中断,进行完7次中断后才能将数据输入进去。

    OLED模块由于代码的数据量过多,而且我使用的是六针OLED,对于OLED的驱动可能会与市场常见的OLED可能不一样,在这里我先把OLED的驱动填写上,

    #include "oled.h"
    #include "stdlib.h"
    #include "oledfont.h"  	 
    #include "delay.h"
    u8 OLED_GRAM[128][8];	 
    /**************************************************************************
    Function: Refresh the OLED screen
    Input   : none
    Output  : none
    函数功能:刷新OLED屏幕,更新缓存,显示内容
    入口参数:无
    返回  值:无
    **************************************************************************/
    void OLED_Refresh_Gram(void)
    {
    	u8 i,n;		    
    	for(i=0;i<8;i++)  
    	{  
    		OLED_WR_Byte (0xb0+i,OLED_CMD);    //设置页地址(0~7)
    		OLED_WR_Byte (0x00,OLED_CMD);      //设置显示位置—列低地址
    		OLED_WR_Byte (0x10,OLED_CMD);      //设置显示位置—列高地址   
    		for(n=0;n<128;n++) OLED_WR_Byte(OLED_GRAM[n][i],OLED_DATA); 
    	}   
    }
    
    /**************************************************************************
    Function: Refresh the OLED screen
    Input   : Dat: data/command to write, CMD: data/command flag 0, represents the command;1, represents data
    Output  : none
    函数功能:向OLED写入一个字节
    入口参数:dat:要写入的数据/命令,cmd:数据/命令标志 0,表示命令;1,表示数据
    返回  值:无
    **************************************************************************/  
    void OLED_WR_Byte(u8 dat,u8 cmd)
    {	
    	u8 i;			  
    	if(cmd)				//判断是命令还是写数据
    	  OLED_RS_Set();  //DC判断
    	else 
    	  OLED_RS_Clr();	//DC判断	  
    	for(i=0;i<8;i++)		//数据输入
    	{			  
    		OLED_SCLK_Clr();
    		if(dat&0x80)
    		   OLED_SDIN_Set();
    		else 
    		   OLED_SDIN_Clr();
    		OLED_SCLK_Set();
    		dat<<=1;   
    	}				 		  
    	OLED_RS_Set();   	  
    } 
    /**************************************************************************
    Function: Turn on the OLED display
    Input   : none
    Output  : none
    函数功能:开启OLED显示 
    入口参数:无
    返回  值:无
    **************************************************************************/      
    void OLED_Display_On(void)
    {
    	OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令
    	OLED_WR_Byte(0X14,OLED_CMD);  //DCDC ON
    	OLED_WR_Byte(0XAF,OLED_CMD);  //DISPLAY ON
    }
    /**************************************************************************
    Function: Turn off the OLED display
    Input   : none
    Output  : none
    函数功能:关闭OLED显示 
    入口参数:无			  
    返回  值:无
    **************************************************************************/         
    void OLED_Display_Off(void)
    {
    	OLED_WR_Byte(0X8D,OLED_CMD);  //SET DCDC命令
    	OLED_WR_Byte(0X10,OLED_CMD);  //DCDC OFF
    	OLED_WR_Byte(0XAE,OLED_CMD);  //DISPLAY OFF
    }		   			 
    /**************************************************************************
    Function: Screen clear function, clear the screen, the entire screen is black, and did not light up the same
    Input   : none
    Output  : none
    函数功能:清屏函数,清完屏,整个屏幕是黑色的,和没点亮一样
    入口参数:无		  
    返回  值:无
    **************************************************************************/  	  
    void OLED_Clear(void)  
    {  
    	u8 i,n;  
    	for(i=0;i<8;i++)for(n=0;n<128;n++)OLED_GRAM[n][i]=0X00;  
    	OLED_Refresh_Gram();//更新显示
    }
    /**************************************************************************
    Function: Draw point
    Input   : x,y: starting coordinate;T :1, fill,0, empty
    Output  : none
    函数功能:画点 
    入口参数:x,y :起点坐标; t:1,填充,0,清空			  
    返回  值:无
    **************************************************************************/ 			   				   
    void OLED_DrawPoint(u8 x,u8 y,u8 t)
    {
    	u8 pos,bx,temp=0;
    	if(x>127||y>63)return;//超出范围了.
    	pos=7-y/8;
    	bx=y%8;
    	temp=1<<(7-bx);
    	if(t)  
    		OLED_GRAM[x][pos]|=temp;
    	else   
    		OLED_GRAM[x][pos]&=~temp;	    
    }
    
    /**************************************************************************
    Function: Displays a character, including partial characters, at the specified position
    Input   : x,y: starting coordinate;Len: The number of digits;Size: font size;Mode :0, anti-white display,1, normal display
    Output  : none
    函数功能:在指定位置显示一个字符,包括部分字符
    入口参数:x,y :起点坐标; len :数字的位数; size:字体大小; mode:0,反白显示,1,正常显示	   
    返回  值:无
    **************************************************************************/
    void OLED_ShowChar(u8 x,u8 y,u8 chr,u8 size,u8 mode)
    {      			    
    	u8 temp,t,t1;
    	u8 y0=y;
    	chr=chr-' ';																//得到偏移后的值,ASALL寻找位置	,减一去零	   
        for(t=0;t<size;t++)
        {   
    			if(size==12)  temp=oled_asc2_1206[chr][t];  //调用1206字体
    			else          temp=oled_asc2_1608[chr][t];	//调用1608字体 	高16宽8                          
    			for(t1=0;t1<8;t1++)
    			{
    				if(temp&0x80)  OLED_DrawPoint(x,y,mode);		//标点
    				else           OLED_DrawPoint(x,y,!mode);
    				temp<<=1;
    				y++;
    				if((y-y0)==size)		//1206的控制,如果控制到12位就停止
    				{
    					y=y0;
    					x++;
    					break;
    				}
    			}  	 
        }          
    }
    /**************************************************************************
    Function: Find m to the NTH power
    Input   : m: base number, n: power number
    Output  : none
    函数功能:求m的n次方的函数
    入口参数:m:底数,n:次方数
    返回  值:无
    **************************************************************************/
    u32 oled_pow(u8 m,u8 n)
    {
    	u32 result=1;	 
    	while(n--)result*=m;    
    	return result;
    }				  
    /**************************************************************************
    Function: Displays 2 numbers
    Input   : x,y: starting coordinate;Len: The number of digits;Size: font size;Mode: mode, 0, fill mode, 1, overlay mode;Num: value (0 ~ 4294967295);
    Output  : none
    函数功能:显示2个数字
    入口参数:x,y :起点坐标; len :数字的位数; size:字体大小; mode:模式, 0,填充模式, 1,叠加模式; num:数值(0~4294967295);	 
    返回  值:无
    **************************************************************************/		  
    void OLED_ShowNumber(u8 x,u8 y,u32 num,u8 len,u8 size)
    {         	
    	u8 t,temp;
    	u8 enshow=0;						   
    	for(t=0;t<len;t++)
    	{
    		temp=(num/oled_pow(10,len-t-1))%10;
    		if(enshow==0&&t<(len-1))
    		{
    			if(temp==0)
    			{
    				OLED_ShowChar(x+(size/2)*t,y,' ',size,1);
    				continue;
    			}
    			else enshow=1; 
    		 	 
    		}
    	 	OLED_ShowChar(x+(size/2)*t,y,temp+'0',size,1); 
    	}
    } 
    /**************************************************************************
    Function: Display string
    Input   : x,y: starting coordinate;*p: starting address of the string
    Output  : none
    函数功能:显示字符串
    入口参数:x,y :起点坐标; *p:字符串起始地址 
    返回  值:无
    **************************************************************************/
    //用16字体
    void OLED_ShowString(u8 x,u8 y,const u8 *p)
    {
    #define MAX_CHAR_POSX 122
    #define MAX_CHAR_POSY 58          
        while(*p!='\0')
        {       
          if(x>MAX_CHAR_POSX){x=0;y+=16;}
          if(y>MAX_CHAR_POSY){y=x=0;OLED_Clear();}
          OLED_ShowChar(x,y,*p,12,1);	 
          x+=8;
          p++;
        }  
    }	   
    /**************************************************************************
    Function: Initialize the OLED
    Input   : none
    Output  : none
    函数功能:初始化OLED	
    入口参数: 无 
    返回  值:无
    **************************************************************************/	 				    
    void OLED_Init(void)
    { 	
    	GPIO_InitTypeDef GPIO_InitStructure;
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); 				 //使能PB端口时钟
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3|GPIO_Pin_4|GPIO_Pin_5;//端口配置
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;      				 //推挽输出
    	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;     					 //2M
      GPIO_Init(GPIOB, &GPIO_InitStructure);					               //根据设定参数初始化GPIO 
    	
    	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);          //开A口时钟。
      GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_15;
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz;               //设为输出 
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
      GPIO_Init(GPIOA, &GPIO_InitStructure);
    	
    	PWR_BackupAccessCmd(ENABLE); //允许修改RTC 和后备寄存器
    	RCC_LSEConfig(RCC_LSE_OFF);  //关闭外部低速外部时钟信号功能 后,PC13 PC14 PC15 才可以当普通IO用。
    	BKP_TamperPinCmd(DISABLE);   //关闭入侵检测功能,也就是 PC13,也可以当普通IO 使用
    	PWR_BackupAccessCmd(DISABLE);//禁止修改后备寄存器
    
    	OLED_RST_Clr();
    	delay_ms(100);
    	OLED_RST_Set(); 
    					  
    	OLED_WR_Byte(0xAE,OLED_CMD); //关闭显示
    	OLED_WR_Byte(0xD5,OLED_CMD); //设置时钟分频因子,震荡频率
    	OLED_WR_Byte(80,OLED_CMD);   //[3:0],分频因子;[7:4],震荡频率
    	OLED_WR_Byte(0xA8,OLED_CMD); //设置驱动路数
    	OLED_WR_Byte(0X3F,OLED_CMD); //默认0X3F(1/64) 
    	OLED_WR_Byte(0xD3,OLED_CMD); //设置显示偏移
    	OLED_WR_Byte(0X00,OLED_CMD); //默认为0
    
    	OLED_WR_Byte(0x40,OLED_CMD); //设置显示开始行 [5:0],行数.
    													    
    	OLED_WR_Byte(0x8D,OLED_CMD); //电荷泵设置
    	OLED_WR_Byte(0x14,OLED_CMD); //bit2,开启/关闭
    	OLED_WR_Byte(0x20,OLED_CMD); //设置内存地址模式
    	OLED_WR_Byte(0x02,OLED_CMD); //[1:0],00,列地址模式;01,行地址模式;10,页地址模式;默认10;
    	OLED_WR_Byte(0xA1,OLED_CMD); //段重定义设置,bit0:0,0->0;1,0->127;
    	OLED_WR_Byte(0xC0,OLED_CMD); //设置COM扫描方向;bit3:0,普通模式;1,重定义模式 COM[N-1]->COM0;N:驱动路数
    	OLED_WR_Byte(0xDA,OLED_CMD); //设置COM硬件引脚配置
    	OLED_WR_Byte(0x12,OLED_CMD); //[5:4]配置
    		 
    	OLED_WR_Byte(0x81,OLED_CMD); //对比度设置
    	OLED_WR_Byte(0xEF,OLED_CMD); //1~255;默认0X7F (亮度设置,越大越亮)
    	OLED_WR_Byte(0xD9,OLED_CMD); //设置预充电周期
    	OLED_WR_Byte(0xf1,OLED_CMD); //[3:0],PHASE 1;[7:4],PHASE 2;
    	OLED_WR_Byte(0xDB,OLED_CMD); //设置VCOMH 电压倍率
    	OLED_WR_Byte(0x30,OLED_CMD); //[6:4] 000,0.65*vcc;001,0.77*vcc;011,0.83*vcc;
    
    	OLED_WR_Byte(0xA4,OLED_CMD); //全局显示开启;bit0:1,开启;0,关闭;(白屏/黑屏)
    	OLED_WR_Byte(0xA6,OLED_CMD); //设置显示方式;bit0:1,反相显示;0,正常显示	    						   
    	OLED_WR_Byte(0xAF,OLED_CMD); //开启显示	 
    	OLED_Clear();
    }  
    
    
    
    
    
    

    这是我OLED的驱动,针对的是0.96寸的6针OLED驱动屏幕,

    效果展示图

    在这里插入图片描述CX,CY,CW,CH都在OLED中展现出来

    最后,感觉我自己写的博客不咋样啊,我还是把我的代码分享给大家吧,
    链接:https://pan.baidu.com/s/1uObuYJZnwb1hMOb5AYUdQw
    提取码:1234
    –来自百度网盘超级会员V3的分享
    新手初次写博客,希望大家能够一起交流

    展开全文
  • openMV和单片机串口通信

    千次阅读 2020-12-16 18:23:19
    2、openmv串口通信必须以字节为单位发送数据,否则单片机连串口接收中断都进不了(串口助手例外)。可采用以下函数: data=bytearray([0x30]) #ascill码0x30对应字符0 uart.write(data) 3、单片机进入串口接收
  • 今晚上准备二开匿名飞控由openmv巡色块循迹,首先需要通信成功,对吧。在暑假电赛之前,我与班里同学就已做出了MV方与32方数据的通信与错误校正。然后今晚上任务是把32的代码直接移植到匿名飞控上和写出追踪代码然后...
  • openmv与其他单片双向串口通信

    千次阅读 2020-11-03 14:30:40
    Openmv与其他单片双向串口通信 目的 为了让openmv进行阈值切换或者只运行某一部分代码,因此需要openmv与其他单片建立双向通信进行更改内部参数。 起因 openmv自带接收函数uart.read() 进行接收,但接收回来的...
  • openmv专题】串口通信

    千次阅读 2019-09-15 13:14:39
    主要是讲自己使用openmv时碰到的串口通信问题,只是简单的传输16进制的一组数字。
  • 刚开始学openmv与32串口通信,我是用的stm32f103的板子。开始想简单发送字符或者16位数试验一下,然后就遇到了个小问题,即openmv和单片机可以分别和电脑通信,但是让他俩通信的话就不行,随后解决在此记录下来。 ...
  • 串口通信想必大家都知道,这里就不多赘述了,如果有不了解的可以看我的往期文章【STM32】HAL库 CubeMX例程三—串口中断通信(2)(附工程源码) 1.OpenMV 首先找到OpenMV串口(图:星瞳科技) P4(Tx):发送端 P5...
  • openmv和arduino通信分析字符串会用到的函数:Arduino中处理字符串的常用方法:效果展示接线arduino代码:openmv代码: 分析字符串会用到的函数: isAlphaNumeric() // 判断是否为字母数字 isAlpha() // 判断是否为...
  • openmv串口传输数字.zip

    2019-06-21 18:36:17
    在做串口传输的过程中遇到了串口传输数字的问题,因为字符串传输数字的方式操作实现麻烦传输效率低下,因此参照相关资料写了这个把多个数字直接发送,接收后直接使用。
  • OpenMV与树莓派3串口通信(UART)

    千次阅读 2019-10-19 16:17:55
    这里是在一块前人用过的树莓派3上做的事情,所以有些配置步骤是没有或者说没用的。...在此基础上,为了某个更远大的目标,需要我先实现OpenMV与树莓派之间的通信。 1.树莓派想上网 前人似乎已经配置过 ...
  • ubuntu mate 20 与openmv串口通信 1、将卡格式化为FAT32文件系统(很简单可自行百度) 2、树莓派镜像ubuntu-mate-20.04.1 32位下载 https://ubuntu-mate.org/download/ 3、Win32DiskImager 烧镜像软件 ...
  • OpenMV——串口通信+发送中心位置

    万次阅读 热门讨论 2019-07-16 08:59:44
    OpenMV本质还是一个单片机,可以通过调用pyb中的UART使用串口通信 from pyb import UART uart = UART(3, 9600) uart.write('hello') uart.read(5) # read up to 5 bytes
  • 利用OpenMV与STM32进行串口通信 OpenMV端的程序 # Untitled - By: dell - 周一 7月 19 2021 # Blob Detection and uart transport import sensor, image, time,pyb import ustruct from pyb import UART #import ...
  • 首先,我使用STM 32单片机有2 年左右的时间了,但是openmv却不足一个月的时间,由于近几天问我关于两者之间如何进行通讯问题的人比较多,所以特地写这样一篇文章进行讲解。如果有什么讲的不对的地方,还请各位读者...
  • openmv串口传输代码

    千次阅读 2020-12-23 03:33:16
    功能是找到指定颜色物体中心坐标,再串口发送。我用openmv加无线传输模块发送数据给单片机处理。import sensor, image, timefrom pyb import UARTimport jsonthreshold = [(37, 67, 45, 84, 4, 68), #red(34, 67, -...
  • 由于项目需要使用到串口调试及测试,为了练手,使用 Qt 编写一个串口调试助手。本文按开发的过程进行简单介绍,同时也涉及部分用到的模块代码。详细代码参考源码仓库。# 工具特性## 具体功能- 具备串口收发功能。- ...
  • Openmv通过串口接收数据、发送数据与stm32通信

    万次阅读 多人点赞 2020-09-04 20:09:17
    uart = pyb.UART(3, 115200) #串口3,波特率115200 uart.init(115200, bits=8, parity=None, stop=1) #8位数据位,无校验位,1位停止位 2、将数据和帧头(一般来说是两个帧头)打包,发送打包好的数据 关于函数的用法...
  • 使用openMV3与stm32进行通讯,想用openMV与stm32通讯,在网上找了一大圈,最后决定使用串口,参照这篇文章https://blog.csdn.net/qq_43243338/article/details/89441756
  • OpenMV和STM32串口通讯

    2021-07-26 22:15:43
    利用串口进行OpenMV与STM32(其他单片机同理)进行通讯 OpenMV程序: from pyb import UART import struct def sending_data(x1,y1): data =struct.pack("<bbhhb", #格式为四个字符俩个短整型(2字节) 0x2C, #...
  • 设计思想与代码规范均借鉴明德扬至简设计法,有不足之处希望大家多提...串口是电子设计中非常常见,可以说掌握了串口数据收发,就明白了最基本的时序操作。串口的数据收发过程有其固定的数据格式。下面是本次实验使...
  • Openmv与STM32通信.zip

    2020-05-09 10:28:53
    该文件包括三部分,一个是openmv的官方云台三维模型,可直接打印,一个是openmv的程序,该程序可同时识别三个颜色,本程序中同时识别了红绿蓝,识别后返回颜色顺序,通过串口通信给stm32主控,并在LCD屏幕上显示识别...
  • 蓝牙 舵狗 openmv通信相关

    千次阅读 2020-04-20 00:12:02
    总的思路是以openmv 接收蓝牙的指令,如果是自动选项,就在openmv 运行识别红球进行固定距离跟踪的程序;如果是手动选项,openmv就直接把所得到的数据传给STM32,不做...串口通信 OpenMV本质还是一个单片机,可以...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 479
精华内容 191
关键字:

openmv串口通信