cancel
Showing results for 
Search instead for 
Did you mean: 

Interrupt handling with STM32F4xx_DSP_StdPeriph_Lib (EXTI0)

simo zz
Senior
Posted on October 30, 2017 at 13:38

Hello,

I am studying the STM32F4xx_DSP_StdPeriph_Lib and I am trying to understand how to handleEXTI0 interrupts using the STM32F4xx Discovery Board.

The firmware should execute the interrupt when the GPIOA0 is triggered (in this case with the User button) and sequentially toggle the GPIOD[12:15] pins.

The code I wrote is the following:

#include <stm32f4xx.h>
#include <stm32f4xx_rcc.h>
#include <stm32f4xx_gpio.h>
#include <stm32f4xx_exti.h>
uint8_t gpioDIndex;
// ISR
void EXTI0_IRQHandler(void)
{
if(EXTI_GetITStatus(EXTI_Line0))
{
EXTI_ClearITPendingBit(EXTI_Line0);
gpioDIndex++;
if(gpioDIndex > 3)
gpioDIndex = 0;
}
}
int main(void)
{
// GPIO, NVIC and EXTI declarations
GPIO_InitTypeDef GPIO_t;
NVIC_InitTypeDef NVIC_t;
EXTI_InitTypeDef EXTI_t;
// SYCFG and GPIOA GPIOD Clock enable
RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, ENABLE);
RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA | RCC_AHB1Periph_GPIOD, ENABLE);
// configure GPIOA0 as input
GPIO_t.GPIO_Pin = GPIO_Pin_0;
GPIO_t.GPIO_Mode = GPIO_Mode_IN;
//GPIO_t.GPIO_OType = GPIO_OType_PP;
GPIO_t.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_t.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOA, &GPIO_t);
// Configure GPIOD[12:15] as output
GPIO_t.GPIO_Pin = GPIO_Pin_12 | GPIO_Pin_13 | GPIO_Pin_14 | GPIO_Pin_15;
GPIO_t.GPIO_Mode = GPIO_Mode_OUT;
GPIO_t.GPIO_OType = GPIO_OType_PP;
GPIO_t.GPIO_Speed = GPIO_Speed_100MHz;
GPIO_t.GPIO_PuPd = GPIO_PuPd_NOPULL;
GPIO_Init(GPIOD, &GPIO_t);
// Configure external interrupt for PA0
SYSCFG_EXTILineConfig(EXTI_PortSourceGPIOA, EXTI_PinSource0);
EXTI_t.EXTI_Line = EXTI_Line0;
EXTI_t.EXTI_Mode = EXTI_Mode_Interrupt;
EXTI_t.EXTI_Trigger = EXTI_Trigger_Rising;
EXTI_t.EXTI_LineCmd = ENABLE;
EXTI_Init(&EXTI_t);
// enable EXTI0 interrupt for NVIC
NVIC_t.NVIC_IRQChannel = EXTI0_IRQn;
NVIC_t.NVIC_IRQChannelPreemptionPriority = 0;
NVIC_t.NVIC_IRQChannelSubPriority = 0;
NVIC_t.NVIC_IRQChannelCmd = ENABLE;
NVIC_Init(&NVIC_t);
gpioDIndex = 1;
uint16_t gpioDValue[4] = {GPIO_Pin_12, GPIO_Pin_13, GPIO_Pin_14, GPIO_Pin_15};
while(1)
{
GPIO_SetBits(GPIOD, gpioDValue[gpioDIndex]);
}
return 0;
}
�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

However, it seems the interrupt is never executed since the GPIOD[12:15] state is not changing.

What's wrong with my code on interrupt handling ?

Thank you in advance,

Simon

1 ACCEPTED SOLUTION

Accepted Solutions
Posted on October 30, 2017 at 17:52

Hi Simo,

It does not matter if the function EXTI0_IRQHandler is written in the file stm32f4xx_it.c you can call it from anywhere.

I just used a Standard Periph Library template file.

Moreover you will find this stm32f4xx_it.c and the associated .h in one of the examples of this library.

The function EXTI0_IRQHandler is called from the interrupt vector that has the same name.

All interrupt vectors are in the file startup_stm32f4xx.s (check if this file is include into the project)

I have three questions to ask you:

  1. Are you able to debug a simple toggle program. and you place a breakpoint? In this way you can validate the execution in debug mode.
  2. When to start the debugger, can you execute the code step by step?
  3. When you stop the debugger to which line of code this one stops?

Please check that your program does not stop on a Hard Fault which could signal that your EXTI0 interrupts are not properly called (startup_stm32f4xx.s missing)

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.

View solution in original post

23 REPLIES 23
RomainR.
ST Employee
Posted on October 30, 2017 at 14:14

Hello,

Your code seems correct (GPIOA configuration with EXTI0 and interrupt handler)

Did you tried to place a breakpoint at Line 14 ?

gpioDIndex++;

And see if execution stop here ?

Regards

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.

Posted on October 30, 2017 at 14:31

Is this in a .CPP file, or compiled with C++ syntax?

extern 'C' void EXTI0_IRQHandler(void)
{
...
}

Tips, Buy me a coffee, or three.. PayPal Venmo
Up vote any posts that you find helpful, it shows what's working..
simo zz
Senior
Posted on October 30, 2017 at 15:03

Hello everyone,

Thank you for your interest, I will reply in order.

Unfortunetly, due to an IDE's error (I am using openstm32), I cannot debug the code. I am trying to fix it.

This is a C code in a C file. I am not using C++.

the volatile keyword as no effects.

This is strange becasue this code I wrote a few years ago:

#include <stm32f4xx.h>unsigned char x;void EXTI0_IRQHandler(void){ /* EXTI->PR must be reset to 1 in order to clear the pending edge event flag FROM DATASHEET page 205 Pending register (EXTI_PR) 'This bit is set when the selected edge event arrives on the external interrupt line. This bit is cleared by writing a 1 to the bit or by changing the sensitivity of the edge detector.' */ if(EXTI->PR == EXTI_PR_PR0) EXTI->PR = EXTI_PR_PR0; x++; if(x > 3) x = 0;}void GPIO_config(void){ /* Reset GPIOD pheriperal */ RCC->AHB1RSTR = RCC_AHB1RSTR_GPIODRST | RCC_AHB1RSTR_GPIOARST; RCC->AHB1RSTR &= ~(RCC_AHB1RSTR_GPIODRST | RCC_AHB1RSTR_GPIOARST); /* GPIOD and GPIOA CLOCK ENABLE*/ RCC->AHB1ENR = RCC_AHB1ENR_GPIODEN | RCC_AHB1ENR_GPIOAEN; /* GPIOA:0 configuration */ /* Set GPIOA0 as input */ GPIOA->MODER |= 0x55555554; /* Set GPIOA0 as Open Drain and GPIOA[15:1] as PUSH PULL reset state */ GPIOA->OTYPER = (uint16_t) 0x0000; /* GPIOAx no pull-up or pull-down */ GPIOA->PUPDR = (uint32_t) 0x00000000; /* GPIOD Configuration */ /* Set GPIOD[12 ··· 15] as output */ GPIOD->MODER = GPIO_MODER_MODER12_0 | GPIO_MODER_MODER13_0 | GPIO_MODER_MODER14_0 | GPIO_MODER_MODER15_0; /* Set GPIOD[12 ··· 15] speed up to 25MHz */ GPIOD->OSPEEDR = GPIO_OSPEEDER_OSPEEDR12_0 | GPIO_OSPEEDER_OSPEEDR13_0 | GPIO_OSPEEDER_OSPEEDR14_0 | GPIO_OSPEEDER_OSPEEDR15_0; /* Set GPIODx as PUSH PULL reset state */ GPIOD->OTYPER = 0x0000; /* GPIOD no pull-up or pull-down */ GPIOD->PUPDR = 0x00000000;}void EXTI0_config(void){ /* Reset SYSCFG peripheral */ RCC->APB2RSTR |= RCC_APB2RSTR_SYSCFGRST; RCC->APB2RSTR &= ~(RCC_APB2RSTR_SYSCFGRST); /* Enable SYSCFG clock */ RCC->APB2ENR |= RCC_APB2ENR_SYSCFGEN; /* Configure external interrupt for PA0 */ SYSCFG->EXTICR[0] = 0xfff0; /* Enable Interrupt and event generation on line #0 */ EXTI->IMR |= EXTI_EMR_MR0; /* Enable rising edge detection on line #0 */ EXTI->RTSR |= EXTI_RTSR_TR0; /* CMSIS Functions */ /* Set EXTI0 to the lowest priority */ NVIC_SetPriority(EXTI0_IRQn, 0x0f); /* Enable EXTI0 Interrupt */ NVIC_EnableIRQ(EXTI0_IRQn);}void main(void){ /* 0x1000 -> PD12 -> LD4 Green ON 0x2000 -> PD13 -> LD3 Orange ON 0x4000 -> PD14 -> LD5 Red ON 0x8000 -> PD15 -> LD6 Blue ON */ uint16_t VALUE[4] = {0x1000, 0x2000, 0x4000, 0x8000}; GPIO_config(); EXTI0_config(); x = 0; while(1) { /* Set the GPIOXx bit */ GPIOD->ODR = VALUE[x]; }}�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?�?

works perfectly, but with STD_Peripheral_Libraries it doesn't..

Simon

simo zz
Senior
Posted on October 30, 2017 at 15:17

It seems the problem is related to using the STD_Peripheral_Libraries.

If I use the previous code (direct register assignment) using HAL Libraries includes, it works. It does not work using the STD_Peripheral_Libraries includes (as well as the code in the first message).

Posted on October 30, 2017 at 14:45

... and

volatile uint8_t gpioDIndex;
JW

Posted on October 30, 2017 at 15:24

You wrote:

Unfortunetly, due to an IDE's error (I am using openstm32), I cannot debug the code. I am trying to fix it.

What is error when you try to debug your code ?

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.

Posted on October 30, 2017 at 15:46

I use SPL inside my GPIOPin class. The calls I use match yours exactly. I trust the SPL much more that HAL.

I note that your PushPull settings are different. I have had problems in the past with NO_PULL on the inputs. I usually configure them to drive the line high or low depending on the sense on the input.
Posted on October 30, 2017 at 15:47

‌, the error is the following:

Could not determine GDB version using command: /opt/st/plugins/fr.ac6.mcu.externaltools.arm-none.linux64_1.0.201708311556/tools/compiler/bin/arm-none-eabi-gdb --version/opt/st/plugins/fr.ac6.mcu.externaltools.arm-none.linux64_1.0.201708311556/tools/compiler/bin/arm-none-eabi-gdb: error while loading shared libraries: libncurses.so.5: cannot open shared object file: No such file or directory�?�?

the installed arm-none-eabi-gdb cannot find libncurses.so.5.

However, libncurses.so.5 are installed (I am using openstm32 on Debian). I also asked for this error on openstm32 forum.

Simon

Posted on October 30, 2017 at 15:59

Have you sudo rights?

Try running

 ~>sudo ldconfig

in terminal without those chars that prefixes the sudo command.

Usually, I install the OpenSTM32 on the local home folder, and I remove the Eclipse that comes with the distro. I do the same with the gnu arm compiler.