当前位置:   article > 正文

OpenMV与STM32单片机通信 串口接收数据不全_stm32串口接收数据不完整

stm32串口接收数据不完整

项目场景:

OpenMV与STM32单片机通信,使用MIDI协议。


问题描述

OpenMV发送数据给单片机时,单片机只能收到4个字节,偶尔会丢失一部分数据。

接受代码如下:

  1. if( USART_GetITStatus(USART1,USART_IT_RXNE)!=RESET) //接收中断
  2. {
  3. USART_ClearITPendingBit(USART1,USART_IT_RXNE); //清除中断标志
  4. com_data = USART_ReceiveData(USART1); //串口1接收数据
  5. if(RxState==0&&com_data==0x2C) //0x2C帧头开始数据接收处理
  6. {
  7. RxState=1;
  8. RxBuffer1[RxCounter1++]=com_data;//RxBuffer1[0]==0x2C RxCounter1==1
  9. USART_ClearFlag(USART1,USART_FLAG_TC);
  10. printf("1 \r\n");
  11. }
  12. else if(RxState==1&&com_data==0x12) //0x12帧头
  13. {
  14. RxState=2;
  15. RxBuffer1[RxCounter1++]=com_data;//RxBuffer1[0]==0x12 RxCounter1==2
  16. printf("2 \r\n");
  17. }
  18. else if(RxState==2)//开始接收有效数据
  19. {
  20. RxBuffer1[RxCounter1++]=com_data;//全部接收完,RxCounter1==6
  21. printf("%d \r\n",RxCounter1);
  22. if(RxCounter1>=6||com_data == 0x5B)//RxBuffer1接受满了或者接收数据结束
  23. {
  24. RxState=3;
  25. RxFlag1=1;
  26. Cr=RxBuffer1[2]; //RxBuffer1[2]是openmv发送的第一个有效数据
  27. Cg=RxBuffer1[3];
  28. Cb=RxBuffer1[4];
  29. }
  30. }
  31. else if(RxState==3) //检测是否接受到结束标志
  32. {
  33. if(RxBuffer1[5] == 0x5B)
  34. {
  35. USART_ITConfig(USART1,USART_IT_RXNE,DISABLE);//关闭DTSABLE中断
  36. //ws281x_colorWipe(ws281x_color(0,0,0), 1); //执行程序
  37. USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);
  38. }
  39. else //接收错误
  40. {
  41. RxState = 0;
  42. RxCounter1=0;
  43. for(i=0;i<6;i++)
  44. {
  45. RxBuffer1[i]=0x00; //将存放数据数组清零,重新开始计数
  46. }
  47. printf("No \r\n");
  48. }
  49. }
  50. else //接收异常
  51. {
  52. RxState = 0;
  53. RxCounter1=0;
  54. for(i=0;i<6;i++)
  55. {
  56. RxBuffer1[i]=0x00; //将存放数据数组清零
  57. }
  58. printf("errno \r\n");
  59. }
  60. }

 


原因分析:

发送数据为一帧,有帧头,数据,帧尾。

为检查发送的数据是啥,我在接受到帧头后立即打印出来了。

这时!!!

数据就乱码了。

因为数据打印用的是串口一,使用时会产生中断。同时单片机接受OpenMV发送的数据使用的是串口二,也会有中断,这时就会产生中断嵌套,导致接受数据错乱。


解决方案:

以目的为导向,能接受数据就行。

(1)直接不打印数据,等接受完数据之后再打印。(这时下一帧会错乱,要是实时性不高的程序可将就)

(2)使用中断控制器NVIC

串口配置:

  1. NVIC_InitTypeDef NVIC_InitStructure;
  2. NVIC_InitStructure.NVIC_IRQChannel=USART1_IRQn;//串口一
  3. NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
  4. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;//抢占优先级1
  5. NVIC_InitStructure.NVIC_IRQChannelSubPriority=0;//子优先级0
  6. NVIC_Init(&NVIC_InitStructure);

 主函数配置:

  1. //设置NVIC中断分组2: 2位抢占优先级,2位响应优先级
  2. NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);

设定好子优先级和抢占优先级即可。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/474118
推荐阅读
相关标签
  

闽ICP备14008679号