单片机中断函数中的全局变量问题

第一次写博客。
今天碰到一个很小,但是很诡异的问题,用的是STC8F2K系列单片机,做的一个简单的驱动板。该板子需要根据按钮和传感器状态来驱动器件,共三个按钮,梳理了程序流程,我用两个外部下降沿中断来连接到按钮。然后呢,我不想在中断函数里写太多代码,便只在中断函数里放了一个全局变量,按下按钮进入中断时改变该变量的值,然后在主程序中判断该值,来执行接下来的程序,部分程序代码如下:

void main()
{   
//	PX0=3;                   // INT0优先级3
//	PX1=0;                   // INT1优先级0
IT0 = 1;                 // 使能INT0下降沿中断
EX0 = 1;                 // 使能INT0中断
 IT1 = 1;                 // 使能INT1下降沿中断
EX1 = 1;                 // 使能INT1中断
EA  = 1;


while(a)
{
		//Y1=ON; 

	
if((SWL==0)&(a==1))
	{
		Delay3s();              
		while(~SWL&a)
		Y2=ON;         		      
		Y2=OFF;                 
		Delay3s();
		if(a==1)
	   J1=ON;                
	}	
	
}

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

中断函数就很简单了,如下:

void INT0_Isr() interrupt 0 using 1
{
					a=1; 

}

void INT1_Isr() interrupt 2 using 1
{

   a=0;
	Y1=OFF;
	Y2=OFF;
	J1=OFF;
//  while(~a);               

}`

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

下载程序到板子调试,死活也不行。用KEIL仿真了一下,竟然又是正常的。然后写了段测试程序,确认可以正常进中断,而且硬件也没问题,去网上搜了一圈,他们说最好要加volatile关键字,我加了,还是不行,又有人说,在中断中使用全局变量,要确保中断函数和声明变量的程序在同一文件,我想了一下,STC又不像STM32,中断向量表是单独放在一个文件里然后允许外部引用的,而且工程里只有一个“stc.h”的头文件,没有其他文件,至于链接和编译的时候,编译器如何把中断函数映射到中断向量,我等菜鸟就不得所知了,不过我觉得这个问题也可以深入研究一下。接下来,我又尝试了用指针的方法访问在中断函数中改变a的值,代码如下:

void INT0_Isr() interrupt 0 using 1
{
					int *b
					b=&a;
					*b=1;	
}

 
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

结果还是不行。到这时候,我已经想放弃这种方式了,但我就是很好奇,中断函数里肯定是可以改变全局变量的值的,为什么我这里就不行呢?型号的问题?
继续查找资料,看到了网友的一句话,他说,你可以在中断函数中改变全局变量的值,但你要确保该值没有在主程序中被占用。
我觉得这个可能是问题所在,于是重新写了简单的小程序验证了一下,代码如下:

void main()
{
PX0=0;                                      // INT0优先级最低
PX1=3;                               
IT0 = 1;                                    //使能INT0下降沿中断
EX0 = 1;  
 IT1 = 1;                                    //使能INT1下降沿中断
EX1 = 1;    		                          	//使能INT0中断
EA = 1;

while(1);
}

void INT1_Isr() interrupt 2 using 1
{
a=1;
}

void INT0_Isr() interrupt 0 using 1
{

    if(a==1)
			P10=0;

}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28

烧录程序,P10对应的小灯终于亮了! 看来这就是问题所在。
我有将上面的程序修改了一下,将主程序中的while(1)改成while(a),再烧录程序,就毫无反应了,为什么?因为主程序中的大循环一直在调用a的值,所以你在中断函数中,无法改变它。那么怎么解决呢?主程序中的循环改成这样:

while(1)
	 {
		 if(a==1)
			 P10=0;
	 }

 
 
  • 1
  • 2
  • 3
  • 4
  • 5

这样就OK了。至于为什么这样就OK了,抱歉,我没有去深入探究,也希望了解的大神可以告知一下。

其实这是一个很小的问题,改下程序就可以绕过去,但可能是钻牛角尖的精神吧,自己想了一下,也算解决了一般。水平有限,仅供大家参考。

另外,我觉得写程序,如果需要在中断中使用全局变量,最好还是加上volatile,像我这种简单的程序可能还无所谓,但是复杂的程序,真的可以省去许多不必要的麻烦,尤其是,这种错误,你的编译器永远不会告诉你。

                                </div>
            <link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-b6c3c6d139.css" rel="stylesheet">
                                            <div class="more-toolbox">
            <div class="left-toolbox">
                <ul class="toolbox-list">
                    
                    <li class="tool-item tool-active is-like "><a href="javascript:;"><svg class="icon" aria-hidden="true">
                        <use xlink:href="#csdnc-thumbsup"></use>
                    </svg><span class="name">点赞</span>
                    <span class="count">1</span>
                    </a></li>
                    <li class="tool-item tool-active is-collection "><a href="javascript:;" data-report-click="{&quot;mod&quot;:&quot;popu_824&quot;}"><svg class="icon" aria-hidden="true">
                        <use xlink:href="#icon-csdnc-Collection-G"></use>
                    </svg><span class="name">收藏</span></a></li>
                    <li class="tool-item tool-active is-share"><a href="javascript:;"><svg class="icon" aria-hidden="true">
                        <use xlink:href="#icon-csdnc-fenxiang"></use>
                    </svg>分享</a></li>
                    <!--打赏开始-->
                                            <!--打赏结束-->
                                            <li class="tool-item tool-more">
                        <a>
                        <svg t="1575545411852" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="5717" xmlns:xlink="http://www.w3.org/1999/xlink" width="200" height="200"><defs><style type="text/css"></style></defs><path d="M179.176 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5718"></path><path d="M509.684 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5719"></path><path d="M846.175 499.222m-113.245 0a113.245 113.245 0 1 0 226.49 0 113.245 113.245 0 1 0-226.49 0Z" p-id="5720"></path></svg>
                        </a>
                        <ul class="more-box">
                            <li class="item"><a class="article-report">文章举报</a></li>
                        </ul>
                    </li>
                                        </ul>
            </div>
                        </div>
        <div class="person-messagebox">
            <div class="left-message"><a href="https://blog.csdn.net/weixin_38832162">
                <img src="https://profile.csdnimg.cn/9/9/2/3_weixin_38832162" class="avatar_pic" username="weixin_38832162">
                                        <img src="https://g.csdnimg.cn/static/user-reg-year/1x/3.png" class="user-years">
                                </a></div>
            <div class="middle-message">
                                    <div class="title"><span class="tit"><a href="https://blog.csdn.net/weixin_38832162" data-report-click="{&quot;mod&quot;:&quot;popu_379&quot;}" target="_blank">weixin_38832162</a></span>
                                        </div>
                <div class="text"><span>发布了1 篇原创文章</span> · <span>获赞 1</span> · <span>访问量 680</span></div>
            </div>
                            <div class="right-message">
                                        <a href="https://im.csdn.net/im/main.html?userName=weixin_38832162" target="_blank" class="btn btn-sm btn-red-hollow bt-button personal-letter">私信
                    </a>
                                                        <a class="btn btn-sm  bt-button personal-watch" data-report-click="{&quot;mod&quot;:&quot;popu_379&quot;}">关注</a>
                                </div>
                        </div>
                </div>
  • 21
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值