cancel
Showing results for 
Search instead for 
Did you mean: 

I sent a command with interrupts using HAL_UART_Transmit_IT to get 19 strings. But with interrupts turn on uart2 i am getting half of it not full of 19 strings.

cjaya.1
Associate II
 
5 REPLIES 5
cjaya.1
Associate II
void USARTx_IRQHandler(void)
{	
	uint8_t data;
 
	if(__HAL_UART_GET_IT_SOURCE(&huart2, UART_IT_RXNE) != RESET) 
          { 
		if ((&huart2.Instance->SR & UART_FLAG_RXNE) != RESET)           
		{
			if (&huart2.Init.Parity == UART_PARITY_NONE)
			{
				data = (uint8_t)(&huart2.Instance->DR & (uint8_t)0x00FF);
			}
			else
			{
				data = (uint8_t)(&huart2.Instance->DR & (uint8_t)0x007F);
			}
                        DataStore(data);
		  }   
	   }
 	HAL_UART_IRQHandlder(&huart2);
       HAL_UART_Receive_IT(&huart2, data, 1);
}

cjaya.1
Associate II

In the DataStore(data) function,

void DataStore(uint8_t data)
{
    if(data != '\n\n')
       {
        RxBuffer[i] = data;
        i++;
        }
 
    if(i > 380)
       i = 0;
}

Any suggestion about this?

gbm
Lead III

if(data != '\n\n')

This always yields true.

My STM32 stuff on github - compact USB device stack and more: https://github.com/gbm-ii/gbmUSBdevice
Bob S
Principal

Is that REALLY your code? Check your compiler warnings, and turn on warnings if you don't already have them (-Wall). Specifically, HAL_UART_Receive_IT() wants a POINTER to the location into which to store the data. You give the the VALUE of the local variable "data".

If you are going to use HAL, then use it as it is intended. Your code in USARTx_IRQHandler() duplicates some of what HAL_UART_IRQHandler() does. Create a HAL_UART_RxCpltCallback() function and put your code there (thought NOT the code you have above). You RX complete code should take the data from where ever your HAL_UART_Receive_IT() call told it to, into your RxBuffer[].

And finally, is you RxBuffer array really 381 bytes long? That is what you are testing for in DataStore(). Instead of a hard-coded constant, use:

if ( i >= sizeof(RxBuffer) ) {  // Notice the ">=", not ">"
   i = 0;
}

Or, use @Tilen MAJERLE​ 's code here:

https://github.com/MaJerle/stm32-usart-uart-dma-rx-tx

and get ride of that horrible "re-enable interrupt receive on every byte" code.

Karl Yamashita
Lead III

Your "data" variable needs to be declared outside of the function. Also when you get an interrupt, data already holds the char so there is no need to copy from the DR register

//declare global variable
uint8_t data[1];
 
// somewhere before main while loop you need to initiate the first interrupt
int main(void)
{
	void SystemClock_Config(void);
	static void MX_GPIO_Init(void);
	static void MX_USART2_UART_Init(void);
	...
 
	UART_Start_Receive_IT(&huart2, data, 1);
 
	while(1)
	{
 
	}
}
 
 
// HAL has a weak function that is empty. Just create a new function that overrides it.. 
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
	if(huart->Instance == huart2.Instance)
	{
		DataStore(data); // save char
		UART_Start_Receive_IT(&huart2, data, 1); // restart interrupt
	}
}

Tips and Tricks with TimerCallback https://www.youtube.com/@eebykarl
If you find my solution useful, please click the Accept as Solution so others see the solution.