問題描述:
串口DMA,我只初始化一個DMA的0通道給COM0做發送,數據輸出是正常的
如果再初始化任何第二個DMA通道給其他串口,COM0輸出的數據就只有一個FIFO的數據量
並且從DMA0通道的傳輸字節數寄存器讀出的和我要傳輸的字節數相同,實際只輸出了32字節
看芯片手冊描述,DMA八個通道是“互不幹涉,可以同時運行”;
或許是我配置上有什麼不對;現將我的配置代碼貼出,希望官方大佬能給解惑。
我的配置代碼是基於官方0.6.0庫寫的,而DMA的配置代碼是仿SPI的DMA例程寫的。
串口初始化:
void UART0_Init(uint32_t baudr)
{
huart0.Instance = UART0;
huart0.Init.BaudRate = baudr;
huart0.Init.WordLength = UART_WORDLENGTH_8B;
huart0.Init.StopBits = UART_STOPBITS_1;
huart0.Init.Parity = UART_PARITY_NONE;
huart0.Init.Mode = UART_MODE_TX_RX;
huart0.Init.HwFlowCtl = UART_HWCONTROL_NONE;
if(HAL_UART_Init(&huart0) != HAL_OK)
{
Error_Handler(0xC0);
}
__HAL_UART_DISABLE_RTOE(huart0); //關閉接收超時使能,使用軟件自定義超時
HAL_UART_Receive_IT(&huart0, Uart0_RecBuf, UART0_BUFF_SIZE);
Uart0_DMA_TxConfig();
}
void UART3_Init(uint32_t baudr)
{
huart3.Instance = UART3;
huart3.Init.BaudRate = baudr;
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;
if(HAL_UART_Init(&huart3) != HAL_OK)
{
Error_Handler(0xC3);
}
__HAL_UART_DISABLE_RTOE(huart3); //關閉接收超時使能,使用軟件自定義超時
HAL_UART_Receive_IT(&huart3, Uart3_RecBuf, UART3_BUFF_SIZE);
// Uart3_DMA_TxConfig();
}
DMA初始化配置:
static void Uart0_DMA_TxConfig(void)
{
__HAL_RCC_DMA_CLK_ENABLE();
hdma_uart0_tx.Instance = DMA_Channel0;
hdma_uart0_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_uart0_tx.Init.DestInc = DMA_DINC_DISABLE;
hdma_uart0_tx.Init.SrcInc = DMA_SINC_ENABLE;
hdma_uart0_tx.Init.DataAlignment = DMA_DATAALIGN_BYTE;
hdma_uart0_tx.Init.Mode = DMA_MODE_NORMAL_SINGLE;
hdma_uart0_tx.Init.RequestSourceSel = DMA_REQUEST_SOURCE_UART_TX;
hdma_uart0_tx.Init.RequestUartSel = DMA_UART_CHANNEL_SEL_UART0;
__HAL_LINKDMA(huart0, hdmatx, hdma_uart0_tx);
__HAL_UART_ENABLE_DMA(huart0, UART_DMAC_TDE); //打開DMA發送使能
HAL_NVIC_SetPriority(DMA_Channel0_IRQn, 0);
HAL_NVIC_EnableIRQ(DMA_Channel0_IRQn);
if (HAL_DMA_Init(&hdma_uart0_tx) != HAL_OK)
{
Error_Handler(0xD0);
}
}
static void Uart3_DMA_TxConfig(void)
{
__HAL_RCC_DMA_CLK_ENABLE();
hdma_uart3_tx.Instance = DMA_Channel3;
hdma_uart3_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_uart3_tx.Init.DestInc = DMA_DINC_DISABLE;
hdma_uart3_tx.Init.SrcInc = DMA_SINC_ENABLE;
hdma_uart3_tx.Init.DataAlignment = DMA_DATAALIGN_BYTE;
hdma_uart3_tx.Init.Mode = DMA_MODE_NORMAL_SINGLE;
hdma_uart3_tx.Init.RequestSourceSel = DMA_REQUEST_SOURCE_UART_TX;
hdma_uart3_tx.Init.RequestUartSel = DMA_UART_CHANNEL_SEL_UART3;
__HAL_LINKDMA(huart3, hdmatx, hdma_uart3_tx);
__HAL_UART_ENABLE_DMA(huart3, UART_DMAC_TDE); //打開DMA發送使能
HAL_NVIC_SetPriority(DMA_Channel3_IRQn, 0);
HAL_NVIC_EnableIRQ(DMA_Channel3_IRQn);
if (HAL_DMA_Init(&hdma_uart3_tx) != HAL_OK)
{
Error_Handler(0xD3);
}
}
在wm_uart.c中,添加了串口DMA發送函數
HAL_StatusTypeDef HAL_UART_Transmit_DMA(UART_HandleTypeDef huart, uint8_t pData, uint32_t Size)
{
HAL_StatusTypeDef errorcode = HAL_OK;
uint32_t len = 0;
assert_param(IS_UART_DMA_HANDLE(huart->hdmatx));
if (huart->gState != HAL_UART_STATE_READY)
{
errorcode = HAL_BUSY;
goto error;
}
if ((pData == NULL) || (Size == 0U))
{
errorcode = HAL_ERROR;
goto error;
}
__HAL_LOCK(huart);
huart->gState = HAL_UART_STATE_BUSY_TX;
huart->ErrorCode = HAL_UART_ERROR_NONE;
huart->pTxBuffPtr = (uint8_t *)pData;
huart->TxXferSize = Size;
huart->TxXferCount = Size;
// huart->hdmatx->XferHalfCpltCallback = UART_DMAHalfTransmitCplt;
// huart->hdmatx->XferCpltCallback = UART_DMATransmitCplt;
// huart->hdmatx->XferAbortCallback = NULL;
len = (huart->TxXferCount > BLOCK_SIZE) ? BLOCK_SIZE : huart->TxXferCount;
huart->TxXferCount -= len;
__HAL_UART_CLEAR_FLAG(huart, UART_TX_INT_FLAG);
if (HAL_OK != HAL_DMA_Start_IT(huart->hdmatx,
(uint32_t)huart->pTxBuffPtr,
(uint32_t)&huart->Instance->TDW,
len))
{
SET_BIT(huart->ErrorCode, HAL_UART_ERROR_DMA);
errorcode = HAL_ERROR;
huart->gState = HAL_UART_STATE_READY;
goto error;
}
__HAL_UART_ENABLE_IT(huart, UART_INTS_TEMPT);
error:
__HAL_UNLOCK(huart);
return errorcode;
}
wm_uart.h文件中對串口的結構體定義做了一些更改
typedef struct __UART_HandleTypeDef
{
USART_TypeDef *Instance; /*!< UART registers base address */
UART_InitTypeDef Init; /*!< UART communication parameters */
uint8_t *pTxBuffPtr; /*!< Pointer to UART Tx transfer Buffer */
uint16_t TxXferSize; /*!< UART Tx Transfer size */
__IO uint16_t TxXferCount; /*!< UART Tx Transfer Counter */
uint8_t *pRxBuffPtr; /*!< Pointer to UART Rx transfer Buffer */
uint16_t RxXferSize; /*!< UART Rx Transfer size */
__IO uint16_t RxXferCount; /*!< UART Rx Transfer Counter */
HAL_LockTypeDef Lock; /*!< Locking object */
__IO uint8_t RxTimeCnt; /*!< 接收超時計數 */
__IO uint8_t RxTimeOutFlag; /*!< FIFO接收超時標識 */
DMA_HandleTypeDef *hdmatx; /*!< UART Tx DMA Handle parameters */
DMA_HandleTypeDef *hdmarx; /*!< UART Rx DMA Handle parameters */
__IO HAL_UART_StateTypeDef gState; /*!< UART state information related to global Handle management
and also related to Tx operations.
This parameter can be a value of @ref HAL_UART_StateTypeDef */
__IO HAL_UART_StateTypeDef RxState; /*!< UART state information related to Rx operations.
This parameter can be a value of @ref HAL_UART_StateTypeDef */
__IO uint32_t ErrorCode; /*!< UART Error code */
}UART_HandleTypeDef;
現在串口3初始化中Uart3_DMA_TxConfig();是被注銷掉的,如果打的話,COM0的輸出就只能輸出一個FIFO的字節量,現在卡在這裡,還請大佬們不吝賜教。
非常感謝!