L4_HAL库_串口_DMA

void USART1_IRQHandler(void)
{
  /* USER CODE BEGIN USART1_IRQn 0 */
    /* HAL库好像没有处理空闲中断的代码,需自己添加 */
    if(__HAL_UART_GET_FLAG(&UartHandle,UART_FLAG_IDLE))
    {
        UsartReceive_IDLE(&UartHandle);
    }
  /* USER CODE END USART1_IRQn 0 */
  HAL_UART_IRQHandler(&UartHandle);
  /* USER CODE BEGIN USART1_IRQn 1 */

  /* USER CODE END USART1_IRQn 1 */
}

 

查阅DATAsheet,发现修改发送DMA数据发送数寄存器前,需要先关闭DMA。

查到别人代码有在中断中用HAL_UART_DMAStop(huart)关闭中断,Debug后发现这个函数关闭RXDMA的同时关闭了TXDMA,导致串口的接收到数据后会关闭正在执行的发送DMA,会使串口不能同时进行收发数据,故改为 __HAL_DMA_DISABLE(huart->hdmarx); 关闭对应的接收DMA。

/* 串口接收空闲中断 */
void UsartReceive_IDLE(UART_HandleTypeDef *huart)  
{
    uint16_t i = 0;

    if((__HAL_UART_GET_FLAG(huart,UART_FLAG_IDLE) != RESET))  
    {
        if(huart->Instance == USART1)
        {
            __HAL_UART_CLEAR_IDLEFLAG(huart);
			
            i = RXBUFFERSIZE-hdma_rx.Instance->CNDTR;       //indicating the remaining bytes to be transmitted.

	    __HAL_DMA_DISABLE(huart->hdmarx);    //Once the channel is enabled, this register is read-only
            /* 此处处理数据,主要是拷贝和置位标志位 */
            if(usart1_rx_flag == 0)
            {
		memcpy(aTxBuffer,aRxBuffer,i);              // 字符串拷贝
                usart1_rx_flag = 1;     //接收完毕
            }
            /* 清空缓存,重新接收 */
            memset(aRxBuffer,0x00,RXBUFFERSIZE);    //把从a开始的80个字符全置为0			
	    hdma_rx.Instance->CNDTR=RXBUFFERSIZE;   //重装DMA数值		
			
	    __HAL_DMA_ENABLE(huart->hdmarx);
        }
    }
}  

 

串口DMA的底层配置

void HAL_UART_MspInit(UART_HandleTypeDef *huart)
{
	
  GPIO_InitTypeDef  GPIO_InitStruct;

  /*##-1- Enable peripherals and GPIO Clocks #################################*/
  /* Enable GPIO TX/RX clock */
  USARTx_TX_GPIO_CLK_ENABLE();
  USARTx_RX_GPIO_CLK_ENABLE();

  /* Enable USARTx clock */
  USARTx_CLK_ENABLE();

  /* Enable DMA clock */
  __HAL_RCC_DMA1_CLK_ENABLE();
	
  /*##-2- Configure peripheral GPIO ##########################################*/
  /* UART TX GPIO pin configuration  */
  GPIO_InitStruct.Pin       = USARTx_TX_PIN;
  GPIO_InitStruct.Mode      = GPIO_MODE_AF_PP;
  GPIO_InitStruct.Pull      = GPIO_PULLUP;
  GPIO_InitStruct.Speed     = GPIO_SPEED_FREQ_VERY_HIGH;
  GPIO_InitStruct.Alternate = USARTx_TX_AF;

  HAL_GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStruct);

  /* UART RX GPIO pin configuration  */
  GPIO_InitStruct.Pin = USARTx_RX_PIN;
  GPIO_InitStruct.Alternate = USARTx_RX_AF;

  HAL_GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStruct);
  
  /*##-3- Configure the DMA ##################################################*/
  /* Configure the DMA handler for Transmission process */
  hdma_tx.Instance                 = DMA1_Channel4;
  hdma_tx.Init.Direction           = DMA_MEMORY_TO_PERIPH;
  hdma_tx.Init.PeriphInc           = DMA_PINC_DISABLE;
  hdma_tx.Init.MemInc              = DMA_MINC_ENABLE;
  hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
  hdma_tx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
  hdma_tx.Init.Mode                = DMA_NORMAL;
  hdma_tx.Init.Priority            = DMA_PRIORITY_LOW;
  hdma_tx.Init.Request             = DMA_REQUEST_2;

  HAL_DMA_Init(&hdma_tx);

  /* Associate the initialized DMA handle to the UART handle */
  __HAL_LINKDMA(huart, hdmatx, hdma_tx);

  /* Configure the DMA handler for reception process */
  hdma_rx.Instance                 = DMA1_Channel5;
  hdma_rx.Init.Direction           = DMA_PERIPH_TO_MEMORY;
  hdma_rx.Init.PeriphInc           = DMA_PINC_DISABLE;
  hdma_rx.Init.MemInc              = DMA_MINC_ENABLE;
  hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
  hdma_rx.Init.MemDataAlignment    = DMA_MDATAALIGN_BYTE;
  hdma_rx.Init.Mode                = DMA_NORMAL;
  hdma_rx.Init.Priority            = DMA_PRIORITY_HIGH;
  hdma_rx.Init.Request             = DMA_REQUEST_2;

  HAL_DMA_Init(&hdma_rx);

  /* Associate the initialized DMA handle to the the UART handle */
  __HAL_LINKDMA(huart, hdmarx, hdma_rx);

  /*##-4- Configure the NVIC for DMA #########################################*/
  /* NVIC configuration for DMA transfer complete interrupt (USARTx_TX) */
  HAL_NVIC_SetPriority(DMA1_Channel4_IRQn, 1, 2);
  HAL_NVIC_EnableIRQ(DMA1_Channel4_IRQn);

  /* NVIC configuration for DMA transfer complete interrupt (USARTx_RX) */
  HAL_NVIC_SetPriority(DMA1_Channel5_IRQn, 1, 3);
  HAL_NVIC_EnableIRQ(DMA1_Channel5_IRQn);

  /* NVIC for USART, to catch the TX complete */
  HAL_NVIC_SetPriority(USART1_IRQn, 1, 4);
  HAL_NVIC_EnableIRQ(USART1_IRQn);
  
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值