I am trying to use UART with DMA,
before the DMA I tried polling method with while(HAL_UART_Transmit(&huart2, (uint8_t *)rs485TxBuffer, 17, 100) != HAL_OK);
function and I could communicate successfully,
When I using the
while(HAL_UART_Transmit_DMA(&huart2, (uint8_t *)rs485TxBuffer, 17)!= HAL_OK);
function, data not sending correctly, just first byte correct another bytes are wrong. Why this happened ? How can I solve this problem ?
This is my initilizing sequence:
MX_DMA_Init();
MX_GPIO_Init();
MX_USART1_UART_Init();
MX_USART2_UART_Init();
Below lines try to send data:
while(1U)
{
// Communication Test Block //
while(HAL_UART_Transmit_DMA(&huart2, (uint8_t *)rs485TxBuffer, 17)!= HAL_OK);
// while(HAL_UART_Transmit(&huart2, (uint8_t *)rs485TxBuffer, 17, 100) != HAL_OK);
}
This is the initilizing functions:
..
else if(huart->Instance==USART2)
{
/* USER CODE BEGIN USART2_MspInit 0 */
/* USER CODE END USART2_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_USART2_CLK_ENABLE();
__HAL_RCC_GPIOD_CLK_ENABLE();
/**USART2 GPIO Configuration
PD5 ------> USART2_TX
PD6 ------> USART2_RX
*/
GPIO_InitStruct.Pin = USART2_RS485_TX_Pin|USART2_RS485_RX_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF7_USART2;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* USART2 DMA Init */
/* USART2_RX Init */
hdma_usart2_rx.Instance = DMA1_Stream5;
hdma_usart2_rx.Init.Channel = DMA_CHANNEL_4;
hdma_usart2_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_usart2_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart2_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE;
hdma_usart2_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE;
hdma_usart2_rx.Init.Mode = DMA_NORMAL;
hdma_usart2_rx.Init.Priority = DMA_PRIORITY_MEDIUM;
hdma_usart2_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_usart2_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(huart,hdmarx,hdma_usart2_rx);
/* USART2_TX Init */
hdma_usart2_tx.Instance = DMA1_Stream6;
hdma_usart2_tx.Init.Channel = DMA_CHANNEL_4;
hdma_usart2_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_usart2_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_usart2_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_usart2_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_usart2_tx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_usart2_tx.Init.Mode = DMA_NORMAL;
hdma_usart2_tx.Init.Priority = DMA_PRIORITY_MEDIUM;
hdma_usart2_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE;
if (HAL_DMA_Init(&hdma_usart2_tx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(huart,hdmatx,hdma_usart2_tx);
/* USART2 interrupt Init */
HAL_NVIC_SetPriority(USART2_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART2_IRQn);
/* USER CODE BEGIN USART2_MspInit 1 */
/* USER CODE END USART2_MspInit 1 */
}
This is the interrupt function in stm32f4xx_it.c
void DMA1_Stream5_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Stream5_IRQn 0 */
/* USER CODE END DMA1_Stream5_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart2_rx);
/* USER CODE BEGIN DMA1_Stream5_IRQn 1 */
/* USER CODE END DMA1_Stream5_IRQn 1 */
}
/**
* @brief This function handles DMA1 stream6 global interrupt.
*/
void DMA1_Stream6_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Stream6_IRQn 0 */
/* USER CODE END DMA1_Stream6_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_usart2_tx);
/* USER CODE BEGIN DMA1_Stream6_IRQn 1 */
/* USER CODE END DMA1_Stream6_IRQn 1 */
}
/**
* @brief This function handles USART2 global interrupt.
*/
void USART2_IRQHandler(void)
{
/* USER CODE BEGIN USART2_IRQn 0 */
// SerialPrint("Hi");
/* USER CODE END USART2_IRQn 0 */
HAL_UART_IRQHandler(&huart2);
/* USER CODE BEGIN USART2_IRQn 1 */
/* USER CODE END USART2_IRQn 1 */
}
EDIT:
I tried these method but not worked for me.
while(1U)
{
// Communication Test Block //
HAL_UART_Transmit_DMA(&huart2, (uint8_t *)rs485TxBuffer, 17);
while(!dmaTransmitCompletedFlag);
dmaTransmitCompletedFlag = 0;
}
..
void HAL_UART_TxHalfCpltCallback(UART_HandleTypeDef *huart)
{
dmaTransmitCompletedFlag = 1;
}