下面我们就开始设计数码管计数的程序。首先,设计一个单独的计数程序,即不涉及按键,只是数码管自动地计数,从0到9循环计数,每隔一个时间间隔加一个数,到达9后再从0开始。这个时间间隔也是普通的延时,没有采用精确定时的方式。采用精确定时的方法可以用单片机提供的定时计数方法做,我们在以后讲解。
这个程序的思路很简单,设置一个变量,让它从0到9变化,并逐个送到数码管显示。在送到数码管前,先要把数字变成相应的数码管码段值,才能在数码管显示正确的数字。所以,把数字变成相应的码段值是程序的关键。以下我们列出程序及说明:
除了头文件外,首先定义一个数组,将数码管的码段表存放数组中,以便调用。按照数组的下标,第0个值就是数字0的码段,第1个值就是数字1的码段,依次类推。因此,P0=Tab[i],就把i这个数的码段送到端口P0,使该端口按照码段的值输出电平,从而控制数码管显示i变量中的数字。也就是说,P0=Tab[0],就会在数码管显示0,P0=Tab[9],就会在数码管显示9。
在无限循环中,除了向P0端口发送码段表值、延时以外,还要控制变量i,让它在0到9之间变化。
接着,我们用Keil C51新建工程、新建程序文本、添加程序至工程、设置工程的输出选项可以生成可执行文件、编译工程,直到生成可执行文件,并加载到单片机中(若还不熟悉,请参考前面几讲)。图5-8所示为加载程序后的仿真运行情况。
图5-8 一位数码管自动计数电路
然后,我们来设计采用按钮计数的程序。首先,我们不用中断处理的方式来实现按钮加数和减数的程序。程序及说明如下:
这个程序与上一个程序不同的地方是,把自动计数改为手动计数。根据用户按钮的不同增加或减少计数。首先定义2个按钮S1和S2,分别与P3.2和P3.3相连。判断按钮是否按下就是看该引脚是否为低电平,若S1==0,即按钮1按下,就将计数值p加1,并判断p是否超过9,因为只有一个数码管,最大计数值为9。因此,若超过9就把计数值p改为9。(www.xing528.com)
同理,判断S2是否按下,若S2==0,即按钮2按下,就将计数值p减1,并判断p是否小于1,若小于1就把计数值p改为1。这样,就限定了计数值在1~9之间变化。
循环体的工作就是,输出选定(p值)的码段表值,判断按钮是否按下,根据不同的按钮,增加或减少计数值,在下一次循环输出。图5-9所示为加载程序后的仿真运行情况。
图5-9 一位数码管手动计数的电路
从这个程序看出,主程序的主要工作就是判断按钮是否按下,并作出增加计数或减少计数值。若还有其他工作要做,就会增加程序的复杂度和开发难度。是否有更好的方法,使程序开发更简洁、清晰,这就是中断处理的方法,下面我们就来看一下用中断处理的方式实现上述功能。
与上一个非中断处理程序相比,主程序的循环体变得非常简洁,只有输出码段表和延时。在程序的开始,也没有开关引脚的定义,这是因为外部中断引脚是内定的。但是在主程序开始增加了有关中断处理TCON和IE寄存器的设置,一是打开总允许开关,EX=1。若EX=0就是关闭总允许。二是打开2个外部中断和分允许开关,IT0=1就是打开外部中断0,EX0=1就是打开外部中断0分允许开关。同理,IT1=1就是打开外部中断1,EX1=1就是打开外部中断1分允许开关。这些设置是使用中断处理的前提,也可以在程序中进行变化。
再来看2个中断处理子程序,它的内容就是上一个程序中的判断语句中的内容,增加或减少计数值p的值。中断处理子程序的头部写法是有规定的,其中interrupt 0是外部中断0的子程序,interrupt 2是外部中断1的子程序,不能更改,全部中断编号的定义见上一节的中断编号表,外部中断是0和2,定时/计数中断是1和3,串口中断是4。
从结构上看,中断处理程序更加简洁,设置也不难,只要按规定设置参数和编写中断子程序的头部就可以了。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。