一、定义串口DMA缓存
#define UART2_MAX_LENGTH 255
uint8_t aU2DmaRxBuffer[UART2_MAX_LENGTH];
uint8_t aU2DmaTxBuffer[UART2_MAX_LENGTH]; // = "1234";
二、串口基本初始化
UartHandle[Uart2].Instance = USART2;
UartHandle[Uart2].Init.BaudRate = bute;
UartHandle[Uart2].Init.WordLength = mx_get_uart_databit(databit);
UartHandle[Uart2].Init.StopBits = UART_STOPBITS_1;
UartHandle[Uart2].Init.Parity = mx_get_uart_paritybit(parity);
UartHandle[Uart2].Init.Mode = UART_MODE_TX_RX;
UartHandle[Uart2].Init.HwFlowCtl = UART_HWCONTROL_NONE;
UartHandle[Uart2].Init.OverSampling = UART_OVERSAMPLING_16;
UartHandle[Uart2].Init.OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE;
UartHandle[Uart2].AdvancedInit.AdvFeatureInit = UART_ADVFEATURE_NO_INIT;
if (HAL_UART_Init(&UartHandle[Uart2]) != HAL_OK)
{
Error_Handler();
}
三、打开串口空闲中断
__HAL_UART_ENABLE_IT(&UartHandle[Uart2], UART_IT_IDLE);
四、DMA初始化
找到 void HAL_UART_MspInit(UART_HandleTypeDef *uartHandle)函数,里面实现如下所示:
__HAL_RCC_USART2_CLK_ENABLE();
#if UART2_DMA
__HAL_RCC_DMA1_CLK_ENABLE();
#endif
/**USART2 GPIO Configuration
PA2 ------> USART2_TX
PA3 ------> USART2_RX
*/
GPIO_InitStruct.Pin = GPIO_PIN_2 | GPIO_PIN_3;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF4_USART2;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
#if UART2_DMA
/*##-3- Configure the DMA ##################################################*/
/* Configure the DMA handler for Transmission process */
hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_tx.Instance = DMA1_Channel4;
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_4;
hdma_tx.State = HAL_DMA_STATE_READY;
if (HAL_DMA_Init(&hdma_tx) != HAL_OK)
{
Error_Handler();
}
/* Associate the initialized DMA handle to the UART handle */
__HAL_LINKDMA(uartHandle, hdmatx, hdma_tx);
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_4;
if (HAL_DMA_Init(&hdma_rx) != HAL_OK)
{
Error_Handler();
}
/* Associate the initialized DMA handle to the the UART handle */
__HAL_LINKDMA(uartHandle, hdmarx, hdma_rx);
/* DMA interrupt init */
HAL_NVIC_SetPriority(DMA1_Channel4_5_6_7_IRQn, 0, 1);
HAL_NVIC_EnableIRQ(DMA1_Channel4_5_6_7_IRQn);
#endif
/* Peripheral interrupt init */
HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART2_IRQn);
这里注意几个地方
GPIO_InitStruct.Alternate = GPIO_AF4_USART2;这句代码对应的配置可以在Drivers\STM32L0xx_HAL_Driver\Inc\stm32l0xx_hal_gpio_ex.h文件开头的注释里面查到。hdma_tx.Init.Request = DMA_REQUEST_4;这句代码对应的request表示通道,不能搞错,错了完全不能通信。
五、中断函数
#if UART2_DMA
if (USART2->ISR & (1 << UART_IDLE_IRQ)) // 串口空闲中断
{
ret = UART2_MAX_LENGTH - __HAL_DMA_GET_COUNTER(UartHandle[Uart2].hdmarx); // 接收到数据的长度
dbg_printhex("Uart2RecvBuf\r\n",aU2DmaRxBuffer,128);
if (ret > 0)
{
TypeFunc.StrCpy(Uart2RecvBuf, aU2DmaRxBuffer, ret);
Uart2RecvBufLength = ret;
uart_recv_timer[Uart2] = 5;
}
__HAL_UART_CLEAR_FLAG(&UartHandle[Uart2], UART_CLEAR_IDLEF);
// 处理DMA 数据
}
#else
注意:UART_CLEAR_IDLEF 不是UART_IT_IDLE;
如果这篇文章对您很有帮助,不妨
----- 本文结束 ❤ 感谢您的阅读 ----
上一篇
win nas搭建
下一篇
软件定时注册的设计
- 本文作者: Memory
- 本文链接: https://www.mzpkz.top/post/stm32-usart-dma/
- 版权声明: 本博客所有文章除特别声明外,转载请注明出处!