通过串口空闲中断结合DMA的方式实现不定长数据的接受

首先打开串口并打开串口的收发DMA。

接下来全部编译一遍文件。

找到main.h文件,在对应位置插入回调函数函数声明:

/* USER CODE BEGIN EFP */
void My_UART_IDLECallback(UART_HandleTypeDef *huart);
/* USER CODE END EFP */

进入stm32f4xx_it.c文件,在串口中断函数里面插入空闲中断服务函数:

 /* USER CODE BEGIN USART1_IRQn 1 */
//判断是否是串口1
if(USART1 == huart1.Instance)                                   
{
    //判断是否是空闲中断
    if(RESET != __HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE))   
    {   
        //清除空闲中断标志(否则会一直不断进入中断)
        __HAL_UART_CLEAR_IDLEFLAG(&huart1);                     
        //调用中断回调函数
        My_UART_IDLECallback(&huart1);                         
     }
}
  /* USER CODE END USART1_IRQn 1 */

最后在main.c文件里面加入我们自己的函数:

/* USER CODE BEGIN PD */
#define BUFFER_SIZE 20
/* USER CODE END PD */

struct myuart{
    uint8_t* buffer_addr;//缓冲区首地址
    uint32_t date_size;//传输数据长度
}myuart_1;

//串口结构体初始化
void My_UART_IDLEIT_DMA_Init(uint8_t* Address)
{
    myuart_1.buffer_addr=Address;
}

//串口接收函数
void My_UART_IDLEIT_DMA_Receive(UART_HandleTypeDef *huart, uint8_t *pData)
{
    __HAL_UART_ENABLE_IT(huart, UART_IT_IDLE);//开启空闲中断
    HAL_UART_Receive_DMA(huart, pData, BUFFER_SIZE);//开启DMA接收函数
}

//串口发送函数
void My_UART_IDLEIT_DMA_Transmit(UART_HandleTypeDef *huart, uint8_t *pData)
{
    __HAL_UART_ENABLE_IT(huart, UART_IT_IDLE);//开启空闲中断
    HAL_UART_Transmit_DMA(huart, pData, BUFFER_SIZE);//开启DMA发送函数
}

//空闲中断回调函数
void My_UART_IDLECallback(UART_HandleTypeDef *huart)
{
    HAL_UART_DMAStop(huart);//停止DMA传输

    myuart_1.date_size = BUFFER_SIZE -  __HAL_DMA_GET_COUNTER(huart->hdmarx);//计算数据长度

    /*数据处理函数开始*/
    /*bla  bla ....*/
    /*数据处理函数结束*/
    memset(myuart_1.buffer_addr, 0, myuart_1.date_size);//重置缓冲区

    HAL_UART_Receive_DMA(huart, myuart_1.buffer_addr, BUFFER_SIZE);//开启DMA接受函数
    __HAL_UART_ENABLE_IT(huart, UART_IT_IDLE);//开启空闲中断
}
上一篇
下一篇