I got a problem when using STM32f427 UART with DMA(using stm cube HAL library).
I would like make a console echo function, so I reply received data immediately in uart idle interrupt handler function.
But sometimes, the highest bit of received data will be 1, when I input any key in keyboard. such as following
0x31 -> 0xB1
0x32 -> 0xB2
0x40 -> 0xC0
Does someone have any idea? the code segment as following.
Thank you very much.
My uart configuration as following
uart_handler.Instance = USARTx;
uart_handler.Init.BaudRate = baudrate;
uart_handler.Init.WordLength = UART_WORDLENGTH_8B;
uart_handler.Init.StopBits = UART_STOPBITS_1;
uart_handler.Init.Parity = UART_PARITY_NONE;
uart_handler.Init.HwFlowCtl = UART_HWCONTROL_NONE;
uart_handler.Init.Mode = UART_MODE_TX_RX;
uart_handler.Init.OverSampling = UART_OVERSAMPLING_8;
My PIN and DMA channels configuration as following
GPIO_InitStruct.Pin = USARTx_TX_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_HIGH;
GPIO_InitStruct.Alternate = USARTx_TX_AF;
HAL_GPIO_Init(USARTx_TX_GPIO_PORT, &GPIO_InitStruct);
GPIO_InitStruct.Pin = USARTx_RX_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Alternate = USARTx_RX_AF;
HAL_GPIO_Init(USARTx_RX_GPIO_PORT, &GPIO_InitStruct);
hdma_tx.Instance = USARTx_TX_DMA_STREAM;
hdma_tx.Init.Channel = USARTx_TX_DMA_CHANNEL;
hdma_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_tx.Init.Mode = DMA_NORMAL;
hdma_tx.Init.Priority = DMA_PRIORITY_LOW;
hdma_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
hdma_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_tx.Init.MemBurst = DMA_MBURST_INC16;
hdma_tx.Init.PeriphBurst = DMA_MBURST_INC16;
HAL_DMA_Init(&hdma_tx);
/* Associate the initialized DMA handle to the UART handle */
__HAL_LINKDMA(huart, hdmatx, hdma_tx);
/* Configure the DMA handler for reception process */
hdma_rx.Instance = USARTx_RX_DMA_STREAM;
hdma_rx.Init.Channel = USARTx_RX_DMA_CHANNEL;
hdma_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_rx.Init.Mode = DMA_NORMAL;
hdma_rx.Init.Priority = DMA_PRIORITY_HIGH;
hdma_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
hdma_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_rx.Init.MemBurst = DMA_MBURST_INC16;
hdma_rx.Init.PeriphBurst = DMA_MBURST_INC16;
And use uart idle interrupt to receive data.
uint32_t temp;
if((__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) != RESET))
{
__HAL_UART_CLEAR_IDLEFLAG(huart);
HAL_UART_DMAStop(&uart_handler);
temp = uart_handler.hdmarx->Instance->NDTR;
g_usart_info.rx_len = USART_DMA_RECV_LEN - temp;
g_usart_info.receive_flag = 1;
g_usart_info.usart_dma_tx_buff = g_usart_info.usart_dma_rx_buff[0] ;
memset(g_usart_info.usart_dma_rx_buff, 0,
sizeof(g_usart_info.usart_dma_rx_buff));
__HAL_UART_CLEAR_FLAG(&uart_handler, UART_FLAG_RXNE);
g_usart_info.usart_dma_rx_buff[0] = 0;
HAL_UART_Receive_DMA(&uart_handler, g_usart_info.usart_dma_rx_buff,
USART_DMA_RECV_LEN);
}
Thank you.
I traced the function of UART_Receive_IT and added debug code. and insert break point for int a = *(huart->pRxBuffPtr - 1);
I found huart->Instance->DR is 0x31 but int a is 0xB1.
I tried to disable other interrupt but it still cannot be solved.
if(huart->Init.Parity == UART_PARITY_NONE)
{
*huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x00FF);
if(*(huart->pRxBuffPtr - 1) != 0x31)
{
int a = *(huart->pRxBuffPtr - 1);
a = a;
}
}
else
{
*huart->pRxBuffPtr++ = (uint8_t)(huart->Instance->DR & (uint8_t)0x007F);
}
========================================================================
I found the problem point
RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 /*| RCC_CLOCKTYPE_PCLK2*/);
If I comment RCC_CLOCKTYPE_PCLK2
, this problem could be solved.
But I don't know why, it is official sample code. I think it should be right.