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.7k
1 個回答
isme
isme 認證專家 2023-03-23
冰鎮大西瓜

1.你把代碼編輯時,像下面這樣顯示會正常些,大家看起來會舒服些。
image.png
2.w806 sdk的驅動,串口暫時不支持dma,而且本身6路串口,同一時間只能有1路用dma功能。

撰寫答案

請登錄後再發布答案,點擊登錄

發布
問題

分享
好友

手機
浏覽

掃碼手機浏覽