cancel
Showing results for 
Search instead for 
Did you mean: 

UART interrupt data loss

KMale.1
Associate II

I used USART interrupt for RS485 encoder communication. I send 8 bit data and encoder reply with a 16 bit data. The first 8 bits out of 16 bits are received correctly. But second 8 bits didn't get correctly. I observed receiving data using oscilloscope. By comparing received data and oscilloscope signal, I found that start bit of the second byte always missed. Therefor RDR register take the first 0 bit of the second byte as the start bit.

eg: first byte(0,1,1,0,0,0,0,1,1,1) second byte(0,1,1,0,0,0,1,0,1,1)

Bolded bits are start and stop bits. In second byte, underlined bit is taken as start bit.

Here is my code.

 HAL_UART_IRQHandler(&huart2);

 /* USER CODE BEGIN USART2_IRQn 1 */

 UART_HandleTypeDef *huartx =&huart2;

  uint32_t isr  = READ_REG(huartx->Instance->ISR);

  uint32_t cr1   = READ_REG(huartx->Instance->CR1);

  if (__HAL_UART_GET_IT(&huart2, UART_IT_RXNE)==SET){

   USART2->ISR;

   RX[count] = (USART2->RDR);

   count++;

   if(count==2){

   __HAL_UART_ENABLE_IT(&huart2, UART_IT_TXE);

   count=0;

   }

  }

  if(HAL_RS485Ex_Init(&huart2, UART_DE_POLARITY_HIGH, 1/16,1/16)==HAL_OK){

   if (((isr & USART_ISR_TXE) != RESET) && ((cr1 & USART_CR1_TXEIE) != RESET)){

   HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4, 1); //DE ON

   USART2->ISR;

   USART2->TDR = TX[0];

   __HAL_UART_ENABLE_IT(&huart2, UART_IT_TC);

   __HAL_UART_DISABLE_IT(&huart2, UART_IT_TXE);

   i=1;

   }

  }

  if (((isr & USART_ISR_TC) != RESET) && (i==1)){

    HAL_GPIO_WritePin(GPIOD, GPIO_PIN_4, 0); //DE OFF

    __HAL_UART_DISABLE_IT(&huart2, UART_IT_TC);

    __HAL_UART_CLEAR_FLAG(&huart2, UART_FLAG_TC);

    i=0;

    }

 /* USER CODE END USART2_IRQn 1 */

Could anyone please help me to solve this issue

Thank you.

6 REPLIES 6
KnarfB
Principal III

The other day I implemented RS485 using DMA like

        HAL_UART_Receive_DMA( &huart1, (uint8_t*)&absa_response, sizeof(absa_response) );
	// send request
	HAL_GPIO_WritePin( re_port, re_pin, GPIO_PIN_SET ); // hi inactive
	HAL_GPIO_WritePin( de_port, de_pin, GPIO_PIN_SET ); // hi active
	static const uint8_t request = 0b00000010; // data readout absa
	HAL_UART_Transmit( &huart1, (uint8_t*)&request, 1, 0 ); // no timeout, this makes function return faster
	HAL_GPIO_WritePin( de_port,de_pin, GPIO_PIN_RESET );
	HAL_GPIO_WritePin( re_port, re_pin, GPIO_PIN_RESET ); // lo active

and processed the response in HAL_UART_RxCpltCallback.

Works as a charme with 2500000 baud on a F0 device @ 48 MHz.

Which STM32? What is the primary clock?

Sounds like baudrate mismatch. Verify that the incoming data baudrate matches the expected baudrate, and verify your STM32's clock.

JW

Thank you for the reply. I'll try this.

I'm using STM32 F767zi. My SYSCLK is 180MHz and USART2 clk is 45MHz. Encoder baudrate is 38400bps and I set USART2 baudrate equals to that.

I mean, what's the source of clock, HSI or any other internal RC oscillator - which are imprecise and drift significantly with temperature - or crystal oscillator (HSE)?

And by verification, I mean measuring using oscilloscope or logic analyzer.

JW

I used HSE crystal oscillator(25MHz). I didn't verify the baud rate using oscilloscope and I'll do it.