当前位置:   article > 正文

总结两种串口与通信的方式_无人机飞控串口通信协议

无人机飞控串口通信协议

文章目录


前言

这个暑假参加了电赛,做的是飞机题,因此经常需要使用到串口通信,完成各个模块之间的通信。但是,在使用串口的时候却发现很多的问题,因此这里记录一下一些串口通信方式。主要参考匿名飞控的串口的通信代码。

一、STM32与Openmv之间的串口通信(通信数据长度已知)

1.STM32

首先,先给出匿名飞控之间的串口通信的协议。

 由上图可知,匿名飞控之间的串口通信都是数据长度已知的

下面开始分析代码

首先是串口的配置(STM32F103C8T6)

  1. //USART1
  2. void DrvUart1Init(u32 br_num)
  3. {
  4. USART_InitTypeDef USART_InitStructure;
  5. USART_ClockInitTypeDef USART_ClockInitStruct;
  6. NVIC_InitTypeDef NVIC_InitStructure;
  7. GPIO_InitTypeDef GPIO_InitStructure;
  8. USART_StructInit(&USART_InitStructure);
  9. RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE); //使能USART1,GPIOA时钟
  10. //Usart1 NVIC 配置
  11. NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
  12. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
  13. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; //子优先级3
  14. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道使能
  15. NVIC_Init(&NVIC_InitStructure); //根据指定的参数初始化VIC寄存器
  16. // GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_USART3);
  17. // GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_USART3);
  18. //USART1_TX GPIOA.9
  19. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
  20. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  21. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; //复用推挽输出
  22. GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9
  23. //USART1_RX GPIOA.10初始化
  24. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
  25. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
  26. GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10
  27. USART_InitStructure.USART_BaudRate = br_num;
  28. USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  29. USART_InitStructure.USART_StopBits = USART_StopBits_1;
  30. USART_InitStructure.USART_Parity = USART_Parity_No;
  31. USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  32. USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
  33. USART_ClockInitStruct.USART_Clock = USART_Clock_Disable;
  34. USART_ClockInitStruct.USART_CPOL = USART_CPOL_Low;
  35. USART_ClockInitStruct.USART_CPHA = USART_CPHA_2Edge;
  36. USART_ClockInitStruct.USART_LastBit = USART_LastBit_Disable;
  37. USART_Init(USART1, &USART_InitStructure);
  38. USART_ClockInit(USART1, &USART_ClockInitStruct);
  39. USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);
  40. USART_Cmd(USART1, ENABLE);
  41. }
  42. u8 Tx1Buffer[256];
  43. u8 Tx1Counter = 0;
  44. u8 count1 = 0;
  45. void DrvUart1SendBuf(unsigned char *DataToSend, u8 data_num)
  46. {
  47. u8 i;
  48. for (i = 0; i < data_num; i++)
  49. {
  50. Tx1Buffer[count1++] = *(DataToSend + i);
  51. }
  52. if (!(USART1->CR1 & USART_CR1_TXEIE))
  53. {
  54. USART_ITConfig(USART1, USART_IT_TXE, ENABLE); //打开发送中断
  55. }
  56. }
  57. u8 U1RxDataTmp[100];
  58. u8 U1RxInCnt = 0;
  59. u8 U1RxoutCnt = 0;
  60. void drvU1GetByte(u8 data)
  61. {
  62. U1RxDataTmp[U1RxInCnt++] = data;
  63. if(U1RxInCnt >= 100)
  64. U1RxInCnt = 0;
  65. }
  66. void drvU1DataCheck(void)
  67. {
  68. while(U1RxInCnt!=U1RxoutCnt)
  69. {
  70. U1GetOneByte(U1RxDataTmp[U1RxoutCnt++]);
  71. if(U1RxoutCnt >= 100)
  72. U1RxoutCnt = 0;
  73. }
  74. }
  75. void Usart1_IRQ(void)
  76. {
  77. u8 com_data;
  78. if (USART1->SR & USART_SR_ORE) //ORE中断
  79. {
  80. com_data = USART1->DR;
  81. }
  82. //接收中断
  83. if (USART_GetITStatus(USART1, USART_IT_RXNE))
  84. {
  85. USART_ClearITPendingBit(USART1, USART_IT_RXNE); //清除中断标志
  86. Res_Data = USART1->DR;
  87. drvU1GetByte(com_data);
  88. }
  89. //发送(进入移位)中断
  90. if (USART_GetITStatus(USART1, USART_IT_TXE))
  91. {
  92. USART1->DR = Tx1Buffer[Tx1Counter++]; //写DR清除中断标志
  93. if (Tx1Counter == count1)
  94. {
  95. USART1->CR1 &= ~USART_CR1_TXEIE; //关闭TXE(发送中断)中断
  96. }
  97. }
  98. }
  99. void USART1_IRQHandler(void)
  100. {
  101. Usart1_IRQ();
  102. }
  103. //USART3
  104. void DrvUart3Init(u32 br_num)
  105. {
  106. USART_InitTypeDef USART_InitStructure;
  107. USART_ClockInitTypeDef USART_ClockInitStruct;
  108. NVIC_InitTypeDef NVIC_InitStructure;
  109. GPIO_InitTypeDef GPIO_InitStructure;
  110. USART_StructInit(&USART_InitStructure);
  111. RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
  112. RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
  113. NVIC_InitStructure.NVIC_IRQChannel = USART3_IRQn;
  114. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
  115. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
  116. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  117. NVIC_Init(&NVIC_InitStructure);
  118. // GPIO_PinAFConfig(GPIOB, GPIO_PinSource10, GPIO_AF_USART3);
  119. // GPIO_PinAFConfig(GPIOB, GPIO_PinSource11, GPIO_AF_USART3);
  120. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;
  121. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;
  122. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  123. GPIO_Init(GPIOB, &GPIO_InitStructure);
  124. GPIO_InitStructure.GPIO_Pin = GPIO_Pin_11;
  125. GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
  126. GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  127. GPIO_Init(GPIOB, &GPIO_InitStructure);
  128. USART_InitStructure.USART_BaudRate = br_num;
  129. USART_InitStructure.USART_WordLength = USART_WordLength_8b;
  130. USART_InitStructure.USART_StopBits = USART_StopBits_1;
  131. USART_InitStructure.USART_Parity = USART_Parity_No;
  132. USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
  133. USART_InitStructure.USART_Mode = USART_Mode_Tx | USART_Mode_Rx;
  134. USART_ClockInitStruct.USART_Clock = USART_Clock_Disable;
  135. USART_ClockInitStruct.USART_CPOL = USART_CPOL_Low;
  136. USART_ClockInitStruct.USART_CPHA = USART_CPHA_2Edge;
  137. USART_ClockInitStruct.USART_LastBit = USART_LastBit_Disable;
  138. USART_Init(USART3, &USART_InitStructure);
  139. USART_ClockInit(USART3, &USART_ClockInitStruct);
  140. USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
  141. USART_Cmd(USART3, ENABLE);
  142. }
  143. u8 Tx3Buffer[256];
  144. u8 Tx3Counter = 0;
  145. u8 count3 = 0;
  146. void DrvUart3SendBuf(unsigned char *DataToSend, u8 data_num)
  147. {
  148. u8 i;
  149. for (i = 0; i < data_num; i++)
  150. {
  151. Tx3Buffer[count3++] = *(DataToSend + i);
  152. }
  153. if (!(USART3->CR1 & USART_CR1_TXEIE))
  154. {
  155. USART_ITConfig(USART3, USART_IT_TXE, ENABLE); //打开发送中断
  156. }
  157. }
  158. u8 U3RxDataTmp[100];
  159. u8 U3RxInCnt = 0;
  160. u8 U3RxoutCnt = 0;
  161. void drvU3GetByte(u8 data)
  162. {
  163. U3RxDataTmp[U3RxInCnt++] = data;
  164. if(U3RxInCnt >= 100)
  165. U3RxInCnt = 0;
  166. }
  167. void drvU3DataCheck(void)
  168. {
  169. while(U3RxInCnt!=U3RxoutCnt)
  170. {
  171. U3GetOneByte(U3RxDataTmp[U3RxoutCnt++]);
  172. if(U3RxoutCnt >= 100)
  173. U3RxoutCnt = 0;
  174. }
  175. }
  176. void Usart3_IRQ(void)
  177. {
  178. u8 com_data;
  179. if (USART3->SR & USART_SR_ORE) //ORE中断
  180. com_data = USART3->DR;
  181. //接收中断
  182. if (USART_GetITStatus(USART3, USART_IT_RXNE))
  183. {
  184. USART_ClearITPendingBit(USART3, USART_IT_RXNE); //清除中断标志
  185. com_data = USART3->DR;
  186. drvU3GetByte(com_data);
  187. }
  188. //发送(进入移位)中断
  189. if (USART_GetITStatus(USART3, USART_IT_TXE))
  190. {
  191. USART3->DR = Tx3Buffer[Tx3Counter++]; //写DR清除中断标志
  192. if (Tx3Counter == count3)
  193. {
  194. USART3->CR1 &= ~USART_CR1_TXEIE; //关闭TXE(发送中断)中断
  195. }
  196. }
  197. }
  198. void DrvUartDataCheck(void)
  199. {
  200. drvU3DataCheck();
  201. drvU1DataCheck();
  202. }
  203. void USART3_IRQHandler(void)
  204. {
  205. Usart3_IRQ();
  206. }

        需要注意的事,匿名飞控的Usart3_IRQ();Usart1_IRQ();都是封装好的串口处理函数,使用时,必须把它们放到对应的中断函数处理函数void USART3_IRQHandler(void),否则程序会卡死。同时,将void DrvUartDataCheck(void)这个函数需要放入1ms的中断(建议用一个定时器作为系统的定时,1ms进入1次),这样串口收发的数据就会1ms处理一次。

        void DrvUartDataCheck(void)中调用drvU3DataCheck()就是对应串口的数据接收处理的部分。

  1. void drvU3DataCheck(void)
  2. {
  3. while(U3RxInCnt!=U3RxoutCnt)
  4. {
  5. U3GetOneByte(U3RxDataTmp[U3RxoutCnt++]);
  6. if(U3RxoutCnt >= 100)
  7. U3RxoutCnt = 0;
  8. }
  9. }

        drvU3DataCheck()中调用了用户自定义的串口接收函数U3GetOneByte()U3GetOneByte可以通过宏定义修改为自定义函数名。例如下图 

        同时,这个时候自己就可以在另外的.c文件中定义自己的函数接收函数 ,下面以OPENMV_GetOneByte为例。

 

 

 

下面为代码 

  1. /***********接受数据定义区***************/
  2. #define BB_data0 opmv.lt.shape_flag
  3. #define BB_data1 opmv.lt.err_X
  4. #define BB_data2 opmv.lt.shape_cx
  5. #define BB_data3 opmv.lt.err_Dis
  6. #define BB_data4 opmv.lt.ultrasonic_distance
  7. #define BB_data5 opmv.lt.fire_flag
  8. #define BB_data6 opmv.lt.color_flag
  9. #define BB_data7 opmv.lt.y_vel_out//openmv x方向速度
  10. #define BB_data8 opmv.lt.x_vel_out//超声波前后 控制速度
  11. #define CC_data0 opmv.lt.found_flag//光源寻找到的标志位
  12. #define CC_data1 opmv.lt.red_cx
  13. #define CC_data2 opmv.lt.red_cy
  14. #define CC_data3 opmv.lt.green_pid_vel_v
  15. #define CC_data4 opmv.lt.red_pid_vel_v
  16. #define CC_data5 opmv.lt.ultrasonic_distance
  17. #define CC_data6 opmv.lt.ultrasonic_vel_v
  18. #define CC_data7 opmv.lt.y_vel_out//
  19. #define CC_data8 opmv.lt.x_vel_out
  20. #define DD_data0 opmv.lt.start_flag
  21. #define DD_data1 opmv.lt.start_flag2
  22. #define DD_data2 nouse
  23. #define DD_data3 nouse
  24. #define DD_data4 nouse
  25. #define DD_data5 nouse
  26. #define DD_data6 nouse
  27. #define DD_data7 nouse
  28. #define DD_data8 nouse
  29. /***********接受数据处理***************/
  30. static void OPENMV_DataAnl(uint8_t *data, uint8_t len1)
  31. {
  32. u8 check_sum3 = 0, check_sum4 = 0;
  33. if (*(data + 3) != (len1 - 6)) //判断数据长度是否正确
  34. return;
  35. for (u8 i = 0; i < len1 - 2; i++)
  36. {
  37. check_sum3 += *(data + i);
  38. check_sum4 += check_sum3;
  39. }
  40. if ((check_sum3 != *(data + len1 - 2)) || (check_sum4 != *(data + len1 - 1))) //判断sum校验
  41. return;
  42. //================================================================================
  43. if(*(data + 2) == 0XBB)//底面的openmv
  44. {
  45. BB_data0 = *(data + 4)<<8|*(data + 5);//opmv.lt.shape_flag
  46. BB_data1 = *(data + 6)<<8|*(data + 7);//opmv.lt.color_flag
  47. BB_data2 = *(data + 8)<<8|*(data + 9);//opmv.lt.shape_cx
  48. BB_data3 = *(data + 10)<<8|*(data + 11);//opmv.lt.shape_cy
  49. BB_data4 = *(data + 12)<<8|*(data + 13);//Nouse
  50. BB_data5 = *(data + 14)<<8|*(data + 15);//Nouse
  51. BB_data6 = *(data + 16)<<8|*(data + 17);//Nouse
  52. BB_data7 = *(data + 18)<<8|*(data + 19);//opmv.lt.shape_cy
  53. BB_data8 = *(data +20)<<8|*(data + 21);//opmv.lt.shape_cy
  54. }
  55. else if(*(data + 2) == 0XCC)//顶面的openmv
  56. {
  57. CC_data0 = *(data + 4)<<8|*(data + 5);//Nouse
  58. CC_data1 = *(data + 6)<<8|*(data + 7);//Nouse
  59. CC_data2 = *(data + 8)<<8|*(data + 9);//Nouse
  60. // CC_data3 = *(data + 10)<<8|*(data + 11);//Nouse
  61. // CC_data4 = *(data + 12)<<8|*(data + 13);//Nouse
  62. // CC_data5 = *(data + 14)<<8|*(data + 15);//Nouse
  63. // CC_data6 = *(data + 16)<<8|*(data + 17);//Nouse
  64. CC_data7 = *(data + 18)<<8|*(data + 19);//Nouse
  65. CC_data8 = *(data +20)<<8|*(data + 21);//Nouse
  66. }
  67. else if(*(data + 2) == 0XDD)//zigbee数传
  68. {
  69. DD_data0 = *(data + 4);//opmv.lt.start_flag
  70. DD_data1 = *(data + 5);//Nouse
  71. // DD_data2 = *(data + 8)<<8|*(data + 9);//Nouse
  72. // DD_data3 = *(data + 10)<<8|*(data + 11);//Nouse
  73. // DD_data4 = *(data + 12)<<8|*(data + 13);//Nouse
  74. // DD_data5 = *(data + 14)<<8|*(data + 15);//Nouse
  75. // DD_data6 = *(data + 16)<<8|*(data + 17);//Nouse
  76. // DD_data7 = *(data + 18)<<8|*(data + 19);//Nouse
  77. // DD_data8 = *(data +20)<<8|*(data + 21);//Nouse
  78. }
  79. }
  80. # define HW_TYPE 0x61
  81. /***********接受数据解析,参考匿名飞控通信协议***************/
  82. void OPENMV_GetOneByte(uint8_t data)
  83. {
  84. static u8 _data_len = 0, _data_cnt = 0;
  85. static u8 rxstate = 0;
  86. if (rxstate == 0 && data == 0xAA)
  87. {
  88. rxstate = 1;
  89. uart3_datatemp[0] = data;
  90. }
  91. else if (rxstate == 1 && (data == HW_TYPE || data == HW_ALL))
  92. {
  93. rxstate = 2;
  94. uart3_datatemp[1] = data;
  95. }
  96. else if (rxstate == 2)
  97. {
  98. rxstate = 3;
  99. uart3_datatemp[2] = data;
  100. }
  101. else if (rxstate == 3 && data < 250)
  102. {
  103. rxstate = 4;
  104. uart3_datatemp[3] = data;
  105. _data_len = data;
  106. _data_cnt = 0;
  107. }
  108. else if (rxstate == 4 && _data_len > 0)
  109. {
  110. _data_len--;
  111. uart3_datatemp[4 + _data_cnt++] = data;
  112. if (_data_len == 0)
  113. rxstate = 5;
  114. }
  115. else if (rxstate == 5)
  116. {
  117. rxstate = 6;
  118. uart3_datatemp[4 + _data_cnt++] = data;
  119. }
  120. else if (rxstate == 6)
  121. {
  122. rxstate = 0;
  123. uart3_datatemp[4 + _data_cnt] = data;
  124. // DT_data_cnt = _data_cnt+5;
  125. //
  126. OPENMV_DataAnl(uart3_datatemp, _data_cnt + 5); //
  127. }
  128. else
  129. {
  130. rxstate = 0;
  131. }
  132. }

         void OPENMV_GetOneByte(uint8_t data)就是按照匿名协议进行数据接收,接受完一帧数据后调用OPENMV_DataAnl(uart3_datatemp, _data_cnt + 5)这个函数,进行数据解析,通过自己的宏定义与数据对应上,这里采用宏定义主要是为了与openmv那边的数据位对应上(方便与视觉队友对接),同时在1对多的通信也比较容易区分。

2.OPENMV

  1. from pyb import UART
  2. uart = UART(3,500000)
  3. class Receive(object):
  4. uart_buf = []
  5. _data_len = 0
  6. _data_cnt = 0
  7. state = 0
  8. R=Receive()
  9. class Ctrl(object):
  10. Data1 = 0
  11. Data2 = 0
  12. Data3 = 0
  13. Data4 = 0
  14. Data5 = 0
  15. Data6 = 0
  16. Data7 = 0
  17. Data8 = 0
  18. Data9 = 0
  19. Data10 = 0
  20. IsDebug = 1
  21. T_ms = 0
  22. Ctr=Ctrl()
  23. def UartSendData(Data):
  24. if uart.write(Data)==None:
  25. print('send error')
  26. def ReceiveAnl(data_buf):
  27. Ctr.Data1=data_buf[2]
  28. Ctr.Data2=data_buf[3]
  29. Ctr.Data3=data_buf[4]
  30. Ctr.Data4=data_buf[5]
  31. Ctr.Data5=data_buf[6]
  32. Ctr.Data6=data_buf[7]
  33. Ctr.Data7=data_buf[8]
  34. Ctr.Data8=data_buf[9]
  35. Ctr.Data9=data_buf[10]
  36. Ctr.Data10=data_buf[11]
  37. def ReceivePrepare(data):
  38. if R.state==0:
  39. if data == 0xAA:
  40. R.uart_buf.append(data)
  41. R.state = 1
  42. else:
  43. R.state = 0
  44. elif R.state==1:
  45. if data == 0x32:
  46. R.uart_buf.append(data)
  47. R.state = 2
  48. else:
  49. R.state = 0
  50. elif R.state==2:
  51. R.uart_buf.append(data)
  52. R.state = 3
  53. elif R.state==3:
  54. R.state = 4
  55. R.uart_buf.append(data)
  56. elif R.state==4:
  57. R.uart_buf.append(data)
  58. R.state = 5
  59. elif R.state==5:
  60. R.state = 6
  61. R.uart_buf.append(data)
  62. elif R.state==6:
  63. R.uart_buf.append(data)
  64. R.state = 7
  65. elif R.state==7:
  66. R.state = 8
  67. R.uart_buf.append(data)
  68. elif R.state==8:
  69. R.state = 9
  70. R.uart_buf.append(data)
  71. elif R.state==9:
  72. R.state = 10
  73. R.uart_buf.append(data)
  74. elif R.state==10:
  75. R.state = 11
  76. R.uart_buf.append(data)
  77. elif R.state==11:
  78. R.state = 12
  79. R.uart_buf.append(data)
  80. elif R.state==12:
  81. if data == 0xdd:
  82. R.state = 0
  83. R.uart_buf.append(data)
  84. ReceiveAnl(R.uart_buf)
  85. R.uart_buf=[]#清空缓冲区,准备下次接收数据
  86. else:
  87. R.state = 0
  88. else:
  89. R.state = 0
  90. def UartReadBuffer():
  91. i = 0
  92. Buffer_size = uart.any()
  93. while i<Buffer_size:
  94. ReceivePrepare(uart.readchar())
  95. i = i + 1
  96. def UserDataPack(data0,data1,data2,data3,data4,data5,data6,data7,data8):
  97. UserData=bytearray([0xAA,0x61,0xBB,0x00
  98. ,data0,data1,data2,data3,data4,data5,data6,data7,data8
  99. ,0x00,0x00])
  100. lens = len(UserData)
  101. UserData[3] = lens-6;
  102. i = 0
  103. sum = 0
  104. sum1 = 0
  105. while i<(lens-2):
  106. sum = sum + UserData[i]
  107. sum1 = sum1 + sum
  108. i = i+1
  109. UserData[lens-2] = sum;
  110. UserData[lens-1] = sum1;
  111. return UserData

        这里也是参照匿名openmv的代码,这边的代码就参考上图进行修改。但是注意openmv在接受数据的时候存在丢包的现象,目前还不清楚为什么。飞控这边为了减少处理的压力,把一部分的PID运算放到了Openmv端,但是在初始化PID参数的时候发现经常会有某个PID无法传参,存在丢包现象。因此,为保险起见,飞控在传输数据到openmv时,通常是连续发个几百毫秒

 3.小结

        以上便是数据长度已知的串口通信方式,之后在运用的时候可以参照这种方式修改,调了一个暑假这种方式还是挺稳定的。

  1. void Uart_Send_Str(unsigned char * p)
  2. {
  3. while(*p)
  4. {
  5. Uart_Send_byte(*p++);
  6. }
  7. }

        值得注意的事,进行串口发送的时候,采用上述代码的方式一旦数据有0便会结束,调用void DrvUart1SendBuf(unsigned char *DataToSend, u8 data_num),这个函数进行发送的时候就不会。

二、STM32与UWB之间的通信(通信数据长度未知)

UWB的通信协议

UWB配置完成后会,自动按照上述例子将数据发送过来,按照字符进行发送,数据不定长。当时比赛的时候是第一次用这个UWB,虽然协议很简单,但是为了读UWB的数据也花费了一个下午的时间。 

1.STM32

       这里也是采用匿名飞控的程序的数据接收,但是数据解析函数有些不相同。

  1. #define UART2_BUFFER_SIZE 100 // 假设uart2_datatemp的大小为100
  2. void UWB_GetOneByte(char data)
  3. {
  4. static u8 rxstate_2 = 0;
  5. static u8 i = 0;
  6. // 增加数据长度检查,防止数据长度超出缓冲区大小
  7. if (i >= UART2_BUFFER_SIZE - 1)
  8. {
  9. // 缓冲区已满,进行错误处理或清空操作
  10. rxstate_2 = 0;
  11. i = 0;
  12. // 这里可以根据实际情况进行处理,比如错误提示、丢弃当前数据等
  13. return;
  14. }
  15. if (rxstate_2 == 0 && data == '[')
  16. {
  17. rxstate_2 = 1;
  18. uart2_datatemp[0] = data;
  19. }
  20. else if (rxstate_2 == 1)
  21. {
  22. if (data != ']')
  23. {
  24. i++;
  25. uart2_datatemp[i] = data;
  26. }
  27. else
  28. {
  29. i++;
  30. uart2_datatemp[i] = data;
  31. // 增加对数据长度的检查,防止传递错误的数据长度
  32. if (i + 2 <= UART2_BUFFER_SIZE)
  33. {
  34. UWB_Data_Anl(uart2_datatemp, i + 2);
  35. }
  36. // 处理完一组数据后,重置接收状态和缓冲区
  37. rxstate_2 = 0;
  38. i = 0;
  39. // 清空缓冲区
  40. // memset(uart2_datatemp, 0, sizeof(uart2_datatemp));
  41. }
  42. }
  43. else
  44. {
  45. // 处理未知状态,重置接收状态和缓冲区
  46. rxstate_2 = 0;
  47. i = 0;
  48. // 清空缓冲区
  49. //memset(uart2_datatemp, 0, sizeof(uart2_datatemp));
  50. }
  51. }

          注意这这rxstate_2、i两个变量在接受完成或者数据接收错误的时候都要清0。


 三、总结

        目前这就更新到这里,以后在遇到坑再过来填!

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

闽ICP备14008679号