W806 串口 DMA 问题

发布于 2023-03-23 10: 37: 08

问题描述:

串口 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 的字节量, 现在卡在这里, 还请大佬们不吝赐教.

查看更多

关注者
0
被浏览
1. 6k
1 个回答
isme
isme 认证专家 2023-03-23
冰镇大西瓜

1. 你把代码编辑时, 像下面这样显示会正常些, 大家看起来会舒服些.
image. png
2. w806 sdk 的驱动, 串口暂时不支持 dma, 而且本身 6 路串口, 同一时间只能有 1 路用 dma 功能.

撰写答案

请登录后再发布答案, 点击登录

发布
问题

分享
好友

手机
浏览

扫码手机浏览