STM32F205 & DMA for UART
- March 14, 2017
- 3 replies
- 1512 views
Hi Everybody,
I'm using a STM32f205RG on a personnal electronic board. I would like to communicate with an external equipment using modbus RTU on RS485 link. So, I'm trying to implement USART 1 with DMA.
For the moment, I have set everything (DMA, UART...). My board is the slave. So, I can see frames from the master (read holding registers). These frame have only 8 bytes.
So, at the first frame, the 8 bytes are located in my array from 0 to 7. When I receive the second frame, this one is located from 8 to 15.
So when I calculate the size of my frame, I found 16 instead of 8, and then my checksum is wrong, and the frame is not validated.
So, I'm looking for a solution to 'reset' this array.
Please find my code :
--------------------INITIALIZATION---------------------------
/* USER CODE END USART1_MspInit 0 */
/* Peripheral clock enable */ __HAL_RCC_USART1_CLK_ENABLE(); /**USART1 GPIO Configuration PB6 ------> USART1_TX PB7 ------> USART1_RX */ GPIO_InitStruct.Pin = GPIO_PIN_6|GPIO_PIN_7; 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_USART1; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);/* Peripheral DMA init*/
hdma_usart1_rx.Instance = DMA2_Stream5; hdma_usart1_rx.Init.Channel = DMA_CHANNEL_4; hdma_usart1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY; hdma_usart1_rx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_usart1_rx.Init.MemInc = DMA_MINC_ENABLE; hdma_usart1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; hdma_usart1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; hdma_usart1_rx.Init.Mode = DMA_NORMAL; hdma_usart1_rx.Init.Priority = DMA_PRIORITY_LOW; hdma_usart1_rx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; if (HAL_DMA_Init(&hdma_usart1_rx) != HAL_OK) { Error_Handler(); }__HAL_LINKDMA(huart,hdmarx,hdma_usart1_rx);
hdma_usart1_tx.Instance = DMA2_Stream7;
hdma_usart1_tx.Init.Channel = DMA_CHANNEL_4; hdma_usart1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH; hdma_usart1_tx.Init.PeriphInc = DMA_PINC_DISABLE; hdma_usart1_tx.Init.MemInc = DMA_MINC_ENABLE; hdma_usart1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_BYTE; hdma_usart1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_BYTE; hdma_usart1_tx.Init.Mode = DMA_NORMAL; hdma_usart1_tx.Init.Priority = DMA_PRIORITY_LOW; //hdma_usart1_tx.Init.FIFOMode = DMA_FIFOMODE_DISABLE; if (HAL_DMA_Init(&hdma_usart1_tx) != HAL_OK) { Error_Handler(); }__HAL_LINKDMA(huart,hdmatx,hdma_usart1_tx);
HAL_NVIC_SetPriority(USART1_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(USART1_IRQn);-----------------------------IT--------------------------------------------
/**
* @brief This function handles DMA2 Stream7 global interrupt.*/void DMA2_Stream7_IRQHandler(void){ HAL_DMA_IRQHandler(&hdma_usart1_tx); if((HAL_DMA_GetState(&hdma_usart1_tx) == HAL_DMA_STATE_READY) || (HAL_DMA_GetState(&hdma_usart1_tx) == HAL_DMA_STATE_ERROR)) { Modbus_IT_Transmit(&modbusNET1); }}/**
* @brief This function handles USART6 global interrupt.*/void USART1_IRQHandler(void){ HAL_UART_IRQHandler(&huart1); if((__HAL_UART_GET_FLAG(&huart1, UART_FLAG_IDLE) != RESET) && (__HAL_UART_GET_IT_SOURCE(&huart1, UART_IT_IDLE) != RESET)) { __HAL_UART_CLEAR_IDLEFLAG(&huart1); __HAL_UART_DISABLE_IT(&huart1, UART_IT_IDLE); Modbus_IT_Receive_Data(&modbusNET1); }}If you have any idea, I would be very happy.
Regards,
Fabrice Péden
