STM32串口收发——中断、DMA、不定长数据处理策略
一、中断接收单字节串口数据流程
0-定义接收变量
uint8_t *Rx_Buf;
1-主函数中开启串口接收中断函数。(需主动添加)
开启中断使能
HAL_UART_Transmit_IT(&huart2,Rx_Buf,1);
2-编写中断回调函数(需主动添加)
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
if(huart->Instance == USART2)
{
HAL_UART_Transmit(&huart2,Rx_Buf,1,1000);
HAL_UART_Receive_IT(&huart2,Rx_Buf,1);
}
}
其中条件判断语句用于确定中断源来自哪一个串口。
二、DMA接收
CPU开启DMA传输。
0-选中DMA传输方式
2-接收函数改成DMA方式:
HAL_UART_DMAStop((UART HandleTypeDef *)&huartl);
HAL Delay(3);//需要根据实际情况进行调节
HAL_UART_Receive_DMA((UART HandleTypeDef *) &huartl,(uint8 t *)rx buf,(uint16 t) 5):
注意:务必先初始化 DMA,再初始化串口。否则无法接收到数据。
可以按照下图进行调整。
三、不定长接收
0-使能目标串口中断
HAL_UART_Transmit_IT(&huart2,Rx_Buf,1);
1-使能串口空闲中断
__HAL_UART_ENABLE_IT(&huart2,UART_IT_IDLE);
如下图
2-修改对应串口的中断服务函数
在stm32fxxx_it.c中找到串口中断服务函数。以usart2为例如下:
void USART2_IRQHandler(void)
{
/* USER CODE BEGIN USART2_IRQn 0 */
if(__HAL_UART_GET_FLAG(&huart2,UART_FLAG_IDLE)!=RESET)
UartIdleCallBackFunc(&huart2);
/* USER CODE END USART2_IRQn 0 */
HAL_UART_IRQHandler(&huart2);
/* USER CODE BEGIN USART2_IRQn 1 */
/* USER CODE END USART2_IRQn 1 */
}
/* USER CODE BEGIN 1 */
void UartIdleCallBackFunc(UART_HandleTypeDef *huart)
{
__HAL_UART_CLEAR_IDLEFLAG(huart); //Cleax IDLE Interupt Flag
huart->pRxBuffPtr = RxBuffer; //Move the receive buffer pointer to the head
huart->RxXferCount =0; //Cleax UART Rx Trangrex Countex
xxxxx; //中断服务相关业务
}
/* USER CODE END 1 */
其中“UartIdleCallBackFunc()”为自定义的空闲中断服务函数。函数中首先处理做三个动作:
1-清除空闲中断标志位;——防止频繁进入空闲中断
2-将uart接收数据的指针指向目标数组(缓存区)的首地址;——从新对缓存区进行写入
3-清除计数。——从新计数写入缓存区大小