STM32 GPIO中断使用IDR寄存器

STM32 GPIO Interrupt using IDR register

    /* Configure EXTI interupt PB4 */
    SYSCFG->EXTICR[0] &= ~SYSCFG_EXTICR2_EXTI4_PB; 
    EXTI->IMR |= EXTI_IMR_IM4;                                                                          //Interrupt Mask on line 2  */
    EXTI->RTSR |= EXTI_RTSR_RT4;                                                                        
    EXTI->FTSR |= EXTI_FTSR_FT4;                                                                        
    NVIC_EnableIRQ(EXTI4_15_IRQn);                                                                          //Załączenie przerwania na pinie zasilania
    NVIC_SetPriority(EXTI4_15_IRQn,1); 

这就是我配置 EXTI 的方式

    GPIOB->MODER =      (0U << GPIO_MODER_MODE4_Pos);
    GPIOB->PUPDR =      (1U << GPIO_PUPDR_PUPD4_Pos);

这就是我管理引脚的方式

    while(1)
    {
        if(state == 0){
            ServoToggle(0, 100, 255);
            delay(1000);
        } else {
            ServoToggle(0, 115, 255);
            delay(1000);
            ServoToggle(0, 60, 255);
            delay(1000);
        }
        delay(1);
    }

这是我的程序在站立后所做的

void EXTI4_15_IRQHandler(void)
{
    if(!(GPIOB->IDR & GPIO_IDR_ID4)){
        state = 0;
    } else {
        state = 1;
    } 
    EXTI->PR = EXTI_PR_PR4;
}

这就是我尝试处理中断的方式。

而且这个东西不起作用。我不知道为什么,但对于 PA0,它就像一个魅力,但改变到 PB4 停止弹出中断事件。

我有一个按钮连接到更改 press 上的 IDR 寄存器的引脚。

我错过了什么?

我正在使用 STM32L052 系列

从 4 到 15 的 EXTI IRQ 很少见。也许您可以添加您正在使用的 exakt 控制器?

例如,在 STM32F415 上,IRQ 处理程序为 EXTI4_IRQHandler

对于 PA0,我相信它必须与这一行有关:

SYSCFG->EXTICR[0] &= ~SYSCFG_EXTICR2_EXTI4_PB;

根据参考手册,PB[x](其中 x 为 4)映射到 SYSCFG_EXTICR2 的位 0-3。所以在你的情况下应该是:

SYSCFG->EXTICR[2] &= ~SYSCFG_EXTICR2_EXTI4;
SYSCFG->EXTICR[2] |= SYSCFG_EXTICR2_EXTI4_PB;

PA0 映射到 SYSCFG->EXTICR[0]。 SYSCFG->EXTICR[0] &= ~SYSCFG_EXTICR2_EXTI4_PB; 表示 AND SYSCFG->EXTICR[0] 的内容与 SYSCFG_EXTICR2_EXTI4_PB 的倒数 这是 0xFE。假设 SYSCFG->EXTICR[0] 全部为零,那么您实际上只是 AND 一堆零,因此 PA0 起作用的原因。

我注意到的另一件事是,在您的中断处理程序中,我会检查外部中断处理程序标志而不是 GPIO IDR 寄存器来检查按钮是否被按下。根据我对问题的理解,您想按下按钮来切换变量 state。按下按钮会触发中断,因此您通过检查 IDR 寄存器 anyways.In EXTI 中断处理程序来破坏目的,您通过未决 Register/PR 检查它是否是正确的中断。其他 EXTI 中断看起来它们共享相同的处理程序,因此您可能希望使用 EXTR->PR 寄存器来检查正确的挂起位。

这里有一些STM32F407代码作为例子:

#define PORTD_ALL 0x0000F000
void EXTI0_IRQHandler(void){

  // Check for EXTI 0 flag
  if((EXTI->PR & EXTI_PR_PR0) == EXTI_PR_PR0){

    // Toggle all LED on board
    GPIOD->ODR ^= PORTD_ALL;

    // Clear interupt pending request
    EXTI->PR = EXTI_PR_PR0;
  }
}

每次我按下按钮时,它都会切换板上的 LED

对于state变量使用异或运算。这非常有用。

为了回答这个问题,我使用了 STM32L052 参考手册和来自 ST 网站的 STM32L052.h 文件。就找STM32CubeL0下载