编写51程序的时候,有时候会在主函数和中断函数里面调用同一个函数,如果正的出现这种情况,编译器会提出 这种警告: *** WARNING L15: MULTIPLE CALL TO SEGMENT(重复调用同一个函数)
这种情况时因为函数发生了重入,
尽管这样出现错误的概率很低,但是一旦出现错误,将会是很讨厌的错误,在网上我看到的一篇博文里面,说这个错误必须引起注意,特别是像我们这种做控制和自动化的,一点小小的错误和异常都可能引起一次事故和灾难,必须小心谨慎。
因为它可能引起程序冲突,导致信号产生尖峰。 产生这一警告的一个根源是:你在主循环 里调用了一个函数(如aaa),而在中断服务函数里,你用调用了这个函数(如aaa)。这样当主循环运行到该函数中 是,一旦产生中断,则在中断里又再次调用该函数!这时,很可能出错! 避免这种情况的方法很多:如,在进中断的时候置需调用该函数的标志,而在主循环中调用该函数。
解决方法:
1、可以定义两个功能相同的函数,在中断和主函数里面分别调用,但是需要很多额外重复函数;
2、在中断函数里面设置一个标志,然后在主循环里面调用该函数。
下面具体说说的我的情况和解决办法。
在主函数里面我多次调用 show_string函数,用TFT来显示需要的信息,当中断产生的时候,我又需要在TFT里面显示其他信息,这样就出现了函数的重入,但是又不能取消,进入中断和主函数都是必须的。
当我用第一种方法来解决的时候,发现需要重新定义的函数太多了,太占内存,不能用。于是考虑第二种方法,在中断里面设置标志,然后在主循环里面实现。
void int0() interrupt 0{ delayms(5); if(k3_set==0){ set_flag = ~set_flag;//标志 chose_flag = 0; ds1302_init();//如果没有这句的话,设置完后又会回到原来的数字 } }
在主循环里面:
while(1){ if(set_flag==0){//正常 ds1302_readtime(); show_string(120,16," ");//刷新提示区,就是这个,不能写在中断里面 } else{ key_init(); }
这样这个问题就解决了。当然,当你调用的函数不是很大的情况下,第一种方法也不错。