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下载
/* 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下载