外部stm32中断服务函数执行完为什么不返回主函数

21ic官方微信
后使用快捷导航没有帐号?
查看: 2669|回复: 2
为什么中断返回后主程序不继续执行?
&&未结帖(20)
主题帖子积分
实习生, 积分 3, 距离下一级还需 47 积分
实习生, 积分 3, 距离下一级还需 47 积分
主题帖子积分
专家等级: 结帖率:0%
主题帖子积分
实习生, 积分 3, 距离下一级还需 47 积分
实习生, 积分 3, 距离下一级还需 47 积分
本帖最后由 寻觅奈若何 于
11:58 编辑
为什么中断返回后主程序不继续执行?
我想用红外遥控器控制实验板上的器件,比如led灯、蜂鸣器、继电器等等。接收红外遥控信号是用外中断0完成的,用PI口的8个led灯显示收到的信号的第3个字节的二进制码,但当中断返回以后,主程序中的
while(1)& &//等待红外信号产生的中断
&&{beep(); //检查中断返回后是否运行
& &&&if(P1==0x15) P0=P1;& && && && && &//如果收到的信号的第三个字是0x15,就用P0口的8个led灯显示
&&else { P0=0XFF;}& && && && && && && && & //否则P0口的灯不亮
& & }& &&&
为什么不继续执行了?& && && && && && && && && && && && && &&&
程序如下:
实验板采用12MHZ晶振
#include&reg52.h&& && &
#include&intrins.h&&&
sbit IR=P3^2;& && && &&&//将IR位定义为P3.2引脚外中断0
sbit BEEP = P3^6; //蜂鸣器控制端口
unsigned char a[4];& & //储存用户码、用户反码与键数据码、键数据反码
unsigned int LowTime,HighT //储存高、低电平的宽度
void delay1ms()
& &unsigned char i,j;
&&for(i=0;i&10;i++)
& &for(j=0;j&33;j++)
void delay(unsigned char n)
for(i=0;i&n;i++)
& & delay1ms();
void beep()&&//蜂鸣器响一声函数
&&for (i=0;i&100;i++)
& &delay1ms();
& &BEEP=!BEEP;& && & //BEEP取反
& &BEEP=1;& && && &&&//关闭蜂鸣器
& &delay(250);& && & //延时& &&&
bit DeCode(void)& && &&&//解码函数
& &unsigned char&&i,j;
& & //储存解码出的数据
for(i=0;i&4;i++)& && &//连续读取4个用户码和键数据码
& &for(j=0;j&8;j++)&&//每个码有8位数字
& && && & temp=temp&&1;&&//temp中的各数据位右移一位,因为先读出的是高位数据& && && &
& && &TH0=0;& && && &//定时器清0
& && &TL0=0;& && && &//定时器清0
& && &TR0=1;& && && &//开启定时器T0
& && &&&while(IR==0)& &//如果是低电平就等待
& && && && && & ;& && & //低电平计时
& && &&&TR0=0;& && && &//关闭定时器T0
& && &LowTime=TH0*256+TL0;& & //保存低电平宽度
& && &TH0=0;& && && &//定时器清0
& && &TL0=0;& && && &//定时器清0
& && &TR0=1;& && && &//开启定时器T0
& && &while(IR==1)& &//如果是高电平就等待
& && && & ;& && &
& && &TR0=0;& && &&&//关闭定时器T0
& && &HighTime=TH0*256+TL0;& &//保存高电平宽度
& && &if((LowTime&460)||(LowTime&660))
& && && &&&return 0;& && &&&//如果低电平长度不在合理范围,则认为出错,停止解码& &
& && &if((HighTime&460)&&(HighTime&660))& &//如果高电平时间在560微秒左右,即计数560/1=560次
& && && && &&&temp=temp&0x7f;& && & //(560-100=460, 560+100=660),则该位是0
& && &if((HighTime&1430)&&(HighTime&1930)) //如果高电平时间在1680微秒左右,即计数80次
& && && && &&&temp=temp|0x80;& && & //(0,0),则该位是1
& && & }& && && && && &&&
& & a= //将解码出的字节值储存在a& && && && && && && &
& & }& && && &
&&if(a[2]==~a[3])& & return 1;& &&&//解码正确,返回1
/************************************************************
函数功能:主函数
*************************************************************/
void main()
EA=1;& && &
& &EX0=1;& && &
& &ET0=1;& && &
& &IT0=1;& && &
& & TMOD=0x01;& &
TR0=0;& && &
& &while(1)& &//等待红外信号产生的中断
&&{beep(); //检查中断返回后是否运行
& &&&if(P1==0x15) P0=P1;
&&else { P0=0XFF;}
/函数功能:红外线触发的外中断处理函数
void Int0(void) interrupt 0
& &&&EX0=0;& && &//关闭外中断0,不再接收二次红外信号的中断,只解码当前红外信号
& &TH0=0;& && &//定时器T0的高8位清0
& &TL0=0;& && &//定时器T0的低8位清0
& &TR0=1;& &&&//开启定时器T0&&
& &while(IR==0);& && && & //如果是低电平就等待,给引导码低电平计时
& &TR0=0;& && && && && & //关闭定时器T0& &&&
& &LowTime=TH0*256+TL0;&&//保存低电平时间
& &TH0=0;& && &//定时器T0的高8位清0
& &TL0=0;& && &//定时器T0的低8位清0
& &TR0=1;& &&&//开启定时器T0
& &while(IR==1);&&//如果是高电平就等待,给引导码高电平计时
& &TR0=0;& && &&&//关闭定时器T0
& &HighTime=TH0*256+TL0; //保存引导码的高电平长度
& &&&if((LowTime&8500)&&(LowTime&9500)&&(HighTime&4000)&&(HighTime&5000))
& && &//如果是引导码,就开始解码,否则放弃,引导码的低电平计时
& && &&&//次数=9000us/1.085=8294, 判断区间:=+500=8800.
& && & if(DeCode()==1) // 执行遥控解码功能
& & P1=a[2];
& &//beep();//蜂鸣器响一声 提示解码成功
& &EX0=1;& &//开启外中断EX0
& &//beep();
, , , , , , ,
主题帖子积分
初级工程师, 积分 2324, 距离下一级还需 676 积分
初级工程师, 积分 2324, 距离下一级还需 676 积分
主题帖子积分
专家等级: 结帖率:75%
主题帖子积分
初级工程师, 积分 2324, 距离下一级还需 676 积分
初级工程师, 积分 2324, 距离下一级还需 676 积分
你开了T0的中断,但是没给它写中断服务函数吧?
主题帖子积分
实习生, 积分 3, 距离下一级还需 47 积分
实习生, 积分 3, 距离下一级还需 47 积分
主题帖子积分
专家等级: 结帖率:0%
主题帖子积分
实习生, 积分 3, 距离下一级还需 47 积分
实习生, 积分 3, 距离下一级还需 47 积分
在中断的倒数第二行加入 IE0=0;
精华达人奖章
等级类勋章
湍急之河流
发帖类勋章
时间类勋章
技术高手奖章
人才类勋章
热门推荐 /1后使用快捷导航没有帐号?
查看: 2758|回复: 8
在子函数中关闭中断,回到主函数也是关闭的吧
在线时间0 小时
TA的帖子TA的资源
一粒金砂(初级), 积分 0, 距离下一级还需 5 积分
在子函数中关闭中断,回到主函数也是关闭的吧
如果不是,那是为什么呢
在线时间0 小时
TA的帖子TA的资源
还有一点问题
_BIS_SR_IRQ(GIE); 是什么意思
他和_EINT();有什么不同
在线时间0 小时
TA的帖子TA的资源
你这个提问有点别扭 首先要进中断GIE肯定要被置位 因为GIE是SR寄存器里的一个位
在中断之前SR是被圧栈的 进入中断服务程序的时候GIE是自动关闭的(如果强行打开可能会出现中断嵌套) 退出中断后 SR被弹出 所以恢复到进中断之前(还是置位的)。
_BIS_SR_IRQ(GIE); 这句话再中断函数里一点用处都没有,相当于把原本就是1的那个位再或上1
_EINT();这句话在中断函数里,就是允许中断嵌套
在线时间0 小时
TA的帖子TA的资源
在子函数中关闭中断,回到主函数也是关闭的吧
如果不是,那是为什么呢
在中断函数里关闭总中断,退出中断服务程序后会自动打开。但是关闭该模块的中断使能位,退出中断后,该模块中断就是关闭的
在线时间0 小时
TA的帖子TA的资源
在线时间0 小时
TA的帖子TA的资源
如果想在中断返回时不希望再次发生中断,有两种方法:一是修改修改独立模块的中断使能位,二时修改压入堆栈中的SR的GIE位。
在线时间0 小时
TA的帖子TA的资源
要分两种情况:
1. 如果函数为非中断函数,则在函数执行完后,中断允许GIE=0 ;
2. 如果函数为中断函数,则在函数执行完后,中断允许GIE恢复为执行中断前的值,即GIE=1 ;
_BIS_SR_IRQ(GIE) 与_EINT()功能相同.
在线时间0 小时
TA的帖子TA的资源
多谢楼上ggjj!
升读好几个月书!!!!
在线时间28 小时
TA的帖子TA的资源
多谢3楼,学到了
Powered by
逛了这许久,何不进去瞧瞧?第四章1外部中断_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
文档贡献者
评价文档:
喜欢此文档的还喜欢
第四章1外部中断
把文档贴到Blog、BBS或个人站等:
普通尺寸(450*500pix)
较大尺寸(630*500pix)
大小:2.23MB
登录百度文库,专享文档复制特权,财富值每天免费拿!
你可能喜欢查看: 3889|回复: 5
stm32外部中断0-3与中断函数入口不对应,并触发多个中断
新手请教一个STM32外部中断的问题:
1.情况:连接GPIOPC的0、1、2和3和外部中断0、1、2和3,程序debug过程中使用排针调试,在每个中断函数中加入断点。使用IAR。
2.问题:当使用排针触发PC0时,程序停止在void EXTI0_IRQHandler(void)内,但是继续运行时,程序又会停留在void EXTI2_IRQHandler(void)和void EXTI3_IRQHandler(void)内。触发PC1、PC2和PC3都会出现类似触发多个中断和甚至中断程序入口混乱的情况。
3.中断配置程序请看:
& & & & /* 第1步:CONFIGURE GPIO&&*/
& && &&&//PC0
& & & & RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);// #define RCC_APB2Periph_AFIO&&((uint32_t)0x)& && && && && &
& & & & GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 ;
& & & & GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
& & & & GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
& & & & GPIO_Init(GPIOC, &GPIO_InitStructure);
& && &&&//PC1
& && &&&RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);// #define RCC_APB2Periph_AFIO&&((uint32_t)0x)& && && && && &
& & & & GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1 ;
& & & & GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
& & & & GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
& & & & GPIO_Init(GPIOC, &GPIO_InitStructure);
& && &&&//PC2
& && &&&RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);// #define RCC_APB2Periph_AFIO&&((uint32_t)0x)& && && && && &
& & & & GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2 ;
& & & & GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
& & & & GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
& & & & GPIO_Init(GPIOC, &GPIO_InitStructure);
& && &&&//PC3
& && &&&RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC | RCC_APB2Periph_AFIO, ENABLE);// #define RCC_APB2Periph_AFIO&&((uint32_t)0x)& && && && && &
& & & & GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3 ;
& & & & GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;
& & & & GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
& & & & GPIO_Init(GPIOC, &GPIO_InitStructure);
& & & && && && &
& && &&&/* 第2步: Configure EXTI line */
& && &&&//PC0
& && &&&//Selects the GPIO pin used as EXTI Line.&&(GPIOC.0 USED AS EXTI LINE 0)
& && &&&GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource0);
& && &&&EXTI_InitStructure.EXTI_Line = EXTI_Line0;
& && &&&EXTI_InitStructure.EXTI_Mode = EXTI_Mode_I
& && &&&EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_F
& && &&&EXTI_InitStructure.EXTI_LineCmd = ENABLE;
& && &&&EXTI_Init(&EXTI_InitStructure);
& && &&&//PC1
& && &&&//Selects the GPIO pin used as EXTI Line.&&(GPIOC.0 USED AS EXTI LINE 0)
& && &&&GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource1);
& && &&&EXTI_InitStructure.EXTI_Line = EXTI_Line1;
& && &&&EXTI_InitStructure.EXTI_Mode = EXTI_Mode_I
& && &&&EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_F
& && &&&EXTI_InitStructure.EXTI_LineCmd = ENABLE;
& && &&&EXTI_Init(&EXTI_InitStructure);
& && &&&//PC2
& && &&&//Selects the GPIO pin used as EXTI Line.&&(GPIOC.0 USED AS EXTI LINE 0)
& && &&&GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource2);
& && &&&EXTI_InitStructure.EXTI_Line = EXTI_Line2;
& && &&&EXTI_InitStructure.EXTI_Mode = EXTI_Mode_I
& && &&&EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_F
& && &&&EXTI_InitStructure.EXTI_LineCmd = ENABLE;
& && &&&EXTI_Init(&EXTI_InitStructure);
& && &&&//PC3
& && &&&//Selects the GPIO pin used as EXTI Line.&&(GPIOC.0 USED AS EXTI LINE 0)
& && &&&GPIO_EXTILineConfig(GPIO_PortSourceGPIOC, GPIO_PinSource3);
& && &&&EXTI_InitStructure.EXTI_Line = EXTI_Line3;
& && &&&EXTI_InitStructure.EXTI_Mode = EXTI_Mode_I
& && &&&EXTI_InitStructure.EXTI_Trigger = EXTI_Trigger_F
& && &&&EXTI_InitStructure.EXTI_LineCmd = ENABLE;
& && &&&EXTI_Init(&EXTI_InitStructure);
& && && && && &
& && &&&// Configure one bit for preemption priority
& && &&&NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
& && &&&// Enable the GPIOC.0 Interrupt
& && &&&NVIC_InitStructure.NVIC_IRQChannel = EXTI0_IRQn;
& && &&&NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0;
& && &&&NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
& && &&&NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
& && &&&NVIC_Init(&NVIC_InitStructure);
& && &&&// Enable the GPIOC.1 Interrupt
& && &&&NVIC_InitStructure.NVIC_IRQChannel = EXTI1_IRQn;
& && &&&NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1;
& && &&&NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
& && &&&NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
& && &&&NVIC_Init(&NVIC_InitStructure);
& && &&&// Enable the GPIOC.2 Interrupt
& && &&&NVIC_InitStructure.NVIC_IRQChannel = EXTI2_IRQn;
& && &&&NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 2;
& && &&&NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
& && &&&NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
& && &&&NVIC_Init(&NVIC_InitStructure);
& && &&&// Enable the GPIOC.3 Interrupt
& && &&&NVIC_InitStructure.NVIC_IRQChannel = EXTI3_IRQn;
& && &&&NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 3;
& && &&&NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0;
& && &&&NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
& && &&&NVIC_Init(&NVIC_InitStructure);
& && &&&NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0000);
&&* @brief&&This function handles External interrupt Line 0 request.
&&* @param&&None
&&* @retval None
void EXTI0_IRQHandler(void)
&&static char counter = 0;
&&if(EXTI_GetITStatus(EXTI_Line0) != RESET)
&&counter = !
&&if(counter == 0)
&&GPIO_SetBits(GPIOF, GPIO_Pin_9);& & & & /* 关闭LED4 */
&&GPIO_ResetBits(GPIOF, GPIO_Pin_9);& & & & /* 点亮LED4 */
&&/* Clear EXTI_Line0 pending bit */
&&EXTI_ClearITPendingBit(EXTI_Line0);
&&* @brief&&This function handles External interrupt Line 1 request.
&&* @param&&None
&&* @retval None
void EXTI1_IRQHandler(void)
&&static char counter = 0;
&&if(EXTI_GetITStatus(EXTI_Line1) != RESET)
&&counter = !
&&if(counter == 0)
&&GPIO_SetBits(GPIOF, GPIO_Pin_8);& & & & /* 关闭LED3 */
&&GPIO_ResetBits(GPIOF, GPIO_Pin_8);& & & & /* 点亮LED3 */
&&/* Clear EXTI_Line0 pending bit */
&&EXTI_ClearITPendingBit(EXTI_Line1);
&&* @brief&&This function handles External interrupt Line 2 request.
&&* @param&&None
&&* @retval None
void EXTI2_IRQHandler(void)
&&static char counter = 0;
&&if(EXTI_GetITStatus(EXTI_Line2) != RESET)
&&counter = !
&&if(counter == 0)
&&GPIO_SetBits(GPIOF, GPIO_Pin_7);& & & & /* 关闭LED2 */
&&GPIO_ResetBits(GPIOF, GPIO_Pin_7);& & & & /* 点亮LED2 */
&&/* Clear EXTI_Line0 pending bit */
&&EXTI_ClearITPendingBit(EXTI_Line2);
&&* @brief&&This function handles External interrupt Line 3 request.
&&* @param&&None
&&* @retval None
void EXTI3_IRQHandler(void)
&&static char counter = 0;
&&if(EXTI_GetITStatus(EXTI_Line3) != RESET)
&&counter = !
&&if(counter == 0)
&&GPIO_SetBits(GPIOF, GPIO_Pin_6);& & & & /* 关闭LED1 */
&&GPIO_ResetBits(GPIOF, GPIO_Pin_6);& & & & /* 点亮LED1 */
&&/* Clear EXTI_Line0 pending bit */
&&EXTI_ClearITPendingBit(EXTI_Line3);
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x0000);
NVIC_SetVectorTable(NVIC_VectTab_RAM, 0x0000);
都试过,效果一样。
STM32能产生外部中断,但是进错中断函数,并触发多个中断,请问原因。(自己顶一下!!!)
公益广告:本论坛不得使用、宣传Q群。 有讨论请在论坛里进行。 违者将封锁ID.
问题解决了。原来是开发板上的PC0~3连接着同一个芯片,使得这几个引脚“耦合”,互相影响,断开连接后,中断正常。
公益广告:发表招聘帖子需要缴费,有需要可以联系网站工作人员王小姐:.
holmesruan 发表于
问题解决了。原来是开发板上的PC0~3连接着同一个芯片,使得这几个引脚“耦合”,互相影响,断开连接后,中 ...
浪费感情。
往后你搞清楚再发帖问
公益广告:广告只能发在本论坛的广告区,否则将封锁ID。
问题解决了。原来是开发板上的PC0~3连接着同一个芯片,使得这几个引脚“耦合”,互相影响,断开连接后,中 ...
楼主,我的情况类似。。pc8,pc10,pc11连着74lvc4245,5v转为3v,pc10连接到排针的地线时下降沿中断,结果pc8,pc11一起中断。。请问怎么断开连接?
阿莫电子论坛, 原"中国电子开发网"

我要回帖

更多关于 单片机中断函数 的文章

 

随机推荐