Skip to main content
johannv99
Associate
November 19, 2024
Solved

stm32f0 EXTI cubemx platformio

  • November 19, 2024
  • 9 replies
  • 2956 views

my daily job is C# programming, so after a break on stm32,

I started again with platformIO and CubeMx

( and thought how hard can it be to turn a led on and off ? )

 

the problem i have with the STM32F0 discovery ( the green one )

the EXTI IRQ event is not triggered.

 

i found this example.

https://www.youtube.com/watch?v=xawN4Y7uSJ4

this is my platformIO.ini
[platformio]
default_envs = disco_f051r8

[env:disco_f051r8]
platform = ststm32
board = disco_f051r8
framework = stm32cube
board_build.mcu = stm32f051r8t6
upload_protocol = stlink
build_flags = -I./Inc
board_build.f_cpu = 48000000L
 
after adding the include path ( Inc ) it worked.
 
connecting the board,
building
debugging step by step.
etc etc. 
turn a led on and off ,  push   a button reading the value 1 or 0  ( so i know the button is working )
got it quickly working.
 
the the next step is EXTI interrupt.
( made it with CubeMX32 )
very easy to choose the pins and set up everything.
here some more info how it should be done.

https://moons.link/en/post-256/
https://deepbluembedded.com/stm32-external-interrupt-example-lab/

after chanchig the project with the CubeMx32 tool

the function  changed 

MX_GPIO_Init()

 

 __HAL_RCC_GPIOA_CLK_ENABLE();
 __HAL_RCC_GPIOC_CLK_ENABLE();

from what i read in the documentation.

you can override the weak callback function by adding this.

so when the button is pushed the second led toggles.

void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
 if(GPIO_Pin == UserButton1_Pin) // If The INT Source Is EXTI Line9 (A9 Pin)
 {
 HAL_GPIO_TogglePin(LD4_GPIO_Port, LD4_Pin); // Toggle The Output (LED) Pin
 }
}

there should also be an IRQhandler function.

void EXTI0_IRQHandler(void)
{
 /* USER CODE BEGIN EXTI0_IRQn 0 */
 //HAL_GPIO_TogglePin(LD2_GPIO_Port, LD2_Pin);
 /* 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 */
}
 

 

and the last step where i am not sure about is this.

 
set the priotiry and enable the event.
( but i am not very sure what parameters to send with these functions )
 
PVD_IRQn
 
  HAL_NVIC_SetPriority (PVD_IRQn, 0, 0);
  HAL_NVIC_EnableIRQ (PVD_IRQn);
 

 

after reading a lot and some puzzling, i cannot get it to work.

 

thanks

 

Best answer by mƎALLEm

Hello again:

You need to activate the NVIC of EXTI line.

Since you are using STM32F0DISCOVERY board, I'm making a simple example to toggle LD4 (Blue) using user button connected on PA0 (just make sure SB3 solder bridge is soldered).

EXTI pin definition and IRQ:

 

#define UserButton1_Pin GPIO_PIN_0
#define UserButton1_GPIO_Port GPIOA
#define UserButton1_EXTI_IRQn EXTI0_1_IRQn

 

EXTI NVIC needs to be activated:

 

 /* EXTI interrupt init*/
 HAL_NVIC_SetPriority(EXTI0_1_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(EXTI0_1_IRQn);

 

PA0 IO config (RCC GPIO port enable is already generated for __HAL_RCC_GPIOA_CLK_ENABLE() and  __HAL_RCC_GPIOC_CLK_ENABLE():(

 

 /*Configure GPIO pin : UserButton1_Pin */
 GPIO_InitStruct.Pin = UserButton1_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(UserButton1_GPIO_Port, &GPIO_InitStruct);

 

The GPIO EXTI callback needs to be put in between /* USER CODE XXXX 4 */ 

 

/* USER CODE BEGIN 4 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
 if(GPIO_Pin == UserButton1_Pin) // If The INT Source Is EXTI Line9 (A9 Pin)
 {
 HAL_GPIO_TogglePin(LD4_GPIO_Port, LD4_Pin); // Toggle The Output (LED) Pin
 }
}
/* USER CODE END 4 */

 

The EXTI IRQ handler:

 

void EXTI0_1_IRQHandler(void)
{
 /* USER CODE BEGIN EXTI0_1_IRQn 0 */

 /* USER CODE END EXTI0_1_IRQn 0 */
 HAL_GPIO_EXTI_IRQHandler(UserButton1_Pin);
 /* USER CODE BEGIN EXTI0_1_IRQn 1 */

 /* USER CODE END EXTI0_1_IRQn 1 */
}

 

Attached the project with CubeIDE/CubeMx.

Hope it helps.

9 replies

mƎALLEm
Technical Moderator
November 19, 2024

Hello @johannv99 ,

As it's linked to platformio, better to ask your question in their forum: https://community.platformio.org/

We can help you with STM32CubeIDE, in that case you need to share your ioc file.

"To give better visibility on the answered topics, please click on ""Accept as Solution"" on the reply which solved your issue or answered your question."
mƎALLEm
mƎALLEmBest answer
Technical Moderator
November 19, 2024

Hello again:

You need to activate the NVIC of EXTI line.

Since you are using STM32F0DISCOVERY board, I'm making a simple example to toggle LD4 (Blue) using user button connected on PA0 (just make sure SB3 solder bridge is soldered).

EXTI pin definition and IRQ:

 

#define UserButton1_Pin GPIO_PIN_0
#define UserButton1_GPIO_Port GPIOA
#define UserButton1_EXTI_IRQn EXTI0_1_IRQn

 

EXTI NVIC needs to be activated:

 

 /* EXTI interrupt init*/
 HAL_NVIC_SetPriority(EXTI0_1_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(EXTI0_1_IRQn);

 

PA0 IO config (RCC GPIO port enable is already generated for __HAL_RCC_GPIOA_CLK_ENABLE() and  __HAL_RCC_GPIOC_CLK_ENABLE():(

 

 /*Configure GPIO pin : UserButton1_Pin */
 GPIO_InitStruct.Pin = UserButton1_Pin;
 GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING;
 GPIO_InitStruct.Pull = GPIO_NOPULL;
 HAL_GPIO_Init(UserButton1_GPIO_Port, &GPIO_InitStruct);

 

The GPIO EXTI callback needs to be put in between /* USER CODE XXXX 4 */ 

 

/* USER CODE BEGIN 4 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
 if(GPIO_Pin == UserButton1_Pin) // If The INT Source Is EXTI Line9 (A9 Pin)
 {
 HAL_GPIO_TogglePin(LD4_GPIO_Port, LD4_Pin); // Toggle The Output (LED) Pin
 }
}
/* USER CODE END 4 */

 

The EXTI IRQ handler:

 

void EXTI0_1_IRQHandler(void)
{
 /* USER CODE BEGIN EXTI0_1_IRQn 0 */

 /* USER CODE END EXTI0_1_IRQn 0 */
 HAL_GPIO_EXTI_IRQHandler(UserButton1_Pin);
 /* USER CODE BEGIN EXTI0_1_IRQn 1 */

 /* USER CODE END EXTI0_1_IRQn 1 */
}

 

Attached the project with CubeIDE/CubeMx.

Hope it helps.

"To give better visibility on the answered topics, please click on ""Accept as Solution"" on the reply which solved your issue or answered your question."
johannv99
johannv99Author
Associate
November 19, 2024

thanks for your time and support !!

 

I checked the SB3 solder jumper it has a soldering bridge ( it is original how it came from STM ).

( also, i tested reading the input variable for the push button it goes high and low ) 

 

this is my ioc file.

 

also i choose on

Toolchain  / IDE EWARM

your example has : STM32CubeIDE

 

this looks good now.

 HAL_NVIC_SetPriority(EXTI0_1_IRQn, 0, 0);
 HAL_NVIC_EnableIRQ(EXTI0_1_IRQn);

 

now it is intresting if i push a button the board halts.

 

also when set a breakpoint in. HAL_GPIO_EXTI_Callback() function.

it looks like it is not fired.

 

 

 

mƎALLEm
Technical Moderator
November 19, 2024

Hello,

Sorry I didn't understand this statement:


@johannv99 wrote:

now it is intresting if i push a button the board halts.


What do you mean by "halts"?

 


@johannv99 wrote:

also when set a breakpoint in. HAL_GPIO_EXTI_Callback() function.


This is because you set EXTI in event mode and not in interrupt mode and the NVIC configuration is missing. Fixed you ioc file in attachement.

You need to set interrupt mode:

SofLit_0-1732027851648.png

And in NVIC menu to enable  EXTI line 0:

SofLit_1-1732027942797.png

 

PS:


@johannv99 wrote:

Toolchain  / IDE EWARM

your example has : STM32CubeIDE


You can regenerate the code I've attached previously to generate EWARM project:

SofLit_2-1732028055469.png

Hope it helps.

 

 

"To give better visibility on the answered topics, please click on ""Accept as Solution"" on the reply which solved your issue or answered your question."
johannv99
johannv99Author
Associate
November 19, 2024

after some debugging i found it hangs on.

this loop.

 

/**
 * @brief  This is the code that gets called when the processor receives an
 *         unexpected interrupt.  This simply enters an infinite loop, preserving
 *         the system state for examination by a debugger.
 *
 * @PAram  None
 * @retval : None
*/
    .section .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
  b Infinite_Loop
  .size Default_Handler, .-Default_Handler
 
 
 
 
mƎALLEm
Technical Moderator
November 19, 2024

@johannv99 wrote:

after some debugging i found it hangs on.

this loop.

 

/**
 * @brief  This is the code that gets called when the processor receives an
 *         unexpected interrupt.  This simply enters an infinite loop, preserving
 *         the system state for examination by a debugger.
 *
 * @PAram  None
 * @retval : None
*/
    .section .text.Default_Handler,"ax",%progbits
Default_Handler:
Infinite_Loop:
  b Infinite_Loop
  .size Default_Handler, .-Default_Handler
 

That's because you enabled the EXTI NVIC but you didn't declare the EXTI IRQ handler ..

Did you test the ioc I shared? Use the user button (blue button on the board) to trigger the EXTI interrupt on PA0.

"To give better visibility on the answered topics, please click on ""Accept as Solution"" on the reply which solved your issue or answered your question."
waclawek.jan
Super User
November 19, 2024

> void EXTI0_IRQHandler(void)

Note, that in STM32F0xx there is no dedicated EXTI0 interrupt. See Interrupts and events chapter in RM0091. Note, that @mƎALLEm above used:

> void EXTI0_1_IRQHandler(void)

JW

johannv99
johannv99Author
Associate
November 19, 2024

to answer the question where it "hangs"  ( infinite loop ) 

 

after push the button...

 

it is this file generated by cubeMx

( startup_stm32f051x8.s )

 

 

 

 

mƎALLEm
Technical Moderator
November 19, 2024

@johannv99 wrote:

to answer the question where it "hangs"  ( infinite loop ) 

 

after push the button...

 

it is this file generated by cubeMx

( startup_stm32f051x8.s )


Did you test the ioc I've shared or not? please answer that question.

Thank you.

"To give better visibility on the answered topics, please click on ""Accept as Solution"" on the reply which solved your issue or answered your question."
waclawek.jan
Super User
November 19, 2024

It goes into the Default_Handler because you don't have defined the proper interrupt handler, i.e. EXTI0_1_IRQHandler() (the weak EXTI0_1_IRQHandler in the startup code, which is in that case used, is then just an alias of Default_Handler).

JW

johannv99
johannv99Author
Associate
November 19, 2024

I tried your ioc file and project, but it had the same problem.

 

I think Mr Waclawek could be right.

 

i found 2 similar cases.

this is the loop where it hangs,  ( because of the Default_Handler  )

https://community.st.com/t5/stm32-mcus-products/whenever-interrupt-generate-default-handler-infine-loop-execute/td-p/485841

 

here it looks like there is a solution for the startup_stm32F051x8.s file.

https://community.st.com/t5/stm32-mcus-products/exti-irq-with-userbutton-problem/td-p/427227

 

I think slowly i am getting there.

mƎALLEm
Technical Moderator
November 19, 2024

Could you please share the complete poject?

 

"To give better visibility on the answered topics, please click on ""Accept as Solution"" on the reply which solved your issue or answered your question."
johannv99
johannv99Author
Associate
November 20, 2024

The STM32 CubeMx tool saves you lots of time, figuring out what functions you have left on free pins.
also port configuration and all other options. are real handy.

 

other option is, if your project has to change to a different cpu variant, it will save lots of time.

 

one thing is if you are new to using it, take some time to click through the interface.

 

one checkbox missed, for a port and the function was not generated. and lots of coding debbuging time etc.

 

thanks for all help.

 

@mr_it waclawek.jan

this was indeed missing when code was generated. there was only a default_handler.

EXTI0_1_IRQHandler() ( EXTI0_1_IRQHandler )