STM32 HAL库多串口任意长度接收的方法(无起始和结束标志,不使用DMA)
发现最近随便转载的很多啊,未经授权禁止转载!抄袭!!否则转载者死全家!!另外这是我的笔记,不是教程,难免会有错误,不具有很高的参考性,望周知。
今天在HAL库串口接收任意长度上卡了好久,之前用的都是标准库或者HAL库+DMA的方式来写,今天这个项目用的是F429木有标准库可用,需要和其他模块配合,其他模块发的是不定长的数据且无起始和结束标志,串口又不能用DMA,所以只得使用接收中断和空闲中断的方式来解决。
我也尝试了使用网络上的例程来实现,不知是HAL库的原因还是什么,要么是无法正常接收数据,要么就是无法进入空闲中断,因此自己摸索了好久。
现在的代码思路是:STM32的串口有一个空闲中断的功能,串口在没有数据传输的时候会进入空闲中断,因此利用空闲中断可以接收任意不定长且无起始和结束标志的数据。
首先在STM32 CubeMX中正常配置串口接收,并打开串口中断,我这里勾选了创建默认HAL_UART_IRQHandler函数的选项。
工程创建完毕之后,在main.c文件中,创建两个串口缓冲数组,以及两个unsigned char型变量用来存放接收到的串口数据。在main函数中,需要调用HAL_UART_Receive_IT函数来对串口接收中断进行配置。
还需要在main()函数中添加开启串口空闲中断的代码,有几个串口就开启几个,这里比较坑的是在HAL库中开启空闲中断的方法使用的是宏定义,鼠标在语句上不会有参数提示
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| main.c: unsigned char RxBuffer1[100]; unsigned char RxBuffer2[100]; unsigned char RxByte1; unsigned char RxByte2;
int main() { HAL_UART_Receive_IT(&huart1,&RxByte1,1); HAL_UART_Receive_IT(&huart2,&RxByte2,1); __HAL_UART_ENABLE_IT(&huart1,UART_IT_IDLE); __HAL_UART_ENABLE_IT(&huart2,UART_IT_IDLE); while(1) ...; }
|
当串口接收到数据以后,会将数据放进RxByte1变量中并调用HAL_UART_RxCpltCallback函数,因此在main.c文件中创建void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)函数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| main.c: unsigned int RxCount1; unsigned int RxCount2; unsigned char RxFlag1; unsigned char RxFlag2;
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { if(huart->Instance == USART1) { RxBuffer1[RxCount1] = RxByte1; RxCount1++; HAL_UART_Receive_IT(&huart1,&RxByte1,1); } if(huart->Instance == USART2) { RxBuffer2[RxCount2] = RxByte2; RxCount2++; HAL_UART_Receive_IT(&huart2,&RxByte2,1); }
}
|
在stm32f4xx_it.c文件中,找到串口中断服务函数,添加以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| stm32f4xx_it.c: extern unsigned int RxCount1; extern unsigned int RxCount2; extern unsigned char RxFlag1; extern unsigned char RxFlag2;
void USART1_IRQHandler(void) {
HAL_UART_IRQHandler(&huart1); if(__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE) != RESET) { __HAL_UART_CLEAR_IDLEFLAG(&huart1); RxFlag1 = 1; } }
void USART2_IRQHandler(void) {
HAL_UART_IRQHandler(&huart2); if(__HAL_UART_GET_FLAG(&huart2, UART_FLAG_IDLE) != RESET) { __HAL_UART_CLEAR_IDLEFLAG(&huart2); RxFlag2 = 1; } }
|
接着就可以在mian.c文件中处理接收到的数据了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| main.c: int main() { while (1) { if(RxFlag1 == 1) { printf("USART1:%s\r\n", RxBuffer1); memset(RxBuffer1,0,sizeof(RxBuffer1)); RxFlag1 = 0; RxCount1 = 0; } if(RxFlag2 == 1) { printf("USART2:%s\r\n", RxBuffer2); memset(RxBuffer2,0,sizeof(RxBuffer2)); RxFlag2 = 0; RxCount2 = 0; } }
|
}