[英]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);
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.