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

时间:2016-11-22 20:47:47

标签: c debugging microcontroller interrupt stm32

我的STM32F103C8T6微控制器有问题。我正在使用(作为练习)外部中断来打开/关闭LED,通过按下外部开关来依次连接到PC13。我正在使用StdPeriph Library。

当芯片编程时,没有任何反应。相反,当我使用调试器(在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

4 个答案:

答案 0 :(得分:1)

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

我终于通过查看STM32F1参考手册找到了这一点,该手册稍微全面一些。

答案 1 :(得分:0)

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

答案 2 :(得分:0)

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

您可以在此处看到计时器中断(点击,双击,支持长按事件)中密钥的简单实现:https://www.diymat.co.uk/arm-three-function-click-double-and-long-click-button-library-timer-interrupt-driven/

答案 3 :(得分:-1)

您是否使用不同的构建配置进行调试?如果是,请尝试制作led变量volatile并查看是否有帮助。 如果不是:在清除ISR中的EXTI位之后添加一些延迟循环,即voliatile unsigned i; for (i=0; i < 50000u; ++i);。这通常是在中断服务中使用阻塞延迟的一个不好的实践(如果这是一个好的做法......)但是可能有助于查看它是否与debuncing没有正确完成相关。如果它有帮助,那么去除开关是最可能的问题。

编辑:考虑使用位带(如果可能)来访问输出端口,那么你可以像bind_band_led_port ^= 1;那样做,但这只是一个侧面说明。