以串口3为例,初始化部分为STM32CubeMX生成代码
串口初始化
UART_HandleTypeDef huart3;
DMA_HandleTypeDef hdma_usart3_rx;
DMA_HandleTypeDef hdma_usart3_tx;
void MX_USART3_UART_Init ( void )
{ huart3. Instance = USART3 ; huart3. Init. BaudRate = 115200 ; huart3. Init. WordLength = UART_WORDLENGTH_8B ; huart3. Init. StopBits = UART_STOPBITS_1 ; huart3. Init. Parity = UART_PARITY_NONE ; huart3. Init. Mode = UART_MODE_TX_RX ; huart3. Init. HwFlowCtl = UART_HWCONTROL_NONE ; huart3. Init. OverSampling = UART_OVERSAMPLING_16 ; huart3. Init. OneBitSampling = UART_ONE_BIT_SAMPLE_DISABLE ; huart3. AdvancedInit. AdvFeatureInit = UART_ADVFEATURE_NO_INIT ; if ( HAL_UART_Init ( & huart3) != HAL_OK ) { Error_Handler ( ) ; }
} void HAL_UART_MspInit ( UART_HandleTypeDef* uartHandle )
{ GPIO_InitTypeDef GPIO_InitStruct = { 0 } ; RCC_PeriphCLKInitTypeDef PeriphClkInit = { 0 } ; if ( uartHandle- > Instance == USART3 ) { PeriphClkInit. PeriphClockSelection = RCC_PERIPHCLK_USART3 ; PeriphClkInit. Usart3ClockSelection = RCC_USART3CLKSOURCE_PCLK1 ; if ( HAL_RCCEx_PeriphCLKConfig ( & PeriphClkInit) != HAL_OK ) { Error_Handler ( ) ; } __HAL_RCC_USART3_CLK_ENABLE ( ) ; __HAL_RCC_GPIOC_CLK_ENABLE ( ) ; GPIO_InitStruct. Pin = GPIO_PIN_4 | GPIO_PIN_5 ; GPIO_InitStruct. Mode = GPIO_MODE_AF_PP ; GPIO_InitStruct. Pull = GPIO_NOPULL ; GPIO_InitStruct. Speed = GPIO_SPEED_FREQ_VERY_HIGH ; GPIO_InitStruct. Alternate = GPIO_AF7_USART3 ; HAL_GPIO_Init ( GPIOC , & GPIO_InitStruct) ; hdma_usart3_rx. Instance = DMA1_Channel3; hdma_usart3_rx. Init. Request = DMA_REQUEST_2 ; hdma_usart3_rx. Init. Direction = DMA_PERIPH_TO_MEMORY ; hdma_usart3_rx. Init. PeriphInc = DMA_PINC_DISABLE ; hdma_usart3_rx. Init. MemInc = DMA_MINC_ENABLE ; hdma_usart3_rx. Init. PeriphDataAlignment = DMA_PDATAALIGN_BYTE ; hdma_usart3_rx. Init. MemDataAlignment = DMA_MDATAALIGN_BYTE ; hdma_usart3_rx. Init. Mode = DMA_NORMAL ; hdma_usart3_rx. Init. Priority = DMA_PRIORITY_LOW ; if ( HAL_DMA_Init ( & hdma_usart3_rx) != HAL_OK ) { Error_Handler ( ) ; } __HAL_LINKDMA ( uartHandle, hdmarx, hdma_usart3_rx) ; hdma_usart3_tx. Instance = DMA1_Channel2; hdma_usart3_tx. Init. Request = DMA_REQUEST_2 ; hdma_usart3_tx. Init. Direction = DMA_MEMORY_TO_PERIPH ; hdma_usart3_tx. Init. PeriphInc = DMA_PINC_DISABLE ; hdma_usart3_tx. Init. MemInc = DMA_MINC_ENABLE ; hdma_usart3_tx. Init. PeriphDataAlignment = DMA_PDATAALIGN_BYTE ; hdma_usart3_tx. Init. MemDataAlignment = DMA_MDATAALIGN_BYTE ; hdma_usart3_tx. Init. Mode = DMA_NORMAL ; hdma_usart3_tx. Init. Priority = DMA_PRIORITY_LOW ; if ( HAL_DMA_Init ( & hdma_usart3_tx) != HAL_OK ) { Error_Handler ( ) ; } __HAL_LINKDMA ( uartHandle, hdmatx, hdma_usart3_tx) ; HAL_NVIC_SetPriority ( USART3_IRQn, 1 , 0 ) ; HAL_NVIC_EnableIRQ ( USART3_IRQn) ; }
} void HAL_UART_MspDeInit ( UART_HandleTypeDef* uartHandle )
{ if ( uartHandle- > Instance == USART3 ) { __HAL_RCC_USART3_CLK_DISABLE ( ) ; HAL_GPIO_DeInit ( GPIOC , GPIO_PIN_4 | GPIO_PIN_5 ) ; HAL_DMA_DeInit ( uartHandle- > hdmarx) ; HAL_DMA_DeInit ( uartHandle- > hdmatx) ; HAL_NVIC_DisableIRQ ( USART3_IRQn) ; }
}
DMA初始化
void MX_DMA_Init ( void )
{ __HAL_RCC_DMA1_CLK_ENABLE ( ) ; HAL_NVIC_SetPriority ( DMA1_Channel2_IRQn, 0 , 0 ) ; HAL_NVIC_EnableIRQ ( DMA1_Channel2_IRQn) ; HAL_NVIC_SetPriority ( DMA1_Channel3_IRQn, 0 , 0 ) ; HAL_NVIC_EnableIRQ ( DMA1_Channel3_IRQn) ;
}
中断服务函数
void USART3_IRQHandler ( void )
{ HAL_UART_IRQHandler ( & huart3) ;
}
应用部分,为自己编写代码
开机启用DMA接收
typedef struct
{ uint8_t RxBuffer[ USART_RX_MAX_LENGTH ] ; uint16_t Size; uint8_t FrameFg;
} WS_RxUsartInfoTypeDef; WS_RxUsartInfoTypeDef uart3Rx; void WS_USART_Rx_Tx_Init ( void )
{ HAL_UARTEx_ReceiveToIdle_DMA ( & huart3, uart3Rx. RxBuffer, sizeof ( uart3Rx. RxBuffer) - 1 ) ;
}
发送函数
HAL_StatusTypeDef HAL_UART_Transmit_DMA ( UART_HandleTypeDef * huart, const uint8_t * pData, uint16_t Size) ;
重写发送完成回调函数
void HAL_UART_TxCpltCallback ( UART_HandleTypeDef * huart )
{ UNUSED ( huart) ; if ( huart- > Instance == USART3 ) { }
}
重写接收完成回调函数
void HAL_UARTEx_RxEventCallback ( UART_HandleTypeDef * huart, uint16_t Size )
{
UNUSED ( huart) ; if ( huart- > Instance == USART3 ) { if ( huart- > RxEventType == HAL_UART_RXEVENT_IDLE ) { uart3Rx. FrameFg = 1 ; uart3Rx. Size = Size; HAL_UARTEx_ReceiveToIdle_DMA ( & huart3, uart3Rx. RxBuffer, sizeof ( uart3Rx. RxBuffer) - 1 ) ; } }
}