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