原贴有误已删:https://blog.csdn.net/weixin_50007421/article/details/136138221
今天完善如下:
本意:只是想表达“复杂系统中断里当然尽量不用软延时函数,但简单系统只要心中有数逻辑清楚实测无妨就完全可行”。
但后来感觉还是不求甚解,还是想弄清楚究竟怎么回事,就引入了下面2个具体例子。
ms延时函数就用如下最简代码 (注:MCU11.0592MHz,u8 i,j; u16 x):
void delay_ms(u16 x)
{ u8 i,j;
while(x-- > 0)
{i = 15, j = 90;
do while (--j);
while (--i);
}
}
1.若主程序正在运行delay_ms(100),x=100,已延时50ms时被中断,且中断里有个最简软延时消抖delay_ms(20),x=20,运行结果究竟如何的呢?
中断服务执行完返回主程序delay_ms(100)时,相当于执行delay_ms(20)了,不计其他,原主程序的延时函数实际延时50ms+中断消抖20ms+继续延时20ms=90ms,总延时90mS(缩短了10ms);若中断消抖等延时函数里X相对很小或可忽略不计,是否就相当于原主程序延时函数被中断后就跳过了剩余延时时间?!若个人觉得这个影响不大当然就完全无妨。那么:中断服务执行完返回主程序delay_ms(100)时,为什么相当于执行delay_ms(20)了呢?以及怎么去理解和解决这个问题呢?
有的说:你是用for循环在延时还是while在延时,不管哪一种情况,若中断发生在主程序延时过程中,如果X是局部变量(有个东西叫做栈),两个延时互不干扰,中断返回后继续计数延时。如果X是全局变量,中断返回后,这个X会变得更小(若是从delay函数从0计数)主程序会继续延时80ms...
2.又如:一节课45分钟,30分钟时老师突然“中断”出去接电话10分钟(若中断用同一延时函数,已延时10分钟),老师回来时离下课还有5分钟,那你说他会继续讲几分钟然后下课?
1种可能是15分钟(45-30=15,实际延时10分钟下课)?另一种可能:回来再讲5分钟就下课(45-30-10=5?即提前5分钟下课)?究竟该如何才能明确并选择哪种情况?
有的说:进中断之前,会保持当前场景,且delay形参是以变量而非地址的形式,中断里面的x影响不到主程序里面的x相当于调用了两次delay 两次互不影响...
探讨:
1.留意:Keil的C51编译器缺省是函数不可重入的(当然不是所有不可重入函数在后台和中断中同时调用都会发生问题)。对Keil的设置为大模式和不优化,所有的变量均实际存储在XRAM空间,因此延时函数“delay_ms()”是不可重入的。
中断中延时函数正常退出时,其3个变量的值未必会恢复到它们在主函数中的值:
等中断退出后,i和j的值为0。这时无论做--j或者做--i,其值将变为0xFF,不为0,因此要继续做减一循环,程序原地踏步。但是要把一个16位的长整数减为0,要花不止1秒的时间,
解决Keil的C51程序中断重入问题有两个方法!进一步的理解,请详见qq_25814297-npl的帖子(再次感谢博主):c语言延时函数_子牙篇(2)多任务程序设计中的函数重入问题-CSDN博客文章浏览阅读453次。中断是单片机最重要的功能,对多任务程序设计中的函数重入问题必须要给予足够的重视,下面给出了一个Keil的C51编译器的翻车现场。(一) 函数重入问题如果一个函数如果不受函数递归时或者被中断时被重新执行过的影响,还能继续正常运行下去,称这个函数是“可重入的”,否则称为“不可重入的”。(1)函数的递归调用。递归是一种很重要的计算方法。当一个函数进行递归时,函数从递归点开始又从头开始执行一次本函数,当函..._c语言多线程重入问题有哪些https://blog.csdn.net/weixin_39559333/article/details/110617431
2.本delay_ms()函数中:MCU11.0592MHz;变量定义u8 i,j; u16 x稍有不同;u=unsigned;
以上个人目前理解,欢迎探讨!
————————————————