STM32外部中断仅在调试模式下响应

问题描述 投票:0回答:4

我的 STM32F103C8T6 微控制器有问题。我正在使用(作为练习)外部中断来打开/关闭 LED,方法是按下外部开关,该开关又连接到 PC13。我正在使用 StdPeriph 库。

芯片编程后,没有任何反应。相反,当我使用调试器(在Coocox中调试)时,芯片工作正常。我不知道问题出在哪里。

你能帮我吗?

这是我的代码:

#include<stm32f10x.h>
#include<stm32f10x_rcc.h>
#include<stm32f10x_gpio.h>

#include<stm32f10x_exti.h>
#include<misc.h>

typedef enum{
    on,
    off
}state;
state led=on;

int main(void){

    // enable clocks
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);

    // uncomment to disable/remap JTAG pins
    GPIO_PinRemapConfig(GPIO_Remap_SWJ_NoJTRST,ENABLE);
    GPIO_PinRemapConfig(GPIO_Remap_SWJ_JTAGDisable,ENABLE);

    // configure PC13 as input
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_13;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_2MHz;
    GPIO_Init(GPIOC,&GPIO_InitStructure);

    // configure PB8 as led output
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_8;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_2MHz;
    GPIO_Init(GPIOB,&GPIO_InitStructure);

    // connect PC13 to EXTI controller
    GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource13);

    // enable and configure EXTI controller
    EXTI_InitTypeDef EXTI_InitStructure;
    EXTI_InitStructure.EXTI_Line=EXTI_Line13;
    EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
    EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
    EXTI_InitStructure.EXTI_LineCmd=ENABLE;
    EXTI_Init(&EXTI_InitStructure);

    // enable IRQ
    NVIC_EnableIRQ(EXTI15_10_IRQn);
    NVIC_SetPriorityGrouping(NVIC_PriorityGroup_2);

    // Configure NVIC
    NVIC_InitTypeDef NVIC_InitStructure;
    NVIC_InitStructure.NVIC_IRQChannel=EXTI15_10_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=2;
    NVIC_InitStructure.NVIC_IRQChannelSubPriority=2;
    NVIC_Init(&NVIC_InitStructure);

    // switch on led
    GPIO_WriteBit(GPIOB,GPIO_Pin_8,Bit_SET);
    
    while(1);

    return 0;
}

void EXTI15_10_IRQHandler(void){

    // clear pending bit
    if(EXTI_GetITStatus(EXTI_Line13)!=RESET){
        EXTI_ClearITPendingBit(EXTI_Line13);
    }

    if(led==off){
        GPIO_WriteBit(GPIOB,GPIO_Pin_8,Bit_SET);
        led=on;
    }else{
        GPIO_WriteBit(GPIOB,GPIO_Pin_8,Bit_RESET);
        led=off;
    }
}

#ifdef USE_FULL_ASSERT
void assert_failed(uint8_t * file,uint32_t line){
    /* Infinite loop */
    while (1);
}
#endif
c debugging microcontroller interrupt stm32
4个回答
2
投票

我也遇到这个问题了。我用的是STM32F030。 对我来说,问题是没有启用 SYSCFG 时钟,它是 RCC APB2ENR 寄存器的位 0。我猜这个设置是在调试中启用的,以便软件可以调试?否则时钟将被禁用!

通过查阅STM32F1参考手册终于找到了这个,稍微全面一点。


0
投票

对按钮和按键使用外部中断通常是一个非常糟糕的主意。您应该改用定时器中断。

您可以在这里看到定时器中断中按键的简单实现(支持单击、双击、长按事件):https://www.diymat.co.uk/arm- Three-function-click-double-and -长按按钮库定时器中断驱动/


0
投票

我对上述控制器不了解,但我曾研究过STM32L4系列控制器。在 STM32L4 中,按钮连接到 PC13 引脚。我观察到按下按钮时 GPIO 去抖。在 EXTI15_10_IRQHandler() 中实现去抖逻辑。确保每次按下按钮时中断仅到达此函数一次。可能是调试器正在减慢处理器的速度(与自由运行相比,CPU 以较低的频率运行),并且您正在正确地获取中断。


-1
投票

您是否使用不同的构建配置进行调试?如果是这样,请尝试创建

led
变量
volatile
并查看是否有帮助。 如果不是:添加一些延迟循环,即在 ISR 中清除 EXTI 位后添加
voliatile unsigned i; for (i=0; i < 50000u; ++i);
。在中断服务中使用阻塞延迟通常是一种不好的做法(如果它曾经是一个好的做法......),但可能有助于查看它是否与未正确完成的反跳有关。如果有帮助,那么最有可能出现的问题是开关去抖。

编辑:考虑使用位带(如果可能)来访问输出端口,然后你可以做类似

bind_band_led_port ^= 1;
的事情,但这只是一个旁注。

© www.soinside.com 2019 - 2024. All rights reserved.