Why does the value of the variable inside the interrupt not change?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-07-22 11:09 AM
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 */
}
Solved! Go to Solution.
- Labels:
-
Documentation
-
STM32CubeMX
Accepted Solutions
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-07-22 7:21 PM
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.
TimerCallback tutorial! | UART and DMA Idle tutorial!
If you find my solution useful, please click the Accept as Solution so others see the solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-07-22 11:44 AM
What if range is not 0 and not 1?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-07-22 11:51 AM
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-07-22 11:57 AM
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-07-22 12:01 PM
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-07-22 6:47 PM
The code you linked still has the issues I pointed out in my previous reply.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-07-22 6:50 PM - edited ‎2024-07-22 6:54 PM
Don't write anything in the UART4_IRQHandler. Write your code in the callback instead. Override the HAL_UART_RxCpltCallback callback. Not sure if that'll fix your issue, but at least the HAL driver will be done clearing any interrupts and/or save the error(s) prior to calling the callback.
void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart)
{
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;
}
}
Also, you should look into using HAL_UARTEx_ReceiveToIdle_IT or HAL_UARTEx_ReceiveToIdle_DMA and HAL_UARTEx_RxEventCallback, that way you can receive any variable length packet.
TimerCallback tutorial! | UART and DMA Idle tutorial!
If you find my solution useful, please click the Accept as Solution so others see the solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-07-22 7:21 PM
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.
TimerCallback tutorial! | UART and DMA Idle tutorial!
If you find my solution useful, please click the Accept as Solution so others see the solution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Email to a Friend
- Report Inappropriate Content
‎2024-07-23 1:10 PM
Thanks You Sir!
