Search code examples
carmembeddedstm32bare-metal

STM32F401 Issue with interrupt request


I have a nucleo board, and on it I have a button. The button is connected to the pin C13 and upon pressing it, I am supposed to stop my PWM signal from progressing. Can anyone point me in the right direction?

Here is the code for defining the interrupt and its behaviour.

void INTERRUPT_CONFIG(){

    RCC->APB2ENR|=RCC_APB2ENR_SYSCFGEN;
    SYSCFG->EXTICR[2]|=(0x2<<SYSCFG_EXTICR1_EXTI1_Pos);
    EXTI->IMR|=(0x1<<EXTI_IMR_MR1_Pos);
    EXTI->RTSR|=(0x1<<EXTI_RTSR_TR13_Pos);
    EXTI->FTSR|=(0x0<<EXTI_FTSR_TR13_Pos);
    NVIC_SetPriority(EXTI1_IRQn,1);
    NVIC_EnableIRQ(EXTI1_IRQn);


}
bool flag=false;
void EXTI1_IRQHandler(){
    if(EXTI->PR & EXTI_PR_PR13_Pos){
        EXTI->PR|=(0x0<<EXTI_PR_PR13_Pos);
        flag=!flag;
    }
}

... and here is the main function:

int main(void)
{
  TIM2_INIT();
  //button is pc13
  INTERRUPT_CONFIG();
     EXTI1_IRQHandler();
  RCC->AHB1ENR |= RCC_AHB1ENR_GPIOCEN;
    GPIOC->MODER |= ( 0x0 << GPIO_MODER_MODE13_Pos);
    GPIOC->PUPDR |= ( 0x1 << GPIO_PUPDR_PUPD13_Pos);//defining the Pin c13

  while (1)
  {
      if(flag==true){
          TIM2->CR1&=~(TIM_CR1_CEN);
      }
      else{
      int x;
          for(x=0; x<500; x=x+1)
          {
            TIM2->CCR1=x;
            delayFunct(1);
          }
          for(x=500; x>0; x=x-1)
          {
              TIM2->CCR1=x;
              delayFunct(1);
  }
}

I know the question is a bit verbose, but still would appreciate some help. Thank you guys in advance.

So far I have messed with the contents of the EXTI register values, but to no avail


Solution

  • To preface this, some of the things have been changed rather extensively due to my mentors advice, such as the logic in the IRQ, usage of unions, hope you can still understand the code

    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;
    
    }
    

    and now for the new contents of the main function, the definition of the functions is the same, it's just the while loop that has changed; while (1) {

      int x;
          for(x=0; x<500; x++)
          {
              if(flag.bits_access.flag== 1){
                        x=x-1;
                        TIM2->CCR1=x;
                  }
              else{
                        TIM2->CCR1=x;
                        delayTRIP(1);
              }}
    
          for(x=500; x>0; x--)
          {
              if(flag.bits_access.flag== 1){
                          x=x+1;
                          TIM2->CCR1=x;
                              }
              else{
                          TIM2->CCR1=x;
                          delayTRIP(1);
          }
    
      }
     }}