由数码管动态显示浅谈单片机程序
时器定时5ms,5ms到后刷新一次数码管,这样一来单片机不会在这里死等,二来数码管显示时间绝对均匀。对于定时器,一般的单片机至少有一个,而且它作为单片机的独立模块,根本不影响cpu工作。以3个数码管为例,其程序代码如下
#define DUAN P1 //宏定义段选
#define WEI P0 //宏定义位选
void timer(); //定时器处理函数,用定时器定时5ms
{
if(定时标志位置一)
{
定时标志清零;
If(T_5ms) //若T_5ms大于0,每5ms减1
T_5ms--;
}
}
if(T_5ms==2)
{
WEI=0; //消影 共阳,共阴为 WEI=0xff
DUAN=code[value_duan1];
WEI= value_wei1;
}
if(T_5ms==1)
{
WEI=0;
DUAN=code[value_duan1];
WEI= value_wei2;
}
if(T_5ms==0)
{
T_5ms=3; //计时寄存器重新赋值
WEI=0;
DUAN=code[value1];
WEI=value2;
}
这样CPU不用在这里死等,每次程序跑到这里时,只需做个判断就好了,5ms到后就进去点亮数码管,否则就不进去,显示效果绝对均匀。同理,诸如键盘扫描程序,延时消抖,都可以采用这种方式,而不用delay。
也许读者可能发现了问题,对,还是有点问题。假若程序在其他地方耗费时间大于5ms的话,那么这里的定时5ms就失去了作用。确实是这样的。实际上对于好程序来说,主循环绝对控制在1ms一下(CPU跑1Mhz,即1条指令1us)。也许你会问,有些模块不可能1ms以内就完成啊。是的,有些时候某些模块确实需要很久才能完成。这就涉及到程序分时分段处理的问题。好比人做事情一样,我这件事今天做不完,但可以明天再做,而且同时今天我也要吃饭、睡觉做其他的事情,而不是说这件事没做完,别的什么也不干了。单片机也是如此。不管在大的程序,都是分时分段处理的,不然CPU会崩溃的,CPU不可能同时把所有的都一起处理了,而是这段时间处理一点,下段时间再处理一点。这样在总的时间上是一样的,CPU完成的事情却翻倍了。说道这里程序主循环控制在1ms绝对不成问题了。在试想一下,在程序里面到处delay是不是很可怕?比如按键,消抖可以delay 10ms,如果是长按键呢?难道要delay 3s或更长?所以说不管从功能上还是程序结构上,delay是绝对不可取的。对于delay,几个us(相当于几个nop指令)还是允许的。
说到这里,程序分时分段思想已经很明白了。虽然说一个大型项目,包括很多模块,比如按键、AD采样、数码管显示(或lcd显示)、PWM输出、UART、IIC通讯等等,但是并不是说每个模块都在同一时间完成。比如按键按一下大概几百毫秒的样子,长按好几秒的样子,主程序不是一直在这里等,而是一遍又一遍的循环扫描,当扫描的按键键值变化而且连续在100ms以内没有变化,那么确认此次为短按键按下。每次在扫描键盘时大概耗费几十us,然后接着以同样的方式扫描其他模块。这样主循环把所有的模块都扫一遍顶多也就几百us的样子。这样说来,一次按键按下事件,程序已经把它分成了大概几百次来完成,即为分时处理。而不是以delay的方式死等这一次事件完成。其他模块都遵循这个道理。
告别delay,主循环while(1)周期做到小于1ms,那么就告别了学校教育从而进入实际应用!为什么学校所教的不是这种思想呢?因为在学校和实践严重脱节,没有考虑过真正的项目。所学的都是一些独立子程序模块。由于子程序结构简单,程序较小,delay无所谓。而把各个模块都加在一起,可能就会出毛病。实际情况要考虑的还多的很,比如功耗、成本等等。在学校只管能搞出结果就不错了,哪管这个芯片多少钱,这个电容多少钱?对于真正的项目应用,实现功能只算很小很小的一部分。由于学校所学和实际脱节,所以这也是当今大学生难找工作的原因之一,这也是当今中国教育的缺陷!当然成为单片机高手,还有很多路要走,了解这些只是一个门槛而已。
数码管动态显示单片机程 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)