簡體   English   中英

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 會停止彈出中斷事件。

我有一個按鈕連接到在按下時更改 IDR 寄存器的引腳。

我錯過了什么?

我正在使用 STM32L052 系列

4-15 的 EXTI IRQ 非常罕見。 也許您可以添加您正在使用的 exakt 控制器?

例如,在EXTI4_IRQHandler上,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 寄存器來破壞目的。在 EXTI 中斷處理程序中,您可以通過掛起寄存器/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變量使用 XOR 運算。 這是非常有用的。

為了回答這個問題,我使用了 STM32L052 參考手冊和 ST 網站上的 STM32L052.h 文件。 只需尋找 STM32CubeL0 下載

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM