【星曈科技】OpenMv笔记 您所在的位置:网站首页 串口通信流程 【星曈科技】OpenMv笔记

【星曈科技】OpenMv笔记

2024-07-18 07:34| 来源: 网络整理| 查看: 265

利用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 json # For color tracking to work really well you should ideally be in a very, very, # very, controlled enviroment where the lighting is constant... yellow_threshold = (25, 79, 2, 39, 26, 69) # You may need to tweak the above settings for tracking green things... # Select an area in the Framebuffer to copy the color settings. led3 = pyb.LED(3) # Red LED = 1, Green LED = 2, Blue LED = 3, IR LEDs = 4. led1 = pyb.LED(1) # Red LED = 1, Green LED = 2, Blue LED = 3, IR LEDs = 4. sensor.reset() # Initialize the camera sensor. sensor.set_pixformat(sensor.RGB565) # use RGB565. sensor.set_framesize(sensor.QVGA) # 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)#初始化串口号及其波特率 #**************************传输数据的函数************************************ def sending_data(cx,cy): global uart; #frame=[0x2C,18,cx%0xff,int(cx/0xff),cy%0xff,int(cy/0xff),0x5B]; #data = bytearray(frame) data = ustruct.pack("帧头2>数据1的低八位>数据1的高八位>数据2的低八位>数据2的高八位。0x2c为数据帧的帧头,即检测到数据流的开始,但是一个帧头可能会出现偶然性,因此设置两个帧头0x2c与0x12以便在中断中检测是否检测到了帧头以便存放有用数据。0x5b为帧尾,即数据帧结束的标志。

下面,先让openmv与电脑通讯,通过串口调试助手看一下数据是否成功发送。 这里注意:openmv需要通过一个USB to TTL模块才能与电脑进行串口通信,openmv的RXD要连接模块的TXD,openmv的TXD要连接模块的RXD,然后再把模块与openmv共地即可。 通讯结果: 在这里插入图片描述 可以看到,由于摄像头没有检测到符合条件的色块,所以sending_data(567,789),通过串口助手明显发现数据传输成功,共有7个字节。

这样,我已经保证了openmv的串口发送程序是完全没有问题的,于是将程序烧录进openmv。 接下来,写一下stm32的接受程序

以下代码引用 乌拉~~~~ 博主的 超详细OpenMV与STM32单片机通信 (有完整版源码) 这一篇文章里的源码。感谢此博主的文章!!!!

// 串口中断服务函数//USART2 全局中断服务函数 void DEBUG_USART_IRQHandler(void) { uint8_t com_data; //接收一个字节数据的临时变量 uint8_t i; static uint8_t RxCounter1=0;//数据缓冲区的索引 static uint8_t RxBuffer1[10]={0};//存放数据的接收缓存区 static uint8_t RxState = 0; //接收标志位 // static uint8_t RxFlag1 = 0; if( USART_GetITStatus(DEBUG_USARTx ,USART_IT_RXNE)!=RESET) //接收中断 { USART_ClearITPendingBit(DEBUG_USARTx ,USART_IT_RXNE); //清除中断标志 com_data = USART_ReceiveData(DEBUG_USARTx ); if(RxState==0&&com_data==0x2C) //0x2c帧头 { RxState=1; RxBuffer1[RxCounter1++]=com_data;//RxBuffer1[0]==0x2c RxCounter1==1 } else if(RxState==1&&com_data==0x12) //0x12帧头 { RxState=2; RxBuffer1[RxCounter1++]=com_data;RxBuffer1[0]==0x12 RxCounter1==2 } else if(RxState==2)//开始接收有效数据 { RxBuffer1[RxCounter1++]=com_data;//全部接收完,RxCounter1==7 if(RxCounter1>=10||com_data == 0x5B) //RxBuffer1接受满了,接收数据结束 { RxState=3; // RxFlag1=1; Cx=(RxBuffer1[RxCounter1-4] USART_ITConfig(DEBUG_USARTx,USART_IT_RXNE,DISABLE);//关闭DTSABLE中断 // if(RxFlag1) // { // OLED_ShowNum(0,0,Cx,3,1,2); OLED_ShowNum(0,2,Cy,3,1,2); // } // RxFlag1 = 0; RxCounter1 = 0; RxState = 0; USART_ITConfig(DEBUG_USARTx,USART_IT_RXNE,ENABLE); } else //接收错误 { RxState = 0; RxCounter1=0; for(i=0;i RxState = 0; RxCounter1=0; for(i=0;i uint8_t com_data; //接收一个字节数据的临时变量 uint8_t i; static uint8_t RxCounter1=0;//数据缓冲区的索引 static uint8_t RxBuffer1[7]={0};//存放数据的接收缓存区 static uint8_t RxState = 0; //接收标志位 // static uint8_t RxFlag1 = 0; if( USART_GetITStatus(DEBUG_USARTx ,USART_IT_RXNE)!=RESET) //接收中断 { USART_ClearITPendingBit(DEBUG_USARTx ,USART_IT_RXNE); //清除中断标志 com_data = USART_ReceiveData(DEBUG_USARTx ); if(RxState==0&&com_data==0x2C) //0x2c帧头 { RxState=1; RxBuffer1[RxCounter1++]=com_data;//RxBuffer1[0]==0x2c RxCounter1==1 } else if(RxState==1&&com_data==0x12) //0x12帧头 { RxState=2; RxBuffer1[RxCounter1++]=com_data;RxBuffer1[0]==0x12 RxCounter1==2 } else if(RxState==2)//开始接收有效数据 { RxBuffer1[RxCounter1++]=com_data;//全部接收完,RxCounter1==7 if(RxCounter1>=7||com_data == 0x5B) //RxBuffer1接受满了,接收数据结束 { RxState=3; // RxFlag1=1; Cx=(RxBuffer1[RxCounter1-4] USART_ITConfig(DEBUG_USARTx,USART_IT_RXNE,DISABLE);//关闭DTSABLE中断 // if(RxFlag1) // { OLED_ShowChar(0,0,'(',2); OLED_ShowNum(8,0,Cx,3,1,2); OLED_ShowChar(56,0,',',2); OLED_ShowNum(64,0,Cy,3,1,2); OLED_ShowChar(112,0,')',2); // } // RxFlag1 = 0; RxCounter1 = 0; RxState = 0; USART_ITConfig(DEBUG_USARTx,USART_IT_RXNE,ENABLE); } else //接收错误 { RxState = 0; RxCounter1=0; for(i=0;i RxState = 0; RxCounter1=0; for(i=0;i printf("(%d,%d)",Cx,Cy); }

注意 1.想要单片机与电脑通信,要另外设置特定的串口,我的开发板上单片机通过USART1和电脑通信,所以要另外设置USART1。 2.同一个串口的RXD不可以连接多个设备的TXD。比如,我的开发板的USART1如果连接到openmv的TXD,那么可能就造成程序下载不到单片机,因为电脑的TXD也连接的是USART1的RXD。

///重定向c库函数printf到串口,重定向后可使用printf函数 int fputc(int ch, FILE *f) { /* 发送一个字节数据到串口 */ USART_SendData(DEBUG_USARTx, (uint8_t) ch); /* 等待发送完毕 */ while (USART_GetFlagStatus(DEBUG_USARTx, USART_FLAG_TXE) == RESET); return (ch); }

我这个代码的重定向是写的USART1(DEBUG_USARTx),是不是就说明,我只要使用printf函数就是向USART1的TXR端发送数据???



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有