我的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
答案 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;
那样做,但这只是一个侧面说明。