• 免费好用的星瞳AI云服务上线!简单标注,云端训练,支持OpenMV H7和OpenMV H7 Plus。可以替代edge impulse。 https://forum.singtown.com/topic/9519
  • 我们只解决官方正版的OpenMV的问题(STM32),其他的分支有很多兼容问题,我们无法解决。
  • 如果有产品硬件故障问题,比如无法开机,论坛很难解决。可以直接找售后维修
  • 发帖子之前,请确认看过所有的视频教程,https://singtown.com/learn/ 和所有的上手教程http://book.openmv.cc/
  • 每一个新的提问,单独发一个新帖子
  • 帖子需要目的,你要做什么?
  • 如果涉及代码,需要报错提示全部代码文本,请注意不要贴代码图片
  • 必看:玩转星瞳论坛了解一下图片上传,代码格式等问题。
  • 一个用了两年单片机的人遇到的openmv和stm32 串口通讯的问题,不是那么容易解决,求大神



    • 先描述一下我的问题。
      首先 我用openmv的串口3发送一帧数据,像这样B3 B3 d 1a 1c d1 5d 85 ,前两个b3是帧头,后六个是数据,使用串口助手,可以在电脑上接收到。

      然后我开始配置单片机串口2,初始化如下。

      uint8_t OpenMV_Rx_BUF[8]={0};
      
      
      
      
      /*
       * º¯ÊýÃû£ºUSART2_Configuration
       * ÃèÊö  £ºUSART2 GPIO ÅäÖÃ,¹¤×÷ģʽÅäÖá£uBaud 8-N-1
       * ÊäÈë  £ºuint32_t uBaud
       * Êä³ö  : ÎÞ
       * µ÷Óà  £ºÍⲿµ÷ÓÃ
       */
      void USART2_Configuration(uint32_t uBaud)
      {
      	
      	USART_InitTypeDef USART_InitStructure;
      	NVIC_InitTypeDef NVIC_InitStructure;   
      	GPIO_InitTypeDef GPIO_InitStructure;
      	
      	
      	/* config USART2 clock */
          RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
          RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); 
      	USART_DeInit(USART2);
      	/* USART2 GPIO config */
      	/* Configure USART2 Tx (PA2) as alternate function push-pull */
      	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
      	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
      	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      	GPIO_Init(GPIOA, &GPIO_InitStructure);    
      	
      	/* Configure USART2 Rx (PA3) as input floating */
      	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
      	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
      	GPIO_Init(GPIOA, &GPIO_InitStructure);
        
      	NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;//?????3
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;    
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;    
        NVIC_Init(&NVIC_InitStructure);    
        
      	/* USART2 mode config */
      	USART_InitStructure.USART_BaudRate = uBaud;
      	USART_InitStructure.USART_WordLength = USART_WordLength_8b;
      	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); 
      	
      	USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
      	USART_Cmd(USART2, ENABLE);
      	
      }		   
      

      中断子函数如下
      void USART2_IRQHandler(void)
      {
      // uint8_t i = 0;
      //if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET)
      //{
      // i=USART_ReceiveData(USART2);
      // USART_SendData(USART2,i);
      //
      //}
      static uint8_t rebuf[8]={0},i=0;

      if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET)
      {
      	rebuf[i++]=USART_ReceiveData(USART2);	
      	if(rebuf[0]!=0xb3)//ÅжÏÖ¡Í·
      		i=0;
        if((i==2)&&(rebuf[1]!=0xb3))//ÅжÏÖ¡Í·
      		i=0;
      	if(i>=7)//µ±i¼ÆÊýÖµ=8ʱ£¬¹¦ÄÜ×Ö½Ú½ÓÊÜÍê±Ï£¬Êý¾Ý³¤¶È×Ö½Ú½ÓÊÕÍê±Ï
      	{
      		memcpy(OpenMV_Rx_BUF,rebuf,i);
      		
      		i = 0;
      
      	}
      	USART_ClearFlag(USART2,USART_FLAG_RXNE);//ÇåÖжϱêÖ¾
      }	
      

      }

      同样使用串口助手将从openmv接收到的数据发送到单片机上,发现能完美接收到,并且没有错误。

      但是,重点来了,将openmv和单片机串口连接时,单片机收!不!到!数!据!了(t和r已对调),我是真的调了一天了,希望有专业人士能帮我解答,没齿难忘。



    • 我觉得程序应该是没有问题了,想是不是硬件有什么我忽略的地方,求告知



    • void USART2_IRQHandler(void)
      {

      static uint8_t rebuf[8]={0},i=0;
      
      if(USART_GetITStatus(USART2,USART_IT_RXNE) != RESET)
      {
      	rebuf[i++]=USART_ReceiveData(USART2);	
      	if(rebuf[0]!=0xb3)//ÅжÏÖ¡Í·
      		i=0;
        if((i==2)&&(rebuf[1]!=0xb3))//ÅжÏÖ¡Í·
      		i=0;
      	if(i>=7)//µ±i¼ÆÊýÖµ=8ʱ£¬¹¦ÄÜ×Ö½Ú½ÓÊÜÍê±Ï£¬Êý¾Ý³¤¶È×Ö½Ú½ÓÊÕÍê±Ï
      	{
      		memcpy(OpenMV_Rx_BUF,rebuf,i);
      		
      		i = 0;
      
      	}
      	USART_ClearFlag(USART2,USART_FLAG_RXNE);//ÇåÖжϱêÖ¾
      }	
      

      }

      void USART2_Configuration(uint32_t uBaud)
      {

      USART_InitTypeDef USART_InitStructure;
      NVIC_InitTypeDef NVIC_InitStructure;   
      GPIO_InitTypeDef GPIO_InitStructure;
      
      
      /* config USART2 clock */
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
      RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE); 
      USART_DeInit(USART2);
      /* USART2 GPIO config */
      /* Configure USART2 Tx (PA2) as alternate function push-pull */
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
      GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
      GPIO_Init(GPIOA, &GPIO_InitStructure);    
      
      /* Configure USART2 Rx (PA3) as input floating */
      GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
      GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
      GPIO_Init(GPIOA, &GPIO_InitStructure);
      
      NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
      

      NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1 ;//?????3
      NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;
      NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
      NVIC_Init(&NVIC_InitStructure);

      /* USART2 mode config */
      USART_InitStructure.USART_BaudRate = uBaud;
      USART_InitStructure.USART_WordLength = USART_WordLength_8b;
      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); 
      
      USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
      USART_Cmd(USART2, ENABLE);
      

      }
      刚才看了下程序排版乱码,重新发下



    • 补充一点,经过在线调试发现,是无法正确进入串口中断函数



    • 我只能解决OpenMV上的问题,不能解决你的STM32上的问题。



    • 也许你应该用逻辑分析仪,看看tx,rx上的数据。



    • 如果有数据就说明OpenMV发送出去了,
      如果没有数据没准你OpenMV的操作步骤不对,根本没运行程序。比如脱机运行的步骤之类的。



    • 脱机用串口助手是能收到数据的



    • 那可能是接线的问题?或者是测试的数据不一样。



    • import sensor, image, time
      from pyb import UART
      
      threshold = [(37, 67, 45, 84, 4, 68),         #red
                  # (0, 80, -70, -10, -0,  30),      #green
                   (25, 67, -37, 26, -63, -26)]    #blue
      #设置红色的阈值,括号里面的数值分别是L A B 的最大值和最小值(minL, maxL, minA,
      # maxA, minB, maxB),LAB的值在图像左侧三个坐标图中选取。如果是灰度图,则只需
      #设置(min, max)两个数字即可。
      
      sensor.reset()
      sensor.set_pixformat(sensor.RGB565)
      sensor.set_framesize(sensor.QVGA)
      sensor.skip_frames(time = 2000 )
      sensor.set_auto_whitebal(False)
      #关闭白平衡。白平衡是默认开启的,在颜色识别中,需要关闭白平衡。
      
      clock = time.clock()
      
      uart = UART(3, 115200)
      
      uart.init(115200, bits=8, parity=None, stop=1)  #8位数据位,无校验位,1位停止位、
      
      while(True):
          clock.tick()
          img = sensor.snapshot()
          blob = img.find_blobs(threshold, area_threshold=300)
          if blob: #如果找到了目标颜色
             # print(blob)
              uart.write("B3 B3 ")    #一帧数据的帧头
              for b in blob:
              #迭代找到的目标颜色区域
                  img.draw_rectangle(b[0:4]) # rect
                  img.draw_cross(b[5], b[6]) # cx, cy
                  x = b.cx()
                  y = b.cy()
      
                  print(x, y, end = ',')
      
                  uart.write("%x %x "%(x,y))   #以16进制的格式输出
      
          #img.draw_circle((50, 50, 30), color = (250, 0, 0))
      
      
          print(clock.fps())
      
      

      这是我openmv上的代码,请看看有什么问题吗



    • 我今天发现了,有的串口助手能给我的单片机发数据,有的不能,这是为什么呢,感觉和我遇到的问题很像



    • 终于解决了,特地再来回复一下,希望以后的小伙伴不要在绕弯路了
      转载自:https://blog.csdn.net/zzzzjh/article/details/80725348
      penmv发送16进制数据需要转换为字节的形式,假设要发送 0x80,0x06,0x02,0x78这几个16进制数据代码如下:
      uart = UART(3, 9600) #波特率9600
      uart.init(9600, bits=8, parity=None, stop=1)
      data=bytearray([0x80,0x06,0x02,0x78])
      uart.write(data)



    • 你上面代码uart.write("%x %x "%(x,y))的是字符串。



    • 其实你要发送单个的数值(num)的时候只需要使用uart.writechar(num)就行了,uart.write()是发送字符串。



    • @17072969344 同学,您修改后的串口通信代码能再发一下吗?谢谢了