stm32 串口2空闲中断死机_STM32F103串口DMA+空闲中断+多级缓冲实现不定长接收

文本提供的代码是基于STM32CubeMX生成的HAL库的。

STM32串口接收大体分为3种方式:

1、阻塞接收---HAL_UART_Receive(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size, uint32_t Timeout);

2、中断接收---HAL_UART_Receive_IT(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);

3、DMA接收---HAL_UART_Receive_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size);

本文只谈论DMA接收方式,同时增加空闲中断和多级缓冲。单纯的DMA接收适合固定长度的数据接收,局限性太大,很难适用实际项目需要。增加空闲中断,可以做到不定长接收。多级缓冲在一定程度上可以缓解裸机代码实时性差的问题。

具体步骤如下:

1.STM32CubeMX生成工程,这里介绍串口部分的设置:

2.新建usart_ex.c文件,主要关注两个函数:void HW_UART_Modem_IRQHandler(UART_HandleTypeDef *huart)和void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)。

/**

******************************************************************************

* @file    : usart_ex.c

* @author  : xEndLess

* @version : V1.0.0

* @date    : 2018-4-3

* @brief  : 本文件是对usart.c的扩展,避免每次用Cube建立工程时,需要对usart.c做出修改.

*            串口发送函数,回调函数,DMA接收完成函数,都放在这里。

*

******************************************************************************

*/

/* Includes ------------------------------------------------------------------*/

#include "bsp.h"

#include "stdarg.h"

/* Private typedef -----------------------------------------------------------*/

/* Private define ------------------------------------------------------------*/

/* Private macro -------------------------------------------------------------*/

/* Private variables ---------------------------------------------------------*/

Usart1_BufTypeDef Usart1Buf;

Usart2_BufTypeDef Usart2Buf;

Usart3_BufTypeDef Usart3Buf;

Usart4_BufTypeDef Usart4Buf;

Usart5_BufTypeDef Usart5Buf;

/* 以下4个变量是在uasrt.c中定义的 ,Cube自动生成 */

extern DMA_HandleTypeDef hdma_uart4_rx;

extern DMA_HandleTypeDef hdma_usart1_rx;

extern DMA_HandleTypeDef hdma_usart2_rx;

extern DMA_HandleTypeDef hdma_usart3_rx;

/* Private function prototypes -----------------------------------------------*/

/* Private functions ---------------------------------------------------------*/

/****************** UART CallBack *******************/

/**

* @brief  Rx Transfer completed callback

* @param  UartHandle: UART handle

* @note  This example shows a simple way to report end of DMA Rx transfer, and

*        you can add your own implementation.

* @retval None

*/

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)

{

if (huart->Instance == USART1)

{

Usart1Buf.RxEndFlag[Usart1Buf.RxDimension] = SET;

Usart1Buf.RxEndIndex[Usart1Buf.RxDimension] = USART1_BUF_LENGTH - __HAL_DMA_GET_COUNTER(&hdma_usart1_rx);

Usart1Buf.RxDimension++;

Usart1Buf.RxDimension %= USART1_BUF_DIMENSION;

你可能感兴趣的:(stm32,串口2空闲中断死机)