问题描述:
串口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的字节量,现在卡在这里,还请大佬们不吝赐教。
非常感谢!