cancel
Showing results for 
Search instead for 
Did you mean: 

STM32L4 EXTERNAL INTERRUPT

semed abubakar
Associate II
Posted on January 30, 2018 at 15:53

hello friends i recently got an stm32l4 I just go past the led blink i am trying my hands on interrupts I am trying to configure  a falling edge triggered interrupt on A0 and PC15 so far works fine for GPIOA but the interrupt for GPIOC15 

is not working 

I have enabled pull up on the pin but when i drive it low it doesnt trigger the interrupt during the debug i know cause the counter in the ISR is not incrementing

does anyone know why my c code is below i am using keil ide thank you

#include 'stm32l433xx.h'

extern int cnt,j;

void EXTI0_IRQHandler(void)

{

if (!(GPIOA->IDR & (1<<0)) )

{

if(!(cnt%2))

GPIOC->ODR =~(1<<4);

else

GPIOC->ODR|= (1<<4);

cnt++;

}

//Clear the EXTI pending bits

NVIC_ClearPendingIRQ(EXTI3_IRQn);

EXTI->PR1 |=(1<<0);

}

void EXTI15_IRQHandler(void)

{

j++;

NVIC_ClearPendingIRQ(EXTI15_10_IRQn); //Clear the EXTI pending bits

EXTI->PR1 |=(1<<15);

}

void Config_IO(void)

{

RCC->AHB2ENR |= RCC_AHB2ENR_GPIOBEN;

RCC->AHB2ENR |= RCC_AHB2ENR_GPIOCEN;

RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN;

GPIOA->MODER &=~(1<<0); //input mode for A0

GPIOA->MODER &=~(1<<1);

GPIOA->PUPDR |= (1<<0); //pull up on A0

GPIOA->PUPDR &=~(1<<1);

GPIOA->OSPEEDR |=(1<<0); //input mode for A0

GPIOA->OSPEEDR |=(1<<1);

GPIOA ->OTYPER &=~(1<<0);

GPIOB ->MODER &= ~(GPIO_MODER_MODER13_0); // set GPIO 13 as general purpose input

GPIOB ->MODER &= ~(GPIO_MODER_MODER13_1);

GPIOB ->PUPDR &= ~(1<<27); //10000000000 Pull up RB13

GPIOB ->PUPDR |= (1<<26);

GPIOC ->MODER |= GPIO_MODER_MODE12_0; ///set GPIO13 as general output

GPIOC ->MODER &= ~(GPIO_MODER_MODE12_1);

GPIOC ->OTYPER &= ~(GPIO_OTYPER_OT_12); ///push pull output type for GPIOC12

GPIOC ->OSPEEDR |= (GPIO_OSPEEDER_OSPEEDR12_0); // high speed for GPPIOC12

GPIOC ->OSPEEDR |= (GPIO_OSPEEDER_OSPEEDR12_1);

GPIOC ->PUPDR &= ~(GPIO_PUPDR_PUPDR12); //NO PULL UP*/

GPIOC ->MODER |= (1<<8); //PC4 output mode

GPIOC ->MODER &= ~(1<<9);

GPIOC ->OTYPER |= (1<<4); //open drain on PC4

GPIOC ->OSPEEDR |= (1<<8); //PC4 high speed

GPIOC ->OSPEEDR |= (1<<9);

GPIOC ->PUPDR &=~(0<<8);

GPIOC ->PUPDR &=~(0<<9);

GPIOB->MODER &=~(1<<30); //input mode for B15

GPIOB->MODER &=~(1<<31);

GPIOB ->PUPDR &= ~(1<<31); //10000000000 Pull up B15

GPIOB ->PUPDR |= (1<<30);

GPIOB ->OTYPER &= ~(1<<15); ///push pull output type for GPIOB15

GPIOB ->OSPEEDR &= ~ (1<<30); //PB15 high speed

GPIOB ->OSPEEDR |= (1<<31);

}

void Config_Interrupt(void)

{

SYSCFG->EXTICR[0] &= SYSCFG_EXTICR1_EXTI0_PA;

SYSCFG->EXTICR[3] = SYSCFG_EXTICR4_EXTI15_PB ;

EXTI->IMR1 |= (1<<0);

EXTI->IMR1 |= (1<<15);

EXTI->EMR1 |=(1<<0); //interrupt source is unmaskrd

EXTI->EMR1 |=(1<<15); //Unmask interrupt line 15

EXTI->FTSR1 |= (1<<0); //falling edge line 1

EXTI->FTSR1 |= (1<<15); //falling edge line 15

__enable_irq(); //enable interrupt

NVIC_SetPriority(EXTI0_IRQn,4); //Set priority

NVIC_SetPriority(EXTI15_10_IRQn,4);

NVIC_ClearPendingIRQ(EXTI0_IRQn); //clear pending

NVIC_ClearPendingIRQ(EXTI15_10_IRQn);

NVIC_EnableIRQ(EXTI0_IRQn); ///enable interrupt

NVIC_EnableIRQ(EXTI15_10_IRQn);

}

void Config_IO(void);

void Config_Interrupt(void);

int cnt,i,j;

int main()

{

Config_IO();

Config_Interrupt();

while (1)

{

GPIOC->ODR|= (1<<12);

for(i=0;i<100;i++);

GPIOC->ODR&= ~(1<<12);

for(i=0;i<100;i++);

}

return 0;

}
1 ACCEPTED SOLUTION

Accepted Solutions
Posted on January 30, 2018 at 17:14

void EXTI15_10_IRQHandler(void)

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..

View solution in original post

5 REPLIES 5
Posted on January 30, 2018 at 17:14

void EXTI15_10_IRQHandler(void)

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
semed abubakar
Associate II
Posted on January 30, 2018 at 18:03

Thank you waclawek i  i modified the code like you suggested i have changed the IRQ handler to 

void EXTI15

_10_

IRQHandler(void)

  and i set  

RCC_APB2ENR.SYSCFGEN in my config_io fucntion line 40

the interrupt is still not triggering i tried another pin PB3 but so far thats not working either  the code looks like this now

#include 'stm32l433xx.h'

extern int cnt,j;

void EXTI0_IRQHandler(void)

{

if (!(GPIOA->IDR & (1<<0)) )

{

if(!(cnt%2))

GPIOC->ODR =~(1<<4);

else

GPIOC->ODR|= (1<<4);

cnt++;

}

//Clear the EXTI pending bits

NVIC_ClearPendingIRQ(EXTI3_IRQn);

EXTI->PR1 |=(1<<0);

}

void EXTI15_10_IRQHandler(void)

{

cnt++;

j++;

NVIC_ClearPendingIRQ(EXTI15_10_IRQn); //Clear the EXTI pending bits

EXTI->PR1 |=(1<<15);

}

void EXTI1_IRQHandler(void)

{ cnt++;

j++;

NVIC_ClearPendingIRQ(EXTI1_IRQn); //Clear the EXTI pending bits

EXTI->PR1 |=(1<<3);

}

void Config_IO(void)

{

RCC->APB2ENR |=(1<<0);                     //SYSCFG ENABLE

RCC->AHB2ENR |= RCC_AHB2ENR_GPIOBEN;

RCC->AHB2ENR |= RCC_AHB2ENR_GPIOCEN;

RCC->AHB2ENR |= RCC_AHB2ENR_GPIOAEN;

GPIOA->MODER &=~(1<<0); //input mode for A0

GPIOA->MODER &=~(1<<1);

GPIOA->PUPDR |= (1<<0); //pull up on A0

GPIOA->PUPDR &=~(1<<1);

GPIOA->OSPEEDR |=(1<<0); //input mode for A0

GPIOA->OSPEEDR |=(1<<1);

GPIOA ->OTYPER &=~(1<<0);

GPIOB ->MODER &= ~(GPIO_MODER_MODER13_0); // set GPIO 13 as general purpose input

GPIOB ->MODER &= ~(GPIO_MODER_MODER13_1);

GPIOB ->PUPDR &= ~(1<<27); //10000000000 Pull up RB13

GPIOB ->PUPDR |= (1<<26);

GPIOC ->MODER |= GPIO_MODER_MODE12_0; ///set GPIO13 as general output

GPIOC ->MODER &= ~(GPIO_MODER_MODE12_1);

GPIOC ->OTYPER &= ~(GPIO_OTYPER_OT_12); ///push pull output type for GPIOC12

GPIOC ->OSPEEDR |= (GPIO_OSPEEDER_OSPEEDR12_0); // high speed for GPPIOC12

GPIOC ->OSPEEDR |= (GPIO_OSPEEDER_OSPEEDR12_1);

GPIOC ->PUPDR &= ~(GPIO_PUPDR_PUPDR12); //NO PULL UP*/

GPIOC ->MODER |= (1<<8); //PC4 output mode

GPIOC ->MODER &= ~(1<<9);

GPIOC ->OTYPER |= (1<<4); //open drain on PC4

GPIOC ->OSPEEDR |= (1<<8); //PC4 high speed

GPIOC ->OSPEEDR |= (1<<9);

GPIOC ->PUPDR &=~(0<<8);

GPIOC ->PUPDR &=~(0<<9);

GPIOB->MODER &=~(1<<30); //input mode for B15

GPIOB->MODER &=~(1<<31);

GPIOB ->PUPDR &= ~(1<<31); //10000000000 Pull up B15

GPIOB ->PUPDR |= (1<<30);

GPIOB ->OTYPER &= ~(1<<15); ///push pull output type for GPIOB15

GPIOB ->OSPEEDR |= (1<<30); //PB15 high speed

GPIOB ->OSPEEDR |= (1<<31);

GPIOB->MODER &=~(1<<6); //input mode for B3

GPIOB->MODER &=~(1<<7);

GPIOB ->PUPDR &= ~(1<<7); //10000000000 Pull up B3

GPIOB ->PUPDR |= (1<<6);

GPIOB ->OTYPER &= ~(1<<3); ///push pull output type for GPIOB3

GPIOB ->OSPEEDR |= (1<<6); //PB15 high speed

GPIOB ->OSPEEDR |= (1<<7);

}

void Config_Interrupt(void)

{

SYSCFG->EXTICR[0] &= SYSCFG_EXTICR1_EXTI0_PA;

SYSCFG->EXTICR[1] = SYSCFG_EXTICR4_EXTI15_PB ;

SYSCFG->EXTICR[1] = SYSCFG_EXTICR1_EXTI1_PB ;

EXTI->IMR1 |= (1<<0);

EXTI->IMR1 |= (1<<15);

EXTI->IMR1 |= (1<<3);

EXTI->EMR1 |=(1<<0); //interrupt source is unmaskrd

EXTI->EMR1 |=(1<<15); //Unmask interrupt line 15

EXTI->EMR1 |=(1<<3);

EXTI->FTSR1 |= (1<<0); //falling edge line 1

EXTI->FTSR1 |= (1<<15); //falling edge line 15

EXTI->FTSR1 |= (1<<3);

__enable_irq(); //enable interrupt

NVIC_SetPriority(EXTI0_IRQn,4); //Set priority

NVIC_SetPriority(EXTI15_10_IRQn,4);

NVIC_SetPriority(EXTI1_IRQn,4);

NVIC_ClearPendingIRQ(EXTI0_IRQn); //clear pending

NVIC_ClearPendingIRQ(EXTI15_10_IRQn);

NVIC_ClearPendingIRQ(EXTI1_IRQn);

NVIC_EnableIRQ(EXTI0_IRQn); ///enable interrupt

NVIC_EnableIRQ(EXTI15_10_IRQn);

NVIC_EnableIRQ(EXTI3_IRQn);

}

#include 'stm32l433xx.h'

extern int cnt,j;

void EXTI0_IRQHandler(void)

{

if (!(GPIOA->IDR & (1<<0)) )

{

if(!(cnt%2))

GPIOC->ODR =~(1<<4);

else

GPIOC->ODR|= (1<<4);

cnt++;

}

//Clear the EXTI pending bits

NVIC_ClearPendingIRQ(EXTI3_IRQn);

EXTI->PR1 |=(1<<0);

}

void EXTI15_10_IRQHandler(void)

{

cnt++;

j++;

NVIC_ClearPendingIRQ(EXTI15_10_IRQn); //Clear the EXTI pending bits

EXTI->PR1 |=(1<<15);

}

void EXTI1_IRQHandler(void)

{ cnt++;

j++;

NVIC_ClearPendingIRQ(EXTI1_IRQn); //Clear the EXTI pending bits

EXTI->PR1 |=(1<<3);

}

#include 'stm32l433xx.h'

void Config_IO(void);

void Config_Interrupt(void);

int cnt,i,j;

int main()

{

Config_IO();

Config_Interrupt();

while (1)

{

GPIOC->ODR|= (1<<12);

for(i=0;i<100;i++);

GPIOC->ODR&= ~(1<<12);

for(i=0;i<100;i++);

}

return 0;

}
Posted on January 30, 2018 at 17:25

and set RCC_APB2ENR.SYSCFGEN

Posted on January 31, 2018 at 10:24

Read back the SYSCFG and GPIO registers and check if they contain what you expect.

Look at the actual vector table (in binary, or better in disassembled binary) if the address at expected position points to the actual interrupt routine.

JW

henry.dick
Senior II
Posted on January 31, 2018 at 12:11

the flow looks generally right. two suggestions:

1) simplify your code to a minimalist framework. 

2) be consistent: if you are using pin13 as the exti, program your code so it consistently use that pin. I typically define a mask and use that mask throughout my code so if I want to move to a different pin, I can. your code has tons of hard-coded numbers that are inconsistent from one place to another, making it hard to track.