cstm32

STM32 pushbutton interrupt


So here's the code for my pushbutton

void PB_Init(void){
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN;
    GPIOC->MODER |= ( 0x0 << GPIO_MODER_MODE13_Pos);
    GPIOC->PUPDR |= ( 0x1 << GPIO_PUPDR_PUPD13_Pos);
}

void EXTI15_10_Init(void){
    PB_Init(); // Initialize PC13 as input.

    RCC->APB2ENR |= (1<<14);      // Enable System configuration controller
    SYSCFG->EXTICR[3] &= ~(1<<7); // Select Port C as source, EXTIx = 0b0010
    SYSCFG->EXTICR[3] &= ~(1<<6); // Select Port C as source, EXTIx = 0b0010
    SYSCFG->EXTICR[3] |= (1<<5);  // Select Port C as source, EXTIx = 0b0010
    SYSCFG->EXTICR[3] &= ~(1<<4); // Select Port C as source, EXTIx = 0b0010
    EXTI->IMR |= (1<<13);         // Disable interrupt request mask on EXTI line 13
    EXTI->FTSR |= (1<<13);        // Enable EXTI on Falling edge
    EXTI->RTSR &= ~(1<<13);       // Disable EXTI on Rising edge
    RCC->APB2ENR &= ~(1<<14);     // Disable System configuration controller
}
volatile bool flag=0;
void EXTI15_10_IRQHandler(void){
    if(flag==0){
    TIM2->CR1|=TIM_CR1_CEN;
    flag=!flag;
    EXTI->PR |= (1<<13);  // Clear PR to re-enable EXTI interrupt

    }else{
        TIM2->CR1&=~TIM_CR1_CEN;
        flag=!flag;
        EXTI->PR |= (1<<13);  // Clear PR to re-enable EXTI interrupt
    }

}


void Interrupt_Init(void){
    EXTI15_10_Init(); // Step 1, this is defined elsewhere
    NVIC->IP[EXTI15_10_IRQn] =  (1 << 4);    // Step 3: Set priority to 1
    NVIC->ISER[40 >> 5] |= (1 << (40 % 32)); // Step 4: Enable interrupt
}

The issue with it is that whenever I push the button, my timer doesnt pause, it behaves randomly, goes to maximum-minimum, you never know. Never truly pauses

Tried messing with the flags and such, but to no avail


Solution

  • Here's the final piece of code that did the trick, there are a couple of key things I must say before you go through this code. All of the computation was REMOVED from the IRQ handler because my mentor told me it's bad practice to do ANY logic in the IRQ, so it has been moved to main as in the answer i will post about on my other question about a push button. I think that is it.

    void PB_Init(void){
    RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN;
    GPIOC->MODER |= ( 0x0 << GPIO_MODER_MODE13_Pos);
    GPIOC->PUPDR |= ( 0x1 << GPIO_PUPDR_PUPD13_Pos);}
    
    void EXTI15_10_Init(void){
    PB_Init(); // Initialize PC13 as input.
    
    RCC->APB2ENR |= (1<<14);      // Enable System configuration controller
    SYSCFG->EXTICR[3] &= ~(1<<7); // Select Port C as source, EXTIx = 0b0010
    SYSCFG->EXTICR[3] &= ~(1<<6); // Select Port C as source, EXTIx = 0b0010
    SYSCFG->EXTICR[3] |= (1<<5);  // Select Port C as source, EXTIx = 0b0010
    SYSCFG->EXTICR[3] &= ~(1<<4); // Select Port C as source, EXTIx = 0b0010
    EXTI->IMR |= (1<<13);         // Disable interrupt request mask on EXTI 
    EXTI->FTSR |= (1<<13);        // Enable EXTI on Falling edge
    EXTI->RTSR &= ~(1<<13);       // Disable EXTI on Rising edge
    }
    
    
    void Interrupt_Init(void){
    EXTI15_10_Init(); 
    NVIC->IP[EXTI15_10_IRQn] =  (1 << 4);    
    NVIC->ISER[40 >> 5] |= (1 << (40 % 32)); 
    }
    
    union InterruptFlag {
    struct {
       volatile bool flag: 1; // Just one bit for our flag
       volatile bool press: 1;
    } bits_access;
    uint32_t reg; // We'll use this for byte access
    };
    volatile union InterruptFlag flag = { .bits_access.flag = 0 }; // 
    Initialize to 0
    volatile uint16_t pressTime;
    volatile bool lastButtonPress=0;
    volatile bool buttonPress=1;
    
    void EXTI15_10_IRQHandler(void){
    flag.bits_access.flag = !flag.bits_access.flag;
    EXTI->PR |= (1<<13);  // Clear PR to re-enable EXTI interrupt
    
    }
    
    void clearIR(void){
    flag.bits_access.flag = 0;
    buttonPress=0;
    
    }