STM32L1XX使用HAL_UART_Transmit_DMA發(fā)送串口數(shù)據(jù)
使用STM32CubeMX生成初始化代碼。
問題:
HAL_UART_Transmit_DMA函數(shù)只能調(diào)用一次,第二次就返回狀態(tài)HAL_UART_STATE_BUSY 0x02。
原因:
stm32l1xx_hal_uart.c開頭有描述
(##) DMA Configuration if you need to use DMA process (HAL_UART_Transmit_DMA()
and HAL_UART_Receive_DMA() APIs):
(+++) Declare a DMA handle structure for the Tx/Rx channel.
(+++) Enable the DMAx interface clock.
(+++) Configure the declared DMA handle structure with the required
Tx/Rx parameters.
(+++) Configure the DMA Tx/Rx channel.
(+++) Associate the initialized DMA handle to the UART DMA Tx/Rx handle.
(+++) Configure the priority and enable the NVIC for the transfer complete
interrupt on the DMA Tx/Rx channel.
(+++) Configure the USARTx interrupt priority and enable the NVIC USART IRQ handle
(used for last byte sending completion detection in DMA non circular mode)
配置USARTx中斷優(yōu)先級(jí),啟用NVIC USART中斷句柄(使用DMA非循環(huán)模式時(shí),用來檢測(cè)最后一個(gè)字節(jié)發(fā)送完畢)
默認(rèn) USART1的全局中斷未Checked。
或者:
在發(fā)送結(jié)束的回調(diào)函數(shù)中,恢復(fù)uart的Ready狀態(tài)。
void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart)
{
//回調(diào)函數(shù)
huart->State=HAL_UART_STATE_READY;
}
下面附的是mbed-os的代碼,它的UART_DMATransmitCplt函數(shù)直接復(fù)位Uart的狀態(tài)了。
/**
*@briefDMAUARTtransmitprocesscompletecallback
*@paramhdma:DMAhandle
*@retvalNone
*/
01523staticvoidUART_DMATransmitCplt(DMA_HandleTypeDef*hdma)
{
UART_HandleTypeDef*huart=(UART_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
huart->TxXferCount=0;
/*DisabletheDMAtransferfortransmitrequestbysettingtheDMATbit
intheUARTCR3register*/
huart->Instance->CR3&=(uint32_t)~((uint32_t)USART_CR3_DMAT);
/*WaitforUARTTCFlag*/
if(UART_WaitOnFlagUntilTimeout(huart,UART_FLAG_TC,RESET,HAL_UART_TXDMA_TIMEOUTVALUE)!=HAL_OK)
{
/*TimeoutOccured*/
huart->State=HAL_UART_STATE_TIMEOUT;
HAL_UART_ErrorCallback(huart);
}
else
{
/*NoTimeout*/
/*Checkifareceiveprocessisongoingornot*/
if(huart->State==HAL_UART_STATE_BUSY_TX_RX)
{
huart->State=HAL_UART_STATE_BUSY_RX;
}
else
{
huart->State=HAL_UART_STATE_READY;
}
HAL_UART_TxCpltCallback(huart);
}
}