UART发送实验,DMA方式;
1> 初始化
/* USART1 init function */
void bsp_uart1_init(void)
{
/* UART1 configured as follow:
- Word Length = 8 Bits
- Stop Bit = One Stop bit
- Parity = None
- BaudRate = 115200 baud
- Hardware flow control disabled (RTS and CTS signals) */
handle_uart1.Instance = USART1;
handle_uart1.Init.BaudRate = 115200;
handle_uart1.Init.WordLength = UART_WORDLENGTH_8B;
handle_uart1.Init.StopBits = UART_STOPBITS_1;
handle_uart1.Init.Parity = UART_PARITY_NONE;
handle_uart1.Init.Mode = UART_MODE_TX_RX;
handle_uart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
handle_uart1.Init.OverSampling = UART_OVERSAMPLING_16;
HAL_UART_Init(&handle_uart1);
}
void HAL_UART_MspInit(UART_HandleTypeDef* uartHandle)
{
static DMA_HandleTypeDef hdma_tx;
GPIO_InitTypeDef GPIO_InitStruct = {0};
/* Step 1> USART1 clock enable */
__HAL_RCC_USART1_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
__HAL_RCC_DMA2_CLK_ENABLE(); // DMA2
/* Step 2> USART1 GPIO Configuration */
GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7; // PB6-->TX, PB7--->RX
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_USART1;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* Step 3> Configure the DMA stream */
hdma_tx.Instance = DMA2_Stream7;
hdma_tx.Init.Channel = DMA_CHANNEL_4;
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_HIGH;
hdma_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
HAL_DMA_Init(&hdma_tx);
/* Step 4> Associate the DMA handle to the UART handle */
__HAL_LINKDMA(uartHandle,hdmatx,hdma_tx);
/* Step 5> interrupt Init */
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0); // UART1
HAL_NVIC_EnableIRQ(USART1_IRQn);
HAL_NVIC_SetPriority(DMA2_Stream7_IRQn, 0, 0); // DMA2
HAL_NVIC_EnableIRQ(DMA2_Stream7_IRQn);
}
2> 发送
uint8_t tx_buf[24] = "Hello World!";
HAL_UART_Transmit_DMA(&handle_uart1, tx_buf, 12);
3> 回调函数
/* 分析传输完成回调函数 */
HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
/* Set the UART DMA transfer complete callback */
huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt;
}
//----------------------------------------------------------------------------//
static void UART_DMATransmitCplt(DMA_HandleTypeDef *hdma)
{
#if (USE_HAL_UART_REGISTER_CALLBACKS == 1) // stm32f4xx_hal_conf.h中,还不清楚
/*Call registered Tx complete callback*/
huart->TxCpltCallback(huart);
#else
/*Call legacy weak Tx complete callback*/
HAL_UART_TxCpltCallback(huart);
#endif /* USE_HAL_UART_REGISTER_CALLBACKS */
}
//-------------------------------最终调用--------------------------------------//
__weak void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
/* Prevent unused argument(s) compilation warning */
UNUSED(huart);
/* NOTE: This function should not be modified, when the callback is needed,
the HAL_UART_TxCpltCallback could be implemented in the user file
*/
}
4> 中断回调函数
初始化中使能了2个中断, DMA方式下,这2个中断咋用?
4.1> USART1_IRQHandler
4.2> DMA2_Stream7_IRQHandler
/* 以传输完成中断为例 */
void DMA2_Stream7_IRQHandler(void)
{
HAL_DMA_IRQHandler(handle_uart1.hdmatx);
}
void HAL_DMA_IRQHandler(DMA_HandleTypeDef *hdma)
{
hdma->XferCpltCallback(hdma); // 回调到XferCpltCallback
}