OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 7479|回复: 22

新手求解关于外部中断

[复制链接]

25

主题

103

帖子

0

精华

初级会员

Rank: 2

积分
118
金钱
118
注册时间
2018-3-10
在线时间
66 小时
发表于 2018-3-11 20:54:06 | 显示全部楼层 |阅读模式
1金钱
看完外部中断视频后自己写了个代码,想分别用两个按键控制两个LED闪烁,key0抢占优先级设置为1,KEY1为1,当我先按key1时LED1闪烁,可是为什么按KEY0时却没有反应?附上代码求大神解析下

        GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource15);
        EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
        EXTI_InitStructure.EXTI_Line=EXTI_Line15;
        EXTI_InitStructure.EXTI_LineCmd=ENABLE;
        EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
        EXTI_Init(& EXTI_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);
       
       
        GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource5);
EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
        EXTI_InitStructure.EXTI_Line=EXTI_Line5;
        EXTI_InitStructure.EXTI_LineCmd=ENABLE;
        EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
        EXTI_Init(& EXTI_InitStructure);
       
         NVIC_InitStructure.NVIC_IRQChannel=  EXTI9_5_IRQn;
         NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE;
         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=1;
         NVIC_InitStructure.NVIC_IRQChannelSubPriority=1;
        NVIC_Init(& NVIC_InitStructure);
}


void EXTI15_10_IRQHandler()
        {
        delay_ms(10);
                if(KEY1==0)
                {
                        LED0=1;
                while(1)
                        {
               
        LED1=0;
                        delay_ms(500);
                                LED1=1;
                                delay_ms(500);
                               
                }
        }
                EXTI_ClearITPendingBit(EXTI_Line15);
                }
       
               

void EXTI9_5_IRQHandler()

        {
        delay_ms(10);
                if(KEY0==0)
                {
                         LED1=1;
                while(1)
                        {
         
                LED0=0;
                        delay_ms(500);
                                LED0=1;
                                delay_ms(500);
                               
                }
        }
                EXTI_ClearITPendingBit(EXTI_Line5);
                }
               

正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

25

主题

103

帖子

0

精华

初级会员

Rank: 2

积分
118
金钱
118
注册时间
2018-3-10
在线时间
66 小时
 楼主| 发表于 2018-3-11 21:03:50 | 显示全部楼层
而且就算是一开始按key0也没有反应
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2018-3-12 00:48:46 | 显示全部楼层
是不是对应错了?参考下我们开发板例程。
回复

使用道具 举报

82

主题

589

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1255
金钱
1255
注册时间
2017-11-18
在线时间
296 小时
发表于 2018-3-12 08:21:40 | 显示全部楼层
感觉EXTI9_5_IRQHandler()有问题,中断线9和中断线5共用一个中断函数,但是程序不知道是哪个线发生了中断呀,我觉得应该先判断下是Line_9还是Line_5发生了中断
回复

使用道具 举报

25

主题

103

帖子

0

精华

初级会员

Rank: 2

积分
118
金钱
118
注册时间
2018-3-10
在线时间
66 小时
 楼主| 发表于 2018-3-12 09:20:36 | 显示全部楼层
正点原子 发表于 2018-3-12 00:48
是不是对应错了?参考下我们开发板例程。

找到问题了,复用时钟使能函数写错了。可是为什么我这样写不能一个键控制一个led闪烁呢?只能先按下key0或者key1时对应的led闪烁,而再按其他键的时候却没反应,而我明明设置了不同的中断响应级
回复

使用道具 举报

25

主题

103

帖子

0

精华

初级会员

Rank: 2

积分
118
金钱
118
注册时间
2018-3-10
在线时间
66 小时
 楼主| 发表于 2018-3-12 09:21:13 | 显示全部楼层
美丽的时光机器 发表于 2018-3-12 08:21
感觉EXTI9_5_IRQHandler()有问题,中断线9和中断线5共用一个中断函数,但是程序不知道是哪个线发生了中断呀 ...

我没用到中短线9啊,只用了5和15
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2018-3-13 01:59:55 | 显示全部楼层
ljw285 发表于 2018-3-12 09:21
我没用到中短线9啊,只用了5和15

9_5是共用同一个中断服务函数的
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

82

主题

589

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1255
金钱
1255
注册时间
2017-11-18
在线时间
296 小时
发表于 2018-3-13 08:15:50 | 显示全部楼层
ljw285 发表于 2018-3-12 09:21
我没用到中短线9啊,只用了5和15

共用中断函数的,在中断函数里面做判断来区分是哪一根线发生了中断
没有脑袋
回复

使用道具 举报

25

主题

103

帖子

0

精华

初级会员

Rank: 2

积分
118
金钱
118
注册时间
2018-3-10
在线时间
66 小时
 楼主| 发表于 2018-3-13 10:05:03 | 显示全部楼层
正点原子 发表于 2018-3-13 01:59
9_5是共用同一个中断服务函数的

对啊,我只用了5和15这两条线,没用到9啊
回复

使用道具 举报

82

主题

589

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1255
金钱
1255
注册时间
2017-11-18
在线时间
296 小时
发表于 2018-3-13 11:34:11 | 显示全部楼层
美丽的时光机器 发表于 2018-3-13 08:15
共用中断函数的,在中断函数里面做判断来区分是哪一根线发生了中断

会不会是你本身的思路就是不对的,两个中断不同的抢占优先级,假如A优先于B,假如A先中断的话,B中断会打断A中断吗?假如B先中断,那A打断B中断后进入A的中断函数一直循环亮灯,那B中断到来后会打断A中断吗?不知道是不是这样,你验证一下
没有脑袋
回复

使用道具 举报

15

主题

866

帖子

0

精华

论坛元老

Rank: 8Rank: 8

积分
7577
金钱
7577
注册时间
2016-11-30
在线时间
644 小时
发表于 2018-3-13 13:41:32 | 显示全部楼层
一点小建议,中断里最好别加延时,尽量简洁高效。
回复

使用道具 举报

31

主题

265

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
413
金钱
413
注册时间
2018-1-9
在线时间
65 小时
发表于 2018-3-13 16:17:21 | 显示全部楼层
中断服务函数里居然有while死循环和长时间的延时(不推荐),高优先级的中断只要被触发就会一直占用CPU,其他所有的任务都没办法运行了啊?
回复

使用道具 举报

25

主题

103

帖子

0

精华

初级会员

Rank: 2

积分
118
金钱
118
注册时间
2018-3-10
在线时间
66 小时
 楼主| 发表于 2018-3-13 20:29:31 | 显示全部楼层
jinfeihan57 发表于 2018-3-13 16:17
中断服务函数里居然有while死循环和长时间的延时(不推荐),高优先级的中断只要被触发就会一直占用CPU,其 ...

可是我另一个中断的优先级大于这个中断,不能停止这个循环吗
回复

使用道具 举报

31

主题

265

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
413
金钱
413
注册时间
2018-1-9
在线时间
65 小时
发表于 2018-3-14 09:56:13 | 显示全部楼层
ljw285 发表于 2018-3-13 20:29
可是我另一个中断的优先级大于这个中断,不能停止这个循环吗

你是说Key0 没办法抢到Key1吗?
回复

使用道具 举报

31

主题

265

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
413
金钱
413
注册时间
2018-1-9
在线时间
65 小时
发表于 2018-3-14 09:59:58 | 显示全部楼层
你这个最后的中断挂起函数没有被执行过,所以你的两个中断都只能触发一次。可以把源码发一下看看。你是mini板对吧??
回复

使用道具 举报

25

主题

103

帖子

0

精华

初级会员

Rank: 2

积分
118
金钱
118
注册时间
2018-3-10
在线时间
66 小时
 楼主| 发表于 2018-3-15 09:41:09 | 显示全部楼层
jinfeihan57 发表于 2018-3-14 09:56
你是说Key0 没办法抢到Key1吗?

是的  字数字数
回复

使用道具 举报

25

主题

103

帖子

0

精华

初级会员

Rank: 2

积分
118
金钱
118
注册时间
2018-3-10
在线时间
66 小时
 楼主| 发表于 2018-3-15 09:42:19 | 显示全部楼层
jinfeihan57 发表于 2018-3-14 09:59
你这个最后的中断挂起函数没有被执行过,所以你的两个中断都只能触发一次。可以把源码发一下看看。你是mini ...

#include "led.h"
#include "delay.h"
#include "sys.h"
#include "key.h"
#include "usart.h"
#include "handler.h"
int main(void)
{       

        delay_init();                     //延时函数初始化       
        NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
        uart_init(9600);         //串口初始化为9600
        LED_Init();                           //初始化与LED连接的硬件接口
        EXTIX_Init();//外部中断初始化
  LED0=0;                 //点亮LED
         while(1)
        {            
                printf("OK\n");       
                delay_ms(1000);          
        }
}
回复

使用道具 举报

25

主题

103

帖子

0

精华

初级会员

Rank: 2

积分
118
金钱
118
注册时间
2018-3-10
在线时间
66 小时
 楼主| 发表于 2018-3-15 09:42:31 | 显示全部楼层
jinfeihan57 发表于 2018-3-14 09:59
你这个最后的中断挂起函数没有被执行过,所以你的两个中断都只能触发一次。可以把源码发一下看看。你是mini ...

#include "handler.h"
#include "usart.h"
#include "key.h"
#include "delay.h"
#include "led.h"


void EXTIX_Init(void)
{
  EXTI_InitTypeDef   EXTI_InitStructure;
        NVIC_InitTypeDef   NVIC_InitStructure;
       
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);
       
  KEY_Init();
       
GPIO_EXTILineConfig(GPIO_PortSourceGPIOC,GPIO_PinSource5);
  
        EXTI_InitStructure.EXTI_Line=EXTI_Line5;
        EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
        EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
        EXTI_InitStructure.EXTI_LineCmd=ENABLE;       
        EXTI_Init(& EXTI_InitStructure);
       
       
         NVIC_InitStructure.NVIC_IRQChannel=  EXTI9_5_IRQn;
         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x02;
         NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x01;
         NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE;
        NVIC_Init(& NVIC_InitStructure);
       
                GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource15);
       
        EXTI_InitStructure.EXTI_Line=EXTI_Line15;
        EXTI_InitStructure.EXTI_Mode=EXTI_Mode_Interrupt;
        EXTI_InitStructure.EXTI_Trigger=EXTI_Trigger_Falling;
        EXTI_InitStructure.EXTI_LineCmd=ENABLE;
        EXTI_Init(&EXTI_InitStructure);
       
        NVIC_InitStructure.NVIC_IRQChannel=  EXTI15_10_IRQn;
         NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x02;
         NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x00;
         NVIC_InitStructure.NVIC_IRQChannelCmd= ENABLE;
        NVIC_Init(& NVIC_InitStructure);
       

}



void EXTI15_10_IRQHandler(void)
        {
        delay_ms(10);
                if(KEY1==0)
                {
                        LED0=1;
                while(1)
                        {
               
        LED1=0;
                        delay_ms(500);
                                LED1=1;
                                delay_ms(500);
                               
                }
        }
                EXTI_ClearITPendingBit(EXTI_Line15);
                }
       
               

void EXTI9_5_IRQHandler(void)

        {
        delay_ms(10);
                if(KEY0==0)
                {
                         LED1=1;
                while(1)
                        {
         
                LED0=0;
                        delay_ms(500);
                                LED0=1;
                                delay_ms(500);
                               
                }
        }
                EXTI_ClearITPendingBit(EXTI_Line5);
                }

回复

使用道具 举报

31

主题

265

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
413
金钱
413
注册时间
2018-1-9
在线时间
65 小时
发表于 2018-3-15 10:57:58 | 显示全部楼层
ljw285 发表于 2018-3-15 09:42
#include "handler.h"
#include "usart.h"
#include "key.h"

你这个程序跟问题中贴出的程序不一样啊?问题中贴出的应该是对的。这次贴出来的不对。你把其中一个
  NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x02;改为0x01.应该就可以用一个中断去打断另一个中断。记住,你的程序只能打断一次。
回复

使用道具 举报

3

主题

31

帖子

0

精华

初级会员

Rank: 2

积分
126
金钱
126
注册时间
2018-2-3
在线时间
13 小时
发表于 2018-3-15 20:08:06 | 显示全部楼层
我也出现这个问题了,后来把延时函数改了下就好了,你试试用在线编译,把断点设置到key2看能不能运行过去不就得了
回复

使用道具 举报

22

主题

117

帖子

0

精华

资深版主

Rank: 8Rank: 8

积分
798
金钱
798
注册时间
2015-10-24
在线时间
160 小时
发表于 2018-3-16 10:27:37 | 显示全部楼层
你再中断里面加一个断点,看看程序会不会执行到中断里面
回复

使用道具 举报

5

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
54
金钱
54
注册时间
2018-4-7
在线时间
17 小时
发表于 2018-4-7 10:28:48 | 显示全部楼层
你的中断函数里面有while(1)函数啊,程序会卡在这里面出不去
回复

使用道具 举报

20

主题

99

帖子

0

精华

初级会员

Rank: 2

积分
178
金钱
178
注册时间
2020-6-21
在线时间
70 小时
发表于 2020-12-25 13:33:07 | 显示全部楼层
ljw285 发表于 2018-3-15 09:42
#include "handler.h"
#include "usart.h"
#include "key.h"

你在程序都跑到while(1)里面了,出不来了。
把whilie(1)删掉,在主函数里面循环这个闪灯的逻辑。用一个标志选择哪个灯闪烁。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-24 15:40

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表