Skip to main content
Senior
Jun 17, 2023 6:14 AM UTC
Question

Interrupt Mode HAL Delay

Hello 

I am newbie to embedded word.  I am trying to learn interrupt for GPIO on NUCLEO-F091RC. I set the User Button as interrupt and LED should toggle as button is pressed. I copied the callback function ( HAL_GPIO_EXTI_Callback) in main.c . Under callback function, I called HAL_GPIO_Toggle . The code is working as expected. 

But now I want LED to Blink as interrupt from button is generated. I wrote the below code. But as soon code comes to HAL_Delay function , it hangs. I tried to check in debug mode also. As  I come to HAL_Delay function- StepInto , StepOver button fades out and code hangs there. 

************************************************

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
while(1)
{
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
HAL_Delay(1000);
}
}

 

 

 

 

 

 

This topic has been closed for replies.

2 replies

waclawek.jan
Super User
Jun 17, 2023 7:39 AM UTC

Cube/HAL is open source so you can check what's going on by reading those sources.

Delay in Cube/HAL generally depends on interrupt, usually SysTick, so if you don't assign proper priorities to that and your interrrupts, while in your interrupt, the delay-related interrupt can't fire and advance its counter.

JW

Johi
Senior II
Jun 17, 2023 4:12 PM UTC

ISR (interrupt service routines) should be exited as quick as possible and kept as short as possible, delays in and ISR are a bad idea because you block what has a lower interrupt priority in the mcu. On top of that as explained by @waclawek.jan above, if your hardware ISR has a higher priority than the SysTick ISR that is the driver of the time count in HAL_Delay(), HAL_Delay cannot work anymore and your HAL_Delay waits forever for ticks that do not come any more.

The alternative is to set a flag and use the main() loop to organize the blinking:

/* USER CODE BEGIN PV */
#define TRUE 1 // JOHI
#define FALSE 0 // JOHI
volatile uint8_t buttonPressedFlag=FALSE; // JOHI
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
/* USER CODE BEGIN PFP */

// JOHI:
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
 /* Prevent unused argument(s) compilation warning */
 if (GPIO_Pin==BUTTON_Pin)
	 buttonPressedFlag=TRUE;
}

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* 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();
 /* USER CODE BEGIN 2 */

 /* USER CODE END 2 */

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

 /* USER CODE BEGIN 3 */
 // JOHI:
	if (buttonPressedFlag==TRUE)
	{
		HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
		HAL_Delay(1000);
		HAL_GPIO_TogglePin(LED_GPIO_Port,LED_Pin);
		HAL_Delay(1000);
		buttonPressedFlag=FALSE;
	}
	HAL_Delay(10);
 }
 /* USER CODE END 3 */
}