OpenEdv-开源电子网

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

关于外部中断与定时器中断的嵌套问题

[复制链接]

1

主题

7

帖子

0

精华

新手上路

积分
23
金钱
23
注册时间
2017-7-21
在线时间
4 小时
发表于 2017-7-21 17:12:09 | 显示全部楼层 |阅读模式
1金钱
大家好,在下求助,我想做一个设计:设计中包含两个红外探头的判断过程需要放到中断中,大致需求是这样的 :先判断红外A是否触发,然后隔1s判断红外B是否触发,若果B触发,那么就Count++,其他情况均为错误,我自己写的代码不符合我的需求,大家看下帮忙分析下, 代码如下:
(是不是需要用两个外部中断来判断两个红外信号,然后再用定时器?)

望大家不吝赐教,多谢各位!!!

exti.C

void EXTIX_Config(void)
{
        EXTI_InitTypeDef EXTI_InitStructure;
        NVIC_InitTypeDef NVIC_InitStructure;
       
        IR_Config();
        LED_Config();
        KEY_Init();
       
        RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO,ENABLE);  //使能复用功能时钟


        //GPIOA.0          中断线以及中断初始化配置 上升沿触发 PA0  WK_UP
        GPIO_EXTILineConfig(GPIO_PortSourceGPIOA,GPIO_PinSource0);
        EXTI_InitStructure.EXTI_Line=EXTI_Line0;
          EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_Rising;
          EXTI_Init(&EXTI_InitStructure);                //根据EXTI_InitStruct中指定的参数初始化外设EXTI寄存器
       
        NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;                        //使能按键KEY0所在的外部中断通道
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x02;//抢占优先级2
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x02;                //子优先级3
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;                                //使能外部中断通道
        NVIC_Init(&NVIC_InitStructure);
}


void EXTI0_IRQHandler(void)
{       
       
                delay_ms(10);
                if(WK_UP == 1)
                {       
                        LED1 =0;
                        TIM_Cmd(TIM3, ENABLE);  //使能TIM3
                }       


        EXTI_ClearITPendingBit(EXTI_Line0); //清除LINE0上的中断标志位  
}





timer.c

//通用定时器3中断初始化
//这里时钟选择为APB1的2倍,而APB1为36M
//arr:自动重装值。
//psc:时钟预分频数
//这里使用的是定时器3!
void TIM3_Config(u16 arr,u16 psc)
{
        TIM_TimeBaseInitTypeDef  TIM_TimeBaseStructure;
        NVIC_InitTypeDef NVIC_InitStructure;

        RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE); //时钟使能
       
        //定时器TIM3初始化
        TIM_TimeBaseStructure.TIM_Period = arr; //设置在下一个更新事件装入活动的自动重装载寄存器周期的值       
        TIM_TimeBaseStructure.TIM_Prescaler =psc; //设置用来作为TIMx时钟频率除数的预分频值
        TIM_TimeBaseStructure.TIM_ClockDivision = TIM_CKD_DIV1; //设置时钟分割:TDTS = Tck_tim
        TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up;  //TIM向上计数模式
        TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStructure); //根据指定的参数初始化TIMx的时间基数单位

        TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE ); //使能指定的TIM3中断,允许更新中断

        //中断优先级NVIC设置
        NVIC_InitStructure.NVIC_IRQChannel = TIM3_IRQn;  //TIM3中断
        NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;  //先占优先级0级
        NVIC_InitStructure.NVIC_IRQChannelSubPriority = 2;  //从优先级3级
        NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; //IRQ通道被使能
        NVIC_Init(&NVIC_InitStructure);  //初始化NVIC寄存器
               
}
//定时器3中断服务程序
void TIM3_IRQHandler(void)   //TIM3中断
{
        if (TIM_GetITStatus(TIM3, TIM_IT_Update) != RESET)  //检查TIM3更新中断发生与否
                {               
                        delay_ms(10);
                        if(KEY0 == 0)
                        {
                                LED1 =1;
                                Count++;
                                printf("Count = %d",Count);
                        }
                        TIM_ClearITPendingBit(TIM3, TIM_IT_Update  );  //清除TIMx更新中断标志
                        TIM_Cmd(TIM3,DISABLE);  //失能TIM3                       

                }
}


最佳答案

查看完整内容[请看2#楼]

一个中断,只能映射到1个IO口,你两个红外输入都接这个IO口,就无法分辨什么时候是A,什么时候是B。 所以的话,接两个IO口,用2个中断,是最简单的解决办法
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165359
金钱
165359
注册时间
2010-12-1
在线时间
2110 小时
发表于 2017-7-21 17:12:10 | 显示全部楼层
一个中断,只能映射到1个IO口,你两个红外输入都接这个IO口,就无法分辨什么时候是A,什么时候是B。
所以的话,接两个IO口,用2个中断,是最简单的解决办法
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复

使用道具 举报

0

主题

92

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1216
金钱
1216
注册时间
2016-7-17
在线时间
143 小时
发表于 2017-7-21 17:21:48 | 显示全部楼层
本帖最后由 虾兵蟹将 于 2017-7-21 17:24 编辑

你的外部中断没有使能
EXTI_InitStructure.EXTI_LineCmd = ENABLE;我觉得一个中断够用了,先判断A是否触发,若触发,进入中断,在中断里面延时1s,检查B是否触发,是则累加计数,不是则报错
回复

使用道具 举报

1

主题

7

帖子

0

精华

新手上路

积分
23
金钱
23
注册时间
2017-7-21
在线时间
4 小时
 楼主| 发表于 2017-7-21 17:39:21 | 显示全部楼层
不可以吧,外部中断有如图特性啊
图片1.png
回复

使用道具 举报

1

主题

7

帖子

0

精华

新手上路

积分
23
金钱
23
注册时间
2017-7-21
在线时间
4 小时
 楼主| 发表于 2017-7-21 17:40:39 | 显示全部楼层
他的每个IO都对应一个中断,我的两个红外是接到两个IO上的啊
回复

使用道具 举报

1

主题

7

帖子

0

精华

新手上路

积分
23
金钱
23
注册时间
2017-7-21
在线时间
4 小时
 楼主| 发表于 2017-7-21 17:44:55 | 显示全部楼层
虾兵蟹将 发表于 2017-7-21 17:21
你的外部中断没有使能
EXTI_InitStructure.EXTI_LineCmd = ENABLE;我觉得一个中断够用了,先判断A是否触发 ...

还有,其实两个红外是为了检测 人走过的双重判断,所以如果严格设定1s的话是不科学的。急需求解
回复

使用道具 举报

0

主题

92

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1216
金钱
1216
注册时间
2016-7-17
在线时间
143 小时
发表于 2017-7-21 17:50:20 | 显示全部楼层
skyBuddha 发表于 2017-7-21 17:40
他的每个IO都对应一个中断,我的两个红外是接到两个IO上的啊

不是必须用中断来处理红外的,其实甚至可以不用中断,我记得红外返回的应该就是一个电平,你可以直接从引脚读取电平信号,根据电平的高低进行判断。
回复

使用道具 举报

1

主题

7

帖子

0

精华

新手上路

积分
23
金钱
23
注册时间
2017-7-21
在线时间
4 小时
 楼主| 发表于 2017-7-21 17:56:57 | 显示全部楼层
虾兵蟹将 发表于 2017-7-21 17:50
不是必须用中断来处理红外的,其实甚至可以不用中断,我记得红外返回的应该就是一个电平,你可以直接从引 ...

大哥,其实 我目的有两个 ①让程序更完美点   ②学习下这种处理机制  ,遇到问题了。我就想把他解决掉,而且确实是一个不错的处理机制,望各位大哥给点帮助和支持
回复

使用道具 举报

0

主题

92

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1216
金钱
1216
注册时间
2016-7-17
在线时间
143 小时
发表于 2017-7-21 18:07:05 | 显示全部楼层
skyBuddha 发表于 2017-7-21 17:56
大哥,其实 我目的有两个 ①让程序更完美点   ②学习下这种处理机制  ,遇到问题了。我就想把他解决掉, ...

那我建议用一个中断就行,两个中断反而更难处理
回复

使用道具 举报

1

主题

7

帖子

0

精华

新手上路

积分
23
金钱
23
注册时间
2017-7-21
在线时间
4 小时
 楼主| 发表于 2017-7-24 18:18:08 | 显示全部楼层
正点原子 发表于 2017-7-21 17:12
一个中断,只能映射到1个IO口,你两个红外输入都接这个IO口,就无法分辨什么时候是A,什么时候是B。
所以 ...

原子哥,我就是用的两个中断,我试过两个外部中断和一个外部一个定时器中断,但是都没达到我预期的设想,望原子哥指点!
回复

使用道具 举报

1

主题

7

帖子

0

精华

新手上路

积分
23
金钱
23
注册时间
2017-7-21
在线时间
4 小时
 楼主| 发表于 2017-7-25 10:59:04 | 显示全部楼层
正点原子 发表于 2017-7-21 17:12
一个中断,只能映射到1个IO口,你两个红外输入都接这个IO口,就无法分辨什么时候是A,什么时候是B。
所以 ...

原子哥,我用的就是两个中断啊,两个外部中断或一个外部加一个定时器中断都试了,都不能满足我的需求啊  :  我需要当A触发后 1S后 B触发  满足以上两个条件使计数器加一,而我写的那个代码是只有恰好到1SB才会触发,望原子哥修改下我的代码,多谢
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2024-12-23 12:30

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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