How interrups works in buttons in STM32 ?

Thread Starter

Xenon02

Joined Feb 24, 2021
504
Hello !

I've been working on 4 leds in STM32 - school project.
Project was simple : Everytime I click the button, the light switches. For example 1st diode is on the rest are off, when I click the button the 2nd diode is on and the rest are off.

I knew from tutorials how to do it. But I was mixed with Interrupts in STM32. I am also learning how to code in C from basics so this also might be the problem.

The thing is I've set the Button into External interrupt mode.
But I don't understand the functions ....

1)
1696957937770.png

Don't mind the rest of the code I don't know why it didn't color it in green. Only the code inside the red rectangle is the actual code inside of this function.

I don't know why I had to use HAL_GPIO_EXIT_Callback in main function. Because I didn't know where was this interrupt function and it was in a different file.
2)
1696958059875.png
(This photo below nr.3, is from a video of how it looked like when I went inside of HAL_GPIO_EXTI_IRQHandler)
3)
1696966086466.png

When I saw HAL_GPIO_EXTI_IRQHandler I thought I could write a code (red rectangle code) inside of HAL_GPIO_EXTI_IRQHandler like in picture nr.2, but my teacher said to not do it and get inside HAL_GPIO_EXTI_IRQHandler (he showed me how) and copy HAL_GPIO_EXIT_Callback, put it in main function and then write a code inside HAL_GPIO_EXIT_Callback.

Why ? Couldn't I write the code in his original place which was HAL_GPIO_EXIT_Callback? But instead I had to copy it into the main program ?
I am very new to it in C language so maybe that's why but I don't know where to find the source why it works like that. What I found is how to use the function from different files :

1696958511679.png

So it looks pretty much the same there is only one difference. Here in the example from the picture above getSum has a function not inside of main but only in new file but in HAL_GPIO_EXIT_Callback the function is also in main and in different file HAL_GPIO_EXIT_Callback is empty and not used. Why ? Why do I have to copy HAL_GPIO_EXIT_Callback and not write code in HAL_GPIO_EXTI_IRQHandler ?

Or is it somehow also related to functions callback like here ? (but I only found javascript example and not C) :

1696958689997.png

But that's wierd can someone help me resolve this confusion ? Because I didn't have time to ask why but I want to know.
 
Last edited:

MrChips

Joined Oct 2, 2009
34,908
What is HAL?

HAL stands for Hardware Abstraction Layer. So what does this mean?
It means that HAL drivers are prewritten for you so that you do not have worry about how to interface with the hardware.

If you really want to understand how your hardware works, I would recommend that you do not use HAL and other such libraries. HAL etc. are there for production/professional programmers who want to get the job done fast with the ability to be able to run code across a wide family of MCUs.

After you have learned the basics of the hardware, go ahead and indulge by using HAL.
 

Thread Starter

Xenon02

Joined Feb 24, 2021
504
What is HAL?

HAL stands for Hardware Abstraction Layer. So what does this mean?
It means that HAL drivers are prewritten for you so that you do not have worry about how to interface with the hardware.

If you really want to understand how your hardware works, I would recommend that you do not use HAL and other such libraries. HAL etc. are there for production/professional programmers who want to get the job done fast with the ability to be able to run code across a wide family of MCUs.

After you have learned the basics of the hardware, go ahead and indulge by using HAL.
I was introduced to it at the beggining and it was told to us that it is easy even for newbies. In tutorials they are also using mainly HAL.

So that's why I didn't understand only this particular HAL instruction, or rather 2 because there was HAL_GPIO_EXTI_IRQHandler and HAL_GPIO_EXIT_Callback.

The problem was that I didn't understand why I couldn't write the code inside of HAL_GPIO_EXTI_IRQHandler but rather get inside of HAL_GPIO_EXTI_IRQHandler which is wierd because HAL_GPIO_EXTI_IRQHandler had then new functions and outside of it has different functions as well ... Is it something I should know from the basics of C language ? And how could I know that I had to get inside of HAL_GPIO_EXTI_IRQHandler and find this HAL_GPIO_EXIT_Callback ?

I don't know any better tutorials and I have to buy the STM myself because I only used the school STM32 Discovery I guess.

I don't also know if my confusion is well written above I tried my best to show it using examples from tutorial. I found out that HAL_GPIO_EXIT_Callback is not acting the same as callback in C programs like in the picture below :

1696970010426.png

that's why I asked how actually the interrup works and why I had to find this Callback function and copy paste it in main function. And why HAL_GPIO_EXTI_IRQHandler had outside different function and inside also different function like in the first post picture 2 and 3.

If it's C language begginer stuff, I would be glad to know what it is called so I'll try to read something about it.
 

Thread Starter

Xenon02

Joined Feb 24, 2021
504
If you want to use HAL, go ahead. I cannot help you with that.
Dang it I thought you knew the answer to this problem ;<
Also I just use HAL because there are many tutorials about it and I didn't want to break something in the microcontroler and HAL was the easiest (at least that's how many people says). So with these type of problems I wanted to understand to not make a mistake or to better understand why I have to get way deeper into the function.

I never knew that. I thought it was a quote from Space Odyssey.
1696971918034.png

HAL Always watches. Unfortunatelly or fortunatelly it is not the same HAL ;<


Well aside from that does anyone know something about this (the topic) ?
EDIT: Or is this of situation that is way more complex for begginers and I should just accept that is how to do it ? Although I want to know whether why this works like that or how to know where to get specific functions that are hidden pretty deep like it was with HAL_GPIO_EXTI_IRQHandler.
 
Last edited:

MrChips

Joined Oct 2, 2009
34,908
Here are the steps required to activate GPIO interrupts.

1) Initialize the GPIO port and pin.
2) Initialize the pin for interrupts.
3) Initialize NVIC (Nested Vectored Interrupt Controller).
4) Write the GPIO interrupt handler.
 

Thread Starter

Xenon02

Joined Feb 24, 2021
504
Here are the steps required to activate GPIO interrupts.

1) Initialize the GPIO port and pin.
2) Initialize the pin for interrupts.
3) Initialize NVIC (Nested Vectored Interrupt Controller).
4) Write the GPIO interrupt handler.
GPIO port and pin was initialized or rather set in the visual side ? I don't know how to describe it, there was a chip with STM and it's pins, i clicked at one pin set it to EXTIO and turned on NVIC. Then the GPIO Interrupt handler was in different file which was I guess understandable because it was not in main file but as I said in different file. This handler is I guess : EXTIO_IRQHandler (picture nr.2 post nr.1). I wanted to write the code which is this :
1696973726970.png

1696974067753.png
But my teacher said to go "inside" HAL_GPIO_EXTI_IRQHandler and find HAL_GPIO_EXIT_Callback. And instead of writing something in this new found HAL_GPIO_EXIT_Callback, my teacher said to copy HAL_GPIO_EXIT_Callback and use it in main file instead of that different file. Why ???? Why the HAL_GPIO_EXIT_Callback works like that ? I don't understand. Tutorials also says to use this but how on earth I could find this out myself ? :D And this is not like in typical C codes that I use a function from different file to use it's result in the main file or callback functions. But something weird. Like I said is it something basic thing in C that could tell me why I had to find HAL_GPIO_EXIT_Callback copy it and paste it in main instead of writing the code in this different file where was originally HAL_GPIO_EXIT_Callback ?

Sorry for this block of text. I believe I asked one thing that was only about HAL_GPIO_EXIT_Callback. But gave bigger background so to show why I am confused ...
 

MrChips

Joined Oct 2, 2009
34,908
Nothing is set in the visual side but I know what you mean.
All the visual assistant does is generate the initialization code for you. You can go look at the generated code and see what it does. You can even modify the code to suit your needs.
 

Thread Starter

Xenon02

Joined Feb 24, 2021
504
Nothing is set in the visual side but I know what you mean.
All the visual assistant does is generate the initialization code for you. You can go look at the generated code and see what it does. You can even modify the code to suit your needs.
That's right :> I'm glad that it was somehow understandable ;D
So Like I said the handler you mentioned before was probably " EXTIO_IRQHandler", like in the picture below.
1696976038209.png

But my teacher said to do it differently which required for me to dig the code instead of using the visible code and here was the problem stated in post#8, and I'm trying to find the answer to this. And I wonder whether it is to complex or this knowladge where was this HAL_GPIO_EXIT_Callback, not a basic thing how it works and for what it is ?
 

Thread Starter

Xenon02

Joined Feb 24, 2021
504
Please stop saying visible code.
Use the term “auto generated code” or ”STM32CubeIDE generated code“.
I didn't know how to describe the code that was generated inside HAL_GPIO_EXTI_IRQHandler so I said "visible", but I'll try naming it proprely, but if it's possible to talk about the problem I am facing, stated in post#8 ;>. Because I still don't know whether it is a simple C programming basics that I don't know or something out of blue, I tried to understand why I had to use something else and why I had to use this new HAL not inside the HAL_GPIO_EXTI_IRQHandler but somewhere outside?

I don't want to give up on this post because I have a feeling that this knowladge might help me understand coding using HAL or finding usable codes that are hidden inside auto generated codes like for the EXTIO_IRQHandler .
 

MrChips

Joined Oct 2, 2009
34,908
There is nothing hidden inside auto generated codes.
All the functions are declared in the HAL driver .c and .h files. You can open these files and they will tell you how the functions are to be used.
 

Thread Starter

Xenon02

Joined Feb 24, 2021
504
There is nothing hidden inside auto generated codes.
All the functions are declared in the HAL driver .c and .h files. You can open these files and they will tell you how the functions are to be used.
The Handler function was in different file and I could write code there, the Callback function was also in different file but I couldn't write the code there instead I had to use it in main. Why ? I don't know.
And it was pretty hidden, because it wasn't visible at least in core folder. I tried to search it, but clicking the HAL_GPIO_EXTI_IRQHandler gives me this possibility.


Now when I think about it, it is very wierd.

When I want to use the interrupt handler of the button I use this :
1696977650784.png It is in different file but I can write to it. But instead I clock on HAL which is a function that leads me to what this functions does in different file and find this :

1696977744675.png

Can I write something also in that void HAL_GPIO_EXTI_IRQHandler ? Because EXTIO_IRQHandler is not a HAL so maybe that's why I can write in him. But HAL_GPIO_EXTI_IRQ_Handler in EXTIO_IRQHandler acts like calling a function in another file, But a function HAL_GPIO_EXTI_Callback isn't the fuction we call in main fail, in which HAL_GPIO_EXTI_IRQ_Handler is a function we call in Interrupt file or rather it is called in EXTIO_IRQHandler.
Why HAL_GPIO_EXTI_Callback is different and I can't write a code in it like it is in HAL_GPIO_EXTI_IRQ_Handler. It is somewhat special is there any explenation why it works like that ?
How do I know that callback will be used ? I know the interupt will be used but callback ?


Overall is it somehow understandable, that question of mine ? I want to make sure, because I am repeating the same question and I don't want to spam this post ;)
I apologize beforehand if I am annoying here anyone or was rude here.
 

MrChips

Joined Oct 2, 2009
34,908
I don't know. I would have to fire up STM32CubeIDE to see what you are talking about.
The HAL library functions themselves would be write protected. I would assume that cannot change them.
 

Thread Starter

Xenon02

Joined Feb 24, 2021
504
I don't know. I would have to fire up STM32CubeIDE to see what you are talking about.
I would be really glad ;> Because I really want to understand this.
Wonder why you ask ? I don't know I was annoyed when I didn't understand it and tried to understand it watching videos how different type of functions work in C language. I also thought that this type of situation might not be the first so I wanted to understand this situation to understand future similar problem or possibility to look more deep in the codes ;) I know it is not deep but that's how it looked like for me.

Any help is welcome ;) Big brother HAL is watching me so I need to find a way to defeat him :>

Btw if there is anything that is not understandable from my post tell me ! I will try to clarify it using pictures or different wording ;)
Post #8 and #1 are the best so far in which I've described my problem. Yes I know very long post but I didn't know how to ask it simply with my clumsy english.
 

MrChips

Joined Oct 2, 2009
34,908
HAL_GPIO_EXTI_Callback( ) is your function that you write to handle the interrupt.
Put this function in you main.c file, something like this

C:
* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  // your code goes here
}

/* USER CODE END 0 */
 

Thread Starter

Xenon02

Joined Feb 24, 2021
504
PS

I also noticed that void HAL_GPIO_EXTI_Callback is the only HAL that requires to be defined, but HAL_GPIO_WritePin or HAL_GPIO_ReadPin or many more doesn't require being defined, take a look at this :

1696981121739.png

Why ?


HAL_GPIO_EXTI_Callback( ) is your function that you write to handle the interrupt.
Put this function in you main.c file, something like this
I only had this :

1696981167063.png

The HAL_GPIO_EXTI_Callback was inside HAL_GPIO_EXTI_IRQHandler. What's more is that HAL_GPIO_EXTI_IRQHandler didn't have to be defined but HAL_GPIO_EXTI_Callback had to be defined. Both of them are functions so why one doesn't have to be defined and the other function has to be defined ??

that's so weird ...

Oh and holding the ctrl button and clicking at HAL_GPIO_EXTI_IRQHandler will get you inside of him and there I found HAL_GPIO_EXTI_Callback. Like in the picture below :

1696981397933.png

So my guess was that I could write the code here :

1696981167063.pngWhich was the code that wasn't in main but is also for interrupt, would it work ? It is interruption function for button so maybe ?

Your callback is different from mine. Why I have to copy the HAL_GPIO_EXTI_Callback ? That was the question why it works differently than other functions. For example :


1696981167063.png
The HAL_GPIO_EXTI_IRQHandler wasn't copied like HAL_GPIO_EXTI_Callback, the HAL_GPIO_EXTI_IRQHandler code was inside the file while HAL_GPIO_EXTI_Callback had to be in main not in the file he was. Why ?

It is all the time the same question ;) I don't know if I'm making mistakes in explaining why I am confused ;>
Should I write in points what I am trying to ask ? Let me know.

HAL_GPIO_EXTI_Callback( ) is your function that you write to handle the interrupt.
Can't the interrupt be handler also in EXTIO_IRQHandler also supposed to handle the interrupt ? Or in other words when the interrupt happens this is the first function it executes ? Then I write the code there and that's all.
 

MrChips

Joined Oct 2, 2009
34,908
There is nothing weird. Some functions are already written for you, some you have to write yourself.
There is nothing to stop you from inserting your own code directly here.

C:
void EXTI0_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI0_IRQn 0 */

  /* USER CODE END EXTI0_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
  /* USER CODE BEGIN EXTI0_IRQn 1 */

  /* USER CODE END EXTI0_IRQn 1 */
}
Just remember that this same code is also called when different pins are used as GPIO interrupts. You have to choose which interrupt you are servicing.
 

Thread Starter

Xenon02

Joined Feb 24, 2021
504
Just remember that this same code is also called when different pins are used as GPIO interrupts. You have to choose which interrupt you are servicing.
Very interesting I have 3 questions then :

- Why Callback functions works then only for one pin when the argument is GPIO_Pin, It is not Button_Pin ?

- Why only HAL_GPIO_EXTI_Callback required to be defined before using ? He is the only HAL that required to be defined.

Note : Look what do I mean
In your code

C:
Code:
void EXTI0_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI0_IRQn 0 */

  /* USER CODE END EXTI0_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
  /* USER CODE BEGIN EXTI0_IRQn 1 */

  /* USER CODE END EXTI0_IRQn 1 */
}
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0); was not pre defined and was used without adding code inside.

While here :

C:
Code:
* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  // your code goes here
}

/* USER CODE END 0 */
HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin) was copied and could have code inside AND was defined here :

1697000757267.png

Like I asked on 2nd question. Why ?
Both of them here are functions :

1697000813646.png

Is my question somehow understandable ?

Last question

- Similar to second question. Why only HAL_GPIO_EXTI_Callback has to be copied with Void in which HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0) was copied without Void ?

Look here
1697001102520.png

Here Is both HAL_GPIO_EXTI_Callback and HAL_GPIO_EXTI_IRQHandler and they have void. But in your code
C:
Code:
void EXTI0_IRQHandler(void)
{
  /* USER CODE BEGIN EXTI0_IRQn 0 */

  /* USER CODE END EXTI0_IRQn 0 */
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
  /* USER CODE BEGIN EXTI0_IRQn 1 */

  /* USER CODE END EXTI0_IRQn 1 */
}
HAL_GPIO_EXTI_IRQHandler has no void and no brackets to write code.

But here

HAL_GPIO_EXTI_Callback( ) is your function that you write to handle the interrupt.
Put this function in you main.c file, something like this

C:
* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
  // your code goes here
}

/* USER CODE END 0 */
Here HAL_GPIO_EXTI_Callback has void here as well and has brackets for code and was defined at the beginning. Why ? Both of them were void before but one has it and one not.
 
Top