你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

STM32F401 Nucleo 开发板不能进入GPIO EXTI按键中断

[复制链接]
xujiantj 提问时间:2018-12-28 10:25 /
本帖最后由 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_InitTypeDef  GPIO_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);

    }

}




收藏 评论13 发布时间:2018-12-28 10:25

举报

13个回答
wenyangzeng 回答时间:2018-12-29 16:35:33
本帖最后由 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){}

wenyangzeng 回答时间:2018-12-28 11:57:43
按理中断函数里只调用处理函数:
void EXTI0_IRQHandler(void)
{
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN13);
}

然后在处理函数里:
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{

if(GPIO_Pin == GPIO_PIN13)

{//处理过程
.
.
}
}
而不应该在中断函数里是重复调用中断函数。

xujiantj 回答时间:2018-12-28 13:54:11
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;
     }
}
wenyangzeng 回答时间:2018-12-28 14:54:59
xujiantj 发表于 2018-12-28 13:54
改成这样也不行,现象一样
void EXTI15_10_IRQHandler(void)
{

ST官方有例程可以参考的:
GPIO_EXTI.rar (8.33 MB, 下载次数: 19)
xujiantj 回答时间:2018-12-28 15:52:25
好的,多谢,我再试试
xujiantj 回答时间:2018-12-29 15:36:04
用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),应该是不需要)。
不知道为什么进入不了中断?
废鱼 回答时间:2018-12-29 15:44:29
楼主,代码中没有看到对exit的配置。
xujiantj 回答时间:2018-12-29 15:52:14

这部分应该是对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);
xujiantj 回答时间:2018-12-29 16:02:50
我发现仿真的时候按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      EF:__MICROLIB
366               
367                EXPORT  __initial_sp
368                EXPORT  __heap_base
369                EXPORT  __heap_limit
xujiantj 回答时间:2018-12-29 16:46:03
wenyangzeng 发表于 2018-12-29 16:35
那个PC13应该设置上拉才对。
进入的那个状态是硬件出错中断。还有那个stm32f4xx.it.c关于外部中断的代码应 ...

PC13设置成上拉之前试过,也不行。硬件PC13外部有10K电阻的上拉,设置成浮空输入应该也行。
xujiantj 回答时间:2018-12-29 16:52:04
xujiantj 发表于 2018-12-29 16:46
PC13设置成上拉之前试过,也不行。硬件PC13外部有10K电阻的上拉,设置成浮空输入应该也行。 ...

我再看看stm32f4xx.it.c文件中的中断部分的代码,非常感谢!!!
xujiantj 回答时间:2019-1-2 09:57:10
问题解决了!感谢楼上的大哥,是stm32f4xx.it.c中之前例程中给的是外部中断0的服务函数 EXTI0_IRQHandler(),因为外部中断改成PC13了,需要改成 EXTI15_10_IRQHandler()。添加如下代码就可以了。
void EXTI15_10_IRQHandler(void)
{
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
}

非常感谢!!!
xujiantj 回答时间:2019-1-2 10:21:36
wenyangzeng 发表于 2018-12-29 16:35
那个PC13应该设置上拉才对。  GPIO_InitStruct.Pull = GPIO_PULLUP;

进入的那个状态是硬件出错中断。还有 ...

非常感谢楼上大哥,问题已解决!!!
就是例程的stm32f4xx.it.c中原先的中断服务函数是:
void EXTI0_IRQHandler(void)
{
  HAL_GPIO_EXTI_IRQHandler(KEY_BUTTON_PIN);
}
需要改为:
void EXTI15_10_IRQHandler(void)
{
  HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
}
就可以了!!!
非常感谢!!!
关于意法半导体
我们是谁
投资者关系
意法半导体可持续发展举措
创新和工艺
招聘信息
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
关注我们
st-img 微信公众号
st-img 手机版