STM32F401 Nucleo 开发板不能进入GPIO EXTI按键中断
本帖最后由 xujiantj 于 2019-1-2 10:33 编辑功能描述:
PC13连接外部user按键,外部接10K上拉电阻,按键另一端接地,按下按键PC13端口电平变低,下降沿触发中断。PA5控制指示灯闪烁,上电后间隔100ms亮灭1次,按user键后,变成间隔1000ms亮灭1次。
故障描述:
单片机上电或复位后,运行正常,指示灯按100ms间隔不停的亮灭显示。按user键后指示灯常亮或常灭(每次按user键,指示灯状态不确定),感觉单片机检测到了中断,但是没办法进入中断执行,好像死机一样。
程序如下,请各位大侠帮我分析一下问题出在哪里,多谢了!!!
#include "mbed.h"
#include "stm32f4xx_hal.h"
#include "stm32f4xx.h"
#include "stm32f4xx_hal_gpio.h"
static GPIO_InitTypeDefGPIO_InitStruct;
int16_t count1 = 100;
void EXTI15_10_IRQHandler(void)
{
HAL_NVIC_ClearPendingIRQ(EXTI15_10_IRQn);
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
{
// EXTI line interrupt detected
if(__HAL_GPIO_EXTI_GET_IT(GPIO_PIN_13) != RESET)
{
__HAL_GPIO_EXTI_CLEAR_IT(GPIO_PIN_13);
HAL_GPIO_EXTI_Callback(GPIO_PIN_13);
}
}
}
void HAL_GPIO_EXTI_Callback (uint16_t GPIO_Pin)
{
if (GPIO_Pin == GPIO_PIN_13)
{
count1 = 1000;
}
}
int main()
{
HAL_Init();
/* GPIO Ports Clock Enable */
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_13;//PC13 as interrupt test
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING ;
GPIO_InitStruct.Pull =GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
//EXTI interrupt init
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
/* -2- Configure PA05 IO in output push-pull mode to
drive external LED */
GPIO_InitStruct.Pin = GPIO_PIN_5;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
while (1) {
// HAL_NVIC_DisableIRQ(EXTI15_10_IRQn);
HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
/* Insert delay 100 ms */
HAL_Delay(count1);
// Flashing(1000);
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
}
}
本帖最后由 wenyangzeng 于 2018-12-29 16:45 编辑
xujiantj 发表于 2018-12-29 16:02
我发现仿真的时候按PC13按键,检测到中断后,程序没进中断,停留在startup_stm32f401xc.s的356行 B.位置。 ...
那个PC13应该设置上拉才对。GPIO_InitStruct.Pull = GPIO_PULLUP;
进入的那个状态是硬件出错中断。还有那个stm32f4xx.it.c关于外部中断的代码应该贴出来看看,或许你没有在里头设置外部中断头函数void EXTI15_10_IRQHandler(void){}
按理中断函数里只调用处理函数:
void EXTI0_IRQHandler(void)
{
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN13);
}
然后在处理函数里:
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if(GPIO_Pin == GPIO_PIN13)
{//处理过程
.
.
}
}
而不应该在中断函数里是重复调用中断函数。
wenyangzeng 发表于 2018-12-28 11:57
按理中断函数里只调用处理函数:
void EXTI0_IRQHandler(void)
{
改成这样也不行,现象一样
void EXTI15_10_IRQHandler(void)
{
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
}
void HAL_GPIO_EXTI_Callback (uint16_t GPIO_Pin)
{
if (GPIO_Pin == GPIO_PIN_13) {
count1 = 1000;
}
} xujiantj 发表于 2018-12-28 13:54
改成这样也不行,现象一样
void EXTI15_10_IRQHandler(void)
{
ST官方有例程可以参考的:
好的,多谢,我再试试 用ST官方例程还是不行。
把例程中的中断端口有PA0改为PC13,指示灯显示改为PA5,(为了和STM32F401 Nucleo开发板上的硬件匹配)。上电后指示灯闪烁正常,按PC13按键后,指示灯常亮或常灭,未执行中断。
在keil中单步执行后,观察MR13置1(PC13开中断),TR13置1(设置为下降沿触发),运行后,按PC13按键后,观察PR13置1,说明已经检测到了外部中断PC13。但是不执行中断回调函数(例程中只有回调函数HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin),没有中断服务函数EXTI15_10_IRQHandler(void),应该是不需要)。
不知道为什么进入不了中断? 楼主,代码中没有看到对exit的配置。
这部分应该是对EXTI的设置,PC13为外部中断入口
__HAL_RCC_GPIOC_CLK_ENABLE();
GPIO_InitStruct.Pin = GPIO_PIN_13; //PC13 as interrupt test
GPIO_InitStruct.Mode = GPIO_MODE_IT_FALLING ;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
//EXTI interrupt init
HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(EXTI15_10_IRQn); 我发现仿真的时候按PC13按键,检测到中断后,程序没进中断,停留在startup_stm32f401xc.s的356行 B.位置。以后再按单步执行,也都停止这里不动了,是不是和这里有关系。
350 USART6_IRQHandler
351 I2C3_EV_IRQHandler
352 I2C3_ER_IRQHandler
353 FPU_IRQHandler
354 SPI4_IRQHandler
355
356 B .
357
358 ENDP
359
360 ALIGN
361
362 ;*********************************************
363 ; User Stack and Heap initialization
364 ;*********************************************
365 IF :DEF:__MICROLIB
366
367 EXPORT__initial_sp
368 EXPORT__heap_base
369 EXPORT__heap_limit
页:
[1]
2