STM32按钮中断

问题描述 投票:0回答:1

这是我的按钮的代码

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
}

它的问题是,每当我按下按钮时,我的计时器都不会暂停,它的行为是随机的,达到最大-最小,你永远不知道。永远不会真正停下来

尝试弄乱标志等,但无济于事

stm32 hardware bare-metal
1个回答
0
投票

这是实现这一目的的最后一段代码,在您浏览这段代码之前,我必须先说几件关键的事情。所有计算都从 IRQ 处理程序中删除,因为我的导师告诉我,在 IRQ 中执行任何逻辑都是不好的做法,因此它已移至 main,正如我将在有关按钮的其他问题上发布的答案中一样。我想就是这样。

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;

}
© www.soinside.com 2019 - 2024. All rights reserved.