1

I'm trying to toggle an LED at PC13 by toggling PC14, the problem is that the interrupt handler is kept being called without toggling PC14 and the the pending interrupt is not cleared using EXTI->PR register, nor cleared manually using the debugger. I tried also clearing it in NVIC->ICPR, I'm not sure why there are two registers for clearing the same interrupt.
here is my code
and you can find the header in https://github.com/AymenSekhri/tinyHAL-STM32f103/tree/master/STM32F103-HAL/tinyHAL

/* 
* Description:
*   Toggle LED at C13 whenever C14 goes from HIGH to LOW.
*
*/
#include "tinyHAL/stm32f103_hal.h"
int main(){
    //Enable AFIO clock from RCC
    enablePeripheralClock(Peripheral_AFIO);
    //Enable and configure C13 & C14
    enablePeripheralClock(Peripheral_GPIOC);
    configureGPIO(Peripheral_GPIOC, 13, GPIO_MODE_OUT_50MHZ, GPIO_CONF_OUT_PUSHPULL);
    configureGPIO(Peripheral_GPIOC, 14, GPIO_MODE_IN, GPIO_CONF_IN_PUSHUP_PULLDOWN);

    //Link EXTI14 to C14
    AFIO->EXTICR[3] = (AFIO->EXTICR[3] & ~(0xF<<8)) | 2;
    //Configure inturrput at EXTI14 falling edge
    EXTI->FTSR      |= 1<<14;
    //Unmask interrupt 40 (EXTI10-15)
    EXTI->IMR       |= 1<<14;
    //Set Priority to interrupt 40 (EXTI10-15)
    NVIC->IP[40]    |= 0x10;

    //Enable interrupt 40 (EXTI10-15)
    NVIC->ISER[40>>5] |= (1 << (40&0x1F));
    while(1);
}

void EXTI15_10_IRQHandler(void){
    toggleGPIOBit(Peripheral_GPIOC, 13);
    if (EXTI->PR & (1 << 14)){
        EXTI->PR |= (1 << 14);
    }
    //NVIC->ICPR[40>>5] |= (1 << (40&0x1F));
    __COMPILER_BARRIER();
}
0xDEADC0DE
  • 323
  • 3
  • 12
  • search for "debouncing". Generally speaking using EXTI ints for buttond is a bad idea. – 0___________ Apr 30 '20 at 22:49
  • that doesn't explain why ISR is being called even though the input is fixed in HIGH or LOW, does it ? – 0xDEADC0DE Apr 30 '20 at 23:57
  • I do not answer the question. – 0___________ May 01 '20 at 00:21
  • 2
    As a quick comment, I just had exactly the same problem. It turns out that the problem was that I didn't activate the clock of the SYSCFG component, which made the request be re-activated almost immediately. It had nothing to do with electrical noise because the STM32 Nucleo Board's user button has resistors and a capacitor connected to fix this. – DCTLib Dec 01 '20 at 22:44

3 Answers3

1

As @P__J__ suggest add some denouncing logic. There are two methods for de-bouncing like suing RC filter and using software de-bouncing logic. Due to noise on the pins ISR is getting executed continously. You can check one more thing. Try pulling UP/Down the pin and observe the behaviour. ISR should not get executed if logic level doesn't change on Pin.

dev_eng
  • 126
  • 1
  • 12
  • I tried pulling the input down , and the ISR is still over-triggered. – 0xDEADC0DE May 01 '20 at 10:07
  • 1
    This might be due to electronic properties of the way you are "pulling the input down", which I'm not an expert for, sadly. But some wild guesses from my side: If you have only activated the build-in pull-down (instead of soldering one to your PCB in the short time since I wrote my answer, and instead of getting a new PCB layout :-] ), then note that this is called "weak" pull-down, even by STM documentation. Depending on what happens on the pin - could the pull-down be just too weak? ... Well, please try to fix the electronics (maybe using help form electronics board). I think this'll help. – HelpingHand May 01 '20 at 10:17
1

The best solution to get rid of the electronic noise at the pin that (over-)triggers your EXTI is to improve the hardware - but this is the software board, not the electronic one.

If you had a TIM channel connected to that pin, I would recommend to use it to filter the signal coming in. But I think that PC14 doesn't have a timer.

The second-best solution (and this is where workarounds have already started!) is to use a timer (the TIM, not its channel), either to establish a periodic time base to sample the pin (by DMA or by an ISR, and feed samples into a software-based filtering...) - or to deactivate the EXTI interrupt in the EXTI ISR, start the timer and re-activate the EXTI interrupt when the timer expired.

Both of these µC-based approaches are clumsy and clearly inferior to developing a good hardware. This doesn't say that with a "good" hardware you shouldn't add some debouncing or noise protection inside your software!

HelpingHand
  • 1,294
  • 11
  • 27
  • I tried pulling the input down, so the logic level is not changed, and the ISR is still over-triggered. do you think it's really from the debouncing noise ?. I'll try the using the timer to sample the input. – 0xDEADC0DE May 01 '20 at 10:10
  • 1
    I overlooked your comment to this answer when I commented to the other answer earlier today. As I said, if you were only using the "weak pull-down" resistor implemented in STM32 controllers then I'm not sure whether this is enough to stabilize your electronic pin potential - but I'm not an expert for this, and you should ask some electronics guys (or [their SE](https://electronics.stackexchange.com/)). – HelpingHand May 01 '20 at 12:33
  • i used "weak pull-down" indeed, i'll check them out. Thanks. – 0xDEADC0DE May 01 '20 at 12:46
  • 1
    I just checked for one STM32 (not yours) the strength of internal pull-downs, which is 25/40/55 kOhm (Min/Typ/Max). If you have the opportunity to (solder?) add an external pull-down (of lower resistance than the internal one, say 10kOhm?), I'd consider that. – HelpingHand May 01 '20 at 13:03
0

Maybe It's because of TAMPER/RTC second output redirected to PC13. I also faced the same problem before when using PC13 as EXTI. Set BKP_RTCCR->ASOE to 1 to force it as alarm output that will never triggered because i dont't set any rtc alarm.

Alon Eitan
  • 11,997
  • 8
  • 49
  • 58
murekh
  • 1
  • 1