Skip to main content
Associate II
June 26, 2024
Solved

Problem with UART interrupt

  • June 26, 2024
  • 7 replies
  • 2955 views

Hi,

I have two MCU communicating with each other via RS485. It's a very simple code one MCU send a data to other and the other is trying to receive this.

 

With MCU2 code everything is fine. It sends data like it should be.

Problem is with MCU1 code. When I delete #65 line in code (that one with HAL_UART_Transmit...) it works great. It receive data from MCU2 and starts engine and horn. But when I add this line it stop working. I dont understand why this is happening.

When the MCU2 works as a receiver everything is ok, but when I try to send something from it suddenly the whole uart stops working

 

MCU1 code:

/* USER CODE BEGIN 0 */


uint8_t buffer[2];
uint8_t ZERO[2]={0x00,0x00};
uint8_t AA[2]={0xAA,0xAA};
uint8_t BB[2]={0xBB,0xBB};

void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{

if(buffer[0]==0xCC && buffer[1]==0xCC)
{
	Engine(ON);
}

if(buffer[0]==0xDD && buffer[1]==0xDD)
{
	Horn(ON);
}


HAL_UART_Receive_IT(&huart2, buffer, 2);
}



/* USER CODE END 0 */

/**
 * @brief The application entry point.
 * @retval int
 */
int main(void)
{
 /* USER CODE BEGIN 1 */


 /* USER CODE END 1 */

 /* MCU Configuration--------------------------------------------------------*/

 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 HAL_Init();

 /* USER CODE BEGIN Init */

 /* USER CODE END Init */

 /* Configure the system clock */
 SystemClock_Config();

 /* USER CODE BEGIN SysInit */

 /* USER CODE END SysInit */

 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 //MX_I2C1_Init();
 MX_USART2_UART_Init();
 /* USER CODE BEGIN 2 */


 transceiver(WRITE);
 HAL_UART_Transmit(&huart2, ZERO, 2, 10); 
 transceiver(READ);
 HAL_UART_Receive_IT(&huart2, buffer, 2);




 /* USER CODE END 2 */

 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {



 /* USER CODE END WHILE */

 /* USER CODE BEGIN 3 */
 }
 /* USER CODE END 3 */
}

 

MCU2 code:

/* USER CODE BEGIN 0 */


uint8_t CC[2]={0xCC,0xCC};
uint8_t DD[2]={0xDD,0xDD};


/* USER CODE END 0 */

/**
 * @brief The application entry point.
 * @retval int
 */
int main(void)
{
 /* USER CODE BEGIN 1 */


 /* USER CODE END 1 */

 /* MCU Configuration--------------------------------------------------------*/

 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 HAL_Init();

 /* USER CODE BEGIN Init */

 /* USER CODE END Init */

 /* Configure the system clock */
 SystemClock_Config();

 /* USER CODE BEGIN SysInit */

 /* USER CODE END SysInit */

 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 MX_USART1_UART_Init();
 MX_USART2_UART_Init();
 /* USER CODE BEGIN 2 */


 HAL_Delay(1000);
 transceiver(WRITE);
 HAL_UART_Transmit(&huart2, CC, 2, 10);
 HAL_Delay(1000);
 HAL_UART_Transmit(&huart2, DD, 2, 10);
 transceiver(READ);


 /* USER CODE END 2 */

 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {

 /* USER CODE END WHILE */

 /* USER CODE BEGIN 3 */
 }
 /* USER CODE END 3 */
}

 

Best answer by Raf_al

Ok, so i tried with HAL_UART_Transmit_IT but it didnt work.

By accident I disconnected my oscilloscope from MCU1 UART lines and now it works.:grinning_face_with_sweat:

 

7 replies

Tesla DeLorean
Guru
June 26, 2024

Instrument the code so you have some idea as to what's going on

Does HAL_UART_Receive_IT() return an error in any of these case?

Is there an error or status flagged by the UART that needs to be cleared for reception to work? Are you clearing it?

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
Karl Yamashita
Lead III
June 26, 2024

You don't check for HAL status on any of the HAL calls so how do you know what is happening?

 

 if(HAL_UART_Transmit(&huart2, ZERO, 2, 10) != HAL_OK)
 {
 // Do some error handling
 } 

 if(HAL_UART_Receive_IT(&huart2, buffer, 2) != HAL_OK)
 {
 // Do some error handling
 }

 

 

And what do these do?

 

transceiver(WRITE);
transceiver(READ);

 

 

 

 

 

If a reply has proven helpful, click on Accept as Solution so that it'll show at top of the post.CAN Jammer an open source CAN bus hacking toolCANableV3 Open Source
Raf_alAuthor
Associate II
June 27, 2024

I modified MCU1 code a little bit.

/* USER CODE BEGIN 0 */


uint8_t buffer[2];
uint8_t ZERO[2]={0x00,0x00};
uint8_t AA[2]={0xAA,0xAA};
uint8_t BB[2]={0xBB,0xBB};


void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{

if(buffer[0]==0xCC && buffer[1]==0xCC)
{
	LED1(ON);
}

if(buffer[0]==0xDD && buffer[1]==0xDD)
{
	LED2(ON);
}
if(buffer[0]==0xEE && buffer[1]==0xEE)
{
	LED1(OFF);
	LED2(OFF);
}


if((HAL_UART_Receive_IT(&huart2, buffer, 2))==!HAL_OK)
		{
	LED3(ON);
		}

}



/* USER CODE END 0 */

/**
 * @brief The application entry point.
 * @retval int
 */
int main(void)
{
 /* USER CODE BEGIN 1 */


 /* USER CODE END 1 */

 /* MCU Configuration--------------------------------------------------------*/

 /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
 HAL_Init();

 /* USER CODE BEGIN Init */

 /* USER CODE END Init */

 /* Configure the system clock */
 SystemClock_Config();

 /* USER CODE BEGIN SysInit */

 /* USER CODE END SysInit */

 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 //MX_I2C1_Init();
 MX_USART2_UART_Init();
 /* USER CODE BEGIN 2 */


 transceiver(WRITE);
 if((HAL_UART_Transmit(&huart2, ZERO, 2, 10))==!HAL_OK)
		LED3(ON);
 transceiver(READ);
 HAL_UART_Receive_IT(&huart2, buffer, 2);




 /* USER CODE END 2 */

 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {



 /* USER CODE END WHILE */

 /* USER CODE BEGIN 3 */
 }
 /* USER CODE END 3 */
}

On MCU2 I have 3 switches. When I push down first switch it sends {0xCC,0xCC}, second switch {0xDD,0xDD} and third switch {0xEE,0xEE}.

LED3 is off, so everytime status of HAL_UART_Transmist and HAL_UART_Receive_IT is HAL_OK.

 

Something I saw is that if I press the button once, LED 1 or 2 doesn't light up, but if I press it twice, it does. In the same way to off the LEDs I need two presses.

It's as if HAL_UART_Receive_IT is configured to a 4 byte buffer and not a 2 byte buffer.

Karl Yamashita
Lead III
June 27, 2024

You still didn't answer my last question

If a reply has proven helpful, click on Accept as Solution so that it'll show at top of the post.CAN Jammer an open source CAN bus hacking toolCANableV3 Open Source
Raf_alAuthor
Associate II
June 27, 2024

Right,

transceiver(WRITE);
transceiver(READ);

That just sets the state of the rs485 transceiver.

Transceiver (WRITE) sets 1 on the pin to send data

Transceiver (READ) sets 0 on the pin to receive data

Generally this function works well I looked it up on an oscilloscope.

Andrew Neil
Super User
June 27, 2024

@Raf_al wrote:

With MCU2 code everything is fine. It sends data like it should be.


How have you proved that?

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Raf_alAuthor
Associate II
June 27, 2024

I can see on the oscilloscope that it sends, for example, these {0xDD,0xDD} when I press the button. I just decode the whole frame. It's simple UART 8n1

Karl Yamashita
Lead III
June 27, 2024

Is the Transceiver (READ) switching fast enough before the other MCU replies? Check with oscilloscope.

 

Maybe try this approach

 /* Initialize all configured peripherals */
 MX_GPIO_Init();
 MX_USART2_UART_Init();
 /* USER CODE BEGIN 2 */

 
 HAL_UART_Receive_IT(&huart2, buffer, 2); // enable first

	transceiver(WRITE);
	if((HAL_UART_Transmit_IT(&huart2, ZERO, 2)) != HAL_OK) // use transsmit interrupt
		LED3(ON);
 

 /* USER CODE END 2 */

 /* Infinite loop */
 /* USER CODE BEGIN WHILE */
 while (1)
 {
 /* USER CODE END WHILE */

 /* USER CODE BEGIN 3 */
 }
 /* USER CODE END 3 */
}

void HAL_UART_TxCpltCallback(UART_HandleTypeDef *huart)
{
	transceiver(READ);
}

 

 

 

If a reply has proven helpful, click on Accept as Solution so that it'll show at top of the post.CAN Jammer an open source CAN bus hacking toolCANableV3 Open Source
Raf_alAuthor
Associate II
June 27, 2024

I think that problem is somewhere else. I can press that button (button that sends 0xDD for example) 10 seconds after MCU1 goes to tranceiver read mode.

Andrew Neil
Super User
June 27, 2024

@Raf_al wrote:

I think ...


It's good to have a theory. :thumbs_up:

Now you need to devise a test to prove whether your theory is correct or not ...

See The Scientific Approach to Debugginghttp://www.8052mcu.com/faqs/120313 

A complex system that works is invariably found to have evolved from a simple system that worked.A complex system designed from scratch never works and cannot be patched up to make it work.
Raf_alAuthorBest answer
Associate II
June 28, 2024

Ok, so i tried with HAL_UART_Transmit_IT but it didnt work.

By accident I disconnected my oscilloscope from MCU1 UART lines and now it works.:grinning_face_with_sweat: