我正在尝试使用 STM32C0x 参考手册切换 LED。 我已将 LED 连接到端口 A 引脚 0,将按钮连接到端口 A 引脚 1。电路是正确的,因为当我不使用中断但使用带有 if 语句的 while 循环时,LED 会成功切换。然而,在使用中断时,按下按钮不会执行任何操作。
void enablePinGPIOPortA(unsigned short pin , short isInput);
void enableInterrupt(void);
int main(void){
enablePinGPIOPortA(0 , 0);
enablePinGPIOPortA(1 , 1);
enableInterrupt();
while(1);
}
void enablePinGPIOPortA(unsigned short pin , short isInput){
RCC->IOPENR |= RCC_IOPENR_GPIOAEN;
//reset the pin
GPIOA->MODER &= ~(0b11 << 2*pin);
if(!isInput){
GPIOA->MODER |= 0b01 << 2*pin;
}else{
//select pull down for input
GPIOA->PUPDR |= (0b10 << (2*pin));
}
}
void enableInterrupt(){
RCC->APBENR2 |= 1;
EXTI->EXTICR[1] |= 0b00;
EXTI->RTSR1 |= 0x2;
EXTI->IMR1 |= (1 << 1);
NVIC_EnableIRQ(EXTI0_1_IRQn);
RCC->APBENR2 &= ~(1);
}
void EXTI0_1_IRQHandler(void){
GPIOA->ODR ^= 1;
EXTI->RPR1 &= ~(1 << 1);
}
我认为
enableGPIOA
功能是正确的,因为它可以不间断地工作。但是我不确定 enableInterrupt
功能。
我正在使用模拟器https://wokwi.com/projects/new/st-nucleo-c031c6
EXTI_RPR1
位通过写入 1 来清除。所以:
EXTI->RPR1 &= ~(1 << 1);
应该是
EXTI->RPR1 != (1 << 1) ;
EXTI->EXTICR[1] |= 0b00;
是不正确的(尽管在这种情况下可能不会导致您的问题)。与零进行“或”运算没有效果。该寄存器中的任何内容都将保留在该寄存器中。它的重置值为零,因此在其他地方没有任何其他写入的情况下,这就是它将包含的内容。然而,这是试图在错误的寄存器中设置错误的位。这是对 EXTI_EXTCR1 的写入,EXTI_EXTCR1 是 EXTI4 到 EXIT7 的控制寄存器,而您的输入位于 PORTA.1 上,因此您需要 EXTI1。要为 PORTA.1 启用 EXTI1:
EXTI->EXTICR[0] &= ~0xFFFF00FF ;
尽管如此,由于重置状态在任何情况下都为零,因此只有在之前在其他地方用其他值写入时才会产生任何影响。