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
被浏览
2.8k
1 个回答
isme
isme 认证专家 2023-03-23
冰镇大西瓜

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

撰写答案

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

发布
问题

分享
好友

手机
浏览

扫码手机浏览