利用定时器产生时间片的误差造成程序阻塞--蓝桥杯第七届单片机组程序debug

情景描述:我们利用定时器定时2ms,然后利用定时器来定时1s钟。见下面程序:

unsigned int time_flag    //1s定时标志位

void main()
{
    while(1)
        {
            pro();任意的处理函数,在这里的意思是需要处理器一定时间去处理
            if(time_flag == 500)//到达一秒
            {
                time_flag = 0;   //清零,为下一个1s定时
                pro();    //同上
            }
        }
}

void time_2() interrupt 12   //定时器2中断
{
    time_flag++;
}

问题描述:请问上面这样的程序有问题吗?有!并且十分隐蔽。实际上我就遇到了这样的一个问题:实际上,当程序执行接近40s时,if语句里面的内容将不会被执行!!!!但是if外面的语句不会受到影响。

问题分析:我们首先可以想到的是,if语句不执行的原因是其条件不满足。但是为什么条件会不满足呢?每次都有清零的处理啊。在实际debug中,我曾经怀疑过两个中断的优先级导致的错误(实际上我的程序有两个中断),但是事实证明一个中断同样会发生这样的情况。其实还是中断的错!!!如果在if语句执行前,不发生中断,那么当time_flag==500时,就会执行里面的内容。但是当time_flag == 500时,在进入if语句之前发生了中断,那么time_flag++之后就大于500了,那么time_flag就‘永远’不会等于500了。其实它加到65535那也需要两分钟。有人要可能要问,这样的概率也太小了,确实不大。但是在程序执行的时间是很长的,在接近一分钟的时间之内,有近30000次中断,可以确定的是概率绝对不会是30000的高阶无穷小!即必然发生!!!!!!!

问题解决:其实我们知道了异常发生的愿意,解决问题的方法也很简单——对异常情况加以限制。

unsigned int time_flag    //1s定时标志位

void main()
{
    while(1)
        {
            pro();任意的处理函数,在这里的意思是需要处理器一定时间去处理
            if(time_flag == 500)//到达一秒
            {
                time_flag = 0;   //清零,为下一个1s定时
                pro();    //同上
            }
            if(time_flag >500) time_flag = 0;   //对异常情况加以限制!!!!!!关键步骤!!
        }
}

void time_2() interrupt 12   //定时器2中断
{
    time_flag++;
}

有人可能要说,在中断函数中放入if语句就可以避免这种情况的发生了。事实上确实如此,但是我认为这种方法并不是非常好,因为如果我们定时器定时时间非常短的话,在中断函数执行太多语句反而会降低程序的效率。当然这是个人观点,可能是有错误的。但是还有一点,就是放入中断函数中还需要添加标志位,这同时也增大了内存的开销,所以这也是我把if语句放进主函数的原因。

问题的现象大家可以观看我B站的视频,其中有一段的内容是描述这个问题的:

第七届蓝桥杯单片机组程序题zhe_哔哩哔哩_bilibili

(这个bug在视频的后半部分!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值