2017-10-30 05:38 AM
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
Solved! Go to Solution.
2017-10-30 10:52 AM
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:
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.
2017-10-30 06:14 AM
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.
2017-10-30 06:31 AM
Is this in a .CPP file, or compiled with C++ syntax?
extern 'C' void EXTI0_IRQHandler(void)
{
...
}
2017-10-30 07:03 AM
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
2017-10-30 07:17 AM
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).
2017-10-30 07:45 AM
... and
volatile uint8_t gpioDIndex;
JW
2017-10-30 08:24 AM
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.
2017-10-30 08:46 AM
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.2017-10-30 08:47 AM
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
2017-10-30 08:59 AM
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.