Skip to main content
AlexanderKibarov
Associate III
July 22, 2024
Solved

Why does the value of the variable inside the interrupt not change?

In this code, the value of the range variable in the purse does not change correctly. What is the reason?

Board = NUCLEO-F413ZH

/* External variables --------------------------------------------------------*/
extern UART_HandleTypeDef huart4;
extern volatile uint8_t range;
extern uint8_t first_buffer[5];
extern uint8_t main_buffer[8];
/* USER CODE BEGIN EV */

void UART4_IRQHandler(void)
{
 /* USER CODE BEGIN UART4_IRQn 0 */

 /* USER CODE END UART4_IRQn 0 */
 HAL_UART_IRQHandler(&huart4);
 /* USER CODE BEGIN UART4_IRQn 1 */
 //__HAL_UART_ENABLE_IT(&huart4, UART_IT_RXNE);
 if(range == 0) {
	 HAL_UART_Receive_IT(&huart4, first_buffer, 5);
	 range = 1;
 }
 else if(range == 1){
	 HAL_UART_Receive_IT(&huart4, main_buffer, 8);
	 range = 0;
 }
 /* USER CODE END UART4_IRQn 1 */
}

 

This topic has been closed for replies.
Karl Yamashita
Karl YamashitaBest answer
Principal
July 23, 2024

I just confirmed, writing your code in UART4_IRQHandler doesn't work. range doesn't update.

But writing your code in the callback works so range changes correctly. 

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

8 replies

Pavel A.
July 22, 2024

What if range is not 0 and not 1?

AlexanderKibarov
Associate III
July 22, 2024

Hello, the full code is as follows:

 

main.c:

/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * @file : main.c
 * @brief : Main program body
 ******************************************************************************
 */
#include "main.h"

UART_HandleTypeDef huart4;
UART_HandleTypeDef huart3;

PCD_HandleTypeDef hpcd_USB_OTG_FS;

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART3_UART_Init(void);
static void MX_USB_OTG_FS_PCD_Init(void);
static void MX_UART4_Init(void);

volatile uint8_t range = 0;
uint8_t first_buffer[5];
uint8_t main_buffer[8];

int main(void)
{
 HAL_Init();

 SystemClock_Config();

 MX_GPIO_Init();
 MX_USART3_UART_Init();
 MX_USB_OTG_FS_PCD_Init();
 MX_UART4_Init();

 __HAL_UART_ENABLE_IT(&huart4, UART_IT_RXNE);

 while (1)
 {
 HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_14);
 HAL_Delay(250);
 }
}

#endif /* USE_FULL_ASSERT */

 

stm32f4xx_it.h:

/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * @file stm32f4xx_it.c
 * @brief Interrupt Service Routines.
 ******************************************************************************
 */
/* USER CODE END Header */

#include "main.h"
#include "stm32f4xx_it.h"

extern UART_HandleTypeDef huart4;
extern volatile uint8_t range;
extern uint8_t first_buffer[5];
extern uint8_t main_buffer[8];

void UART4_IRQHandler(void)
{
 HAL_UART_IRQHandler(&huart4);

 if(range == 0) {
	 HAL_UART_Receive_IT(&huart4, first_buffer, 5);
	 range = 1;
 }
 else if(range == 1) {
	 HAL_UART_Receive_IT(&huart4, main_buffer, 8);
	 range = 0;
 }
}

 

 

The Range variable measures whether 5 bytes or 8 bytes will be read. However, the variable values do not change properly; sometimes it remains 1 when it should be 0, sometimes the opposite happens, and sometimes it works correctly. But regardless of the situation, it always reads the 5-byte portion the first time it runs, then reads the 8-byte portion without checking the value of the range variable.

TDK
July 22, 2024

Generally, you should be putting HAL_UART_Receive_IT within a user callback such as the receive complete callback. The way it is now, it'll trigger off of any UART IRQ, including each received character. Certainly not what you want. Monitor the return status of HAL_UART_Receive_IT and do something useful when it's something other than HAL_OK.

Most likely, the variable is changing as it should but bugs in the code are responsible for the bad behavior you're seeing.

"If you feel a post has answered your question, please click ""Accept as Solution""."
AlexanderKibarov
Associate III
July 22, 2024

Hello, the full code is as follows:

 

main.c:

/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * @file : main.c
 * @brief : Main program body
 ******************************************************************************
 */
#include "main.h"

UART_HandleTypeDef huart4;
UART_HandleTypeDef huart3;

PCD_HandleTypeDef hpcd_USB_OTG_FS;

void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_USART3_UART_Init(void);
static void MX_USB_OTG_FS_PCD_Init(void);
static void MX_UART4_Init(void);

volatile uint8_t range = 0;
uint8_t first_buffer[5];
uint8_t main_buffer[8];

int main(void)
{
 HAL_Init();

 SystemClock_Config();

 MX_GPIO_Init();
 MX_USART3_UART_Init();
 MX_USB_OTG_FS_PCD_Init();
 MX_UART4_Init();

 __HAL_UART_ENABLE_IT(&huart4, UART_IT_RXNE);

 while (1)
 {
 HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_14);
 HAL_Delay(250);
 }
}

#endif /* USE_FULL_ASSERT */

 

stm32f4xx_it.c:

/* USER CODE BEGIN Header */
/**
 ******************************************************************************
 * @file stm32f4xx_it.c
 * @brief Interrupt Service Routines.
 ******************************************************************************
 */
/* USER CODE END Header */

#include "main.h"
#include "stm32f4xx_it.h"

extern UART_HandleTypeDef huart4;
extern volatile uint8_t range;
extern uint8_t first_buffer[5];
extern uint8_t main_buffer[8];

void UART4_IRQHandler(void)
{
 HAL_UART_IRQHandler(&huart4);

 if(range == 0) {
	 HAL_UART_Receive_IT(&huart4, first_buffer, 5);
	 range = 1;
 }
 else if(range == 1) {
	 HAL_UART_Receive_IT(&huart4, main_buffer, 8);
	 range = 0;
 }
}

 

The Range variable measures whether 5 bytes or 8 bytes will be read. However, the variable values do not change properly; sometimes it remains 1 when it should be 0, sometimes the opposite happens, and sometimes it works correctly. But regardless of the situation, it always reads the 5-byte portion the first time it runs, then reads the 8-byte portion without checking the value of the range variable.

 

TDK
July 23, 2024

The code you linked still has the issues I pointed out in my previous reply.

"If you feel a post has answered your question, please click ""Accept as Solution""."
Karl Yamashita
Karl YamashitaBest answer
Principal
July 23, 2024

I just confirmed, writing your code in UART4_IRQHandler doesn't work. range doesn't update.

But writing your code in the callback works so range changes correctly. 

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
AlexanderKibarov
Associate III
July 23, 2024

Thanks You Sir!