《基于AVR的单片嵌入式系统原理与实践应用》例9 中的中断带来的一个隐藏BUG
觉得可能会出现一个显示BUG。// Timer 0 比较匹配中断服务,2ms定时
interrupt void timer0_comp_isr(void)
{
display(); // LED扫描显示
if (++key_stime_counter >=5)
{
key_stime_counter = 0;
key_stime_ok = 1; // 10ms到
if (++time_counter >= 100)
{
time_counter = 0;
time_1s_ok = 1; // 1s到
}
}
}
在中断中进行时间显示。
而在主循环进行时间调整
while (1)
{
if (time_1s_ok) // 1秒到
{
time_1s_ok = 0;
point_on = ~point_on; // 秒闪烁标志
}
if (key_stime_ok) // 10ms到,键处理
{
key_stime_ok = 0;
if (read_key()) // 调用按键接口程序
{ // 按键确认按下
if (++time >= 60) // 秒加1,以下为时间调整
{
time = 0;
if (++time >= 60)
{
time = 0;
if (++time >= 24) time = 0;
}
}
}
time_to_disbuffer(); // 新调整好的时间送显示缓冲区
}
};
}
问题:
如果时间调整过程(time_to_disbuffer)中,被中断打断,则显示的不一定是正确的时间,而是时间调整的一个中间直,但这个问题可以在(time_to_disbuffer执行完毕)后正常。可否有更好的方案? 这个贴子是书第九章的 会有这样的问题,但在这个例子中没有破坏性的影响,因为2ms后就显示正确的时间了,所以没有考虑如何避免它。
类似time_to_disbuffer()函数称做临界函数,因为它操作的变量可能在中断中也要操作,会发生冲突出错。
简单的解决方式就是在time_to_disbuffer()中加入一个标志位,进入函数置1,退出前清零。在扫描函数中对该标志检测,为1时跳过这次扫描过程。当然此时要求time_to_disbuffer()函数执行时间越短越好。你如果用CVAVR程序向导生成USART程序,也有这样的情况。
你发现这样的问题,说明你已经比较深入了去理解程序了。这样的问题不仅在简单的系统中,就是在32位复杂系统中经常会产生。而且不容易发觉,从而形成BUG,调试起来经常找不到方向。只有非常有经验的人员,才能注意到。 谢谢马老师回答.
页:
[1]