STM32串口收发——中断、DMA、不定长数据处理策略

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-清除计数。——从新计数写入缓存区大小

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
在使用STM32DMA方式进行串口数据收发时,可以使用空闲中断来判断数据接收完成。具体步骤如下: 1. 配置串口DMA模式,设置DMA通道和缓存地址等参数。 2. 启动DMA传输,使其开始接收数据。 3. 在空闲中断中判断DMA传输是否完成,可以通过检查DMA传输的剩余数据度来判断。如果剩余数据度为0,则说明数据传输完成。 4. 在空闲中断中处理接收到的数据,例如将数据存储到缓存中等操作。 5. 处理完接收到的数据后,重新配置DMA通道和缓存地址等参数,使其可以继续接收数据。 下面是一个简单的示例代码: ```c void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { // 检查DMA传输是否完成 if (__HAL_DMA_GET_COUNTER(huart->hdmarx) == 0) { // 处理接收到的数据 // ... // 重新配置DMA通道和缓存地址等参数 HAL_UART_Receive_DMA(huart, rx_buffer, BUFFER_SIZE); } } int main() { // 初始化串口DMA通道等参数 HAL_UART_Receive_DMA(&huart, rx_buffer, BUFFER_SIZE); // 启用空闲中断 __HAL_UART_ENABLE_IT(&huart, UART_IT_IDLE); while (1) { // 主循环 // ... } } ``` 在以上示例代码中,我们先使用HAL_UART_Receive_DMA函数启动DMA传输,并在空闲中断中检查DMA传输是否完成。如果传输完成,则处理接收到的数据,并重新配置DMA通道和缓存地址等参数,使其可以继续接收数据。同时,我们也启用了空闲中断,以便能够及时检测到数据传输的完成。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值