參考文章:1.?http://t.csdn.cn/FT6Mg
? ? ? ? ? ? ? ? ? 2.?http://t.csdn.cn/ejFIQ
今天用STM32F1的HAL庫開發(fā)遇到一個(gè)奇怪的問題,在主函數(shù)循環(huán)調(diào)用中用串口1的DMA請求,將內(nèi)存中的數(shù)據(jù)發(fā)送給串口,無論延遲Delay開了多大,始終只能發(fā)送一次DMA數(shù)據(jù)。后來在網(wǎng)上查閱大佬的資料終于有了思路。
廢話不多說,先上代碼:
在 stm32f1xx_hal_uart.c 文件中找到HAL_UART_Transmit_DMA()函數(shù)實(shí)現(xiàn),在解鎖操作__HAL_UNLOCK;后添加代碼:huart -> gState = HAL_UART_STATE_READY;? 編譯以后運(yùn)行完美解決。而且在低延遲的高速while循環(huán)中反復(fù)調(diào)用串口DMA請求,都可以運(yùn)行。
HAL_UART_Transmit_DMA()函數(shù)實(shí)現(xiàn)修改:(也就多加了一行代碼而已[doge])
HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef *huart, uint8_t *pData, uint16_t Size)
{
uint32_t *tmp;
/* Check that a Tx process is not already ongoing */
if (huart->gState == HAL_UART_STATE_READY)
{
if ((pData == NULL) || (Size == 0U))
{
return HAL_ERROR;
}
/* Process Locked */
__HAL_LOCK(huart);
huart->pTxBuffPtr = pData;
huart->TxXferSize = Size;
huart->TxXferCount = Size;
huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->gState = HAL_UART_STATE_BUSY_TX; //修改串口的工作狀態(tài)為Busy
/* Set the UART DMA transfer complete callback */
huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt;
/* Set the UART DMA Half transfer complete callback */
huart->hdmatx->XferHalfCpltCallback = UART_DMATxHalfCplt;
/* Set the DMA error callback */
huart->hdmatx->XferErrorCallback = UART_DMAError;
/* Set the DMA abort callback */
huart->hdmatx->XferAbortCallback = NULL;
/* Enable the UART transmit DMA channel */
tmp = (uint32_t *)&pData;
HAL_DMA_Start_IT(huart->hdmatx, *(uint32_t *)tmp, (uint32_t)&huart->Instance->DR, Size);
/* Clear the TC flag in the SR register by writing 0 to it */
__HAL_UART_CLEAR_FLAG(huart, UART_FLAG_TC);
/* Process Unlocked */
__HAL_UNLOCK(huart);
huart -> gState = HAL_UART_STATE_READY; //這一句官方好像給落下了???
/* Enable the DMA transfer for transmit request by setting the DMAT bit
in the UART CR3 register */
SET_BIT(huart->Instance->CR3, USART_CR3_DMAT);
return HAL_OK;
}
else
{
return HAL_BUSY;
}
}
簡要分析:每當(dāng)調(diào)用一次HAL_UART_Transmit_DMA()都會(huì)先進(jìn)行一次串口狀態(tài)的判斷:if (huart->gState == HAL_UART_STATE_READY) 如果串口處于READY狀態(tài),則開始本次的DMA傳輸,否則會(huì)返回一個(gè)BUSY狀態(tài):
else
? {
? ? return HAL_BUSY;
? }
當(dāng)?shù)谝淮握{(diào)用HAL_UART_Transmit_DMA()時(shí),串口處于READY狀態(tài),于是進(jìn)行DMA傳輸,注意,在DMA傳輸過程中,會(huì)將串口從READY狀態(tài)改為發(fā)送BUSY狀態(tài)(軟件修改):huart->gState = HAL_UART_STATE_BUSY_TX;但是在DMA完成本次傳輸工作以后,并沒有將串口從發(fā)送BUSY狀態(tài)改回READY狀態(tài),一開始我認(rèn)為可能硬件自動(dòng)修改該標(biāo)志,但是不確定,還沒有翻參考手冊,如果有知道的大佬煩請指教!因此這里我索性添加一句代碼軟件修改該狀態(tài):huart -> gState = HAL_UART_STATE_READY;文章來源:http://www.zghlxwxcb.cn/news/detail-536708.html
這樣就能保證每次調(diào)用完HAL_UART_Transmit_DMA()函數(shù)后,串口的狀態(tài)均為READY,為下一次的串口發(fā)送DMA請求做準(zhǔn)備。文章來源地址http://www.zghlxwxcb.cn/news/detail-536708.html
到了這里,關(guān)于通過修改HAL_UART_Transmit_DMA()函數(shù),解決串口發(fā)送DMA只能發(fā)送一次的問題的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!