|
实现对八位数码管的电路中,让数据从0到7进行循环往右进行显示。
如下图
位数 1 2 3 4 5 6 7 8
显示 0
2 1 0
3 2 1 0
4 3 2 1 0
5 4 3 2 1 0
6 5 4 3 2 1 0
7 6 5 4 3 2 1 0
7 6 5 4 3 2 1
7 6 5 4 3 2
7 6 5 4 3
7 6 5
7 6
7
0
[图1-1 硬件电路图]
单片机的电路采用基本电路来进行实现,目前采用的引脚为P0脚作为八段数据的信号发出脚。P2脚的P2.2跟P2.3引脚分别用作数据信号锁存脚与地址信号锁存脚。从而实现两个硬件的连接,从而得到不同的功能。
这些引脚的改变,可以在对应的程序中进行对于位设置进行配置,可以方便进行改变。
目前用于驱动八段共阴数码管的器件是74LS373,选用的原因只是因为在Proteus中,这个芯片,有对应的仿真的内容,那就只有先用这个来进行搭接。
在实际的电路当中,有些开发板会采用的芯片为,74HC5730来做,当然也都是可以的了。
对共阴数码管进行驱动的时候,需要对于数据引脚的数据收发进行对应配置,具体的操作依据数据手册来进行设置。目前就开始具体地实现程序的配置。
由功能可知:
需要实现数码管的显示<--需要配置对应的延时程序,从而控制显示的时间。
驱动373进行数码管显示<--配置关于数码管信号发送的程序。
其他杂散的,关于引脚定义,段码和位码常量的定义。
以上这些程序的定义就先不在该文章中写了,防止累赘。
在这次的程序中,这个程序的编写,有点欠缺,无法满足各个子程序独立的效果,只能把这个程序先另外拎出来,进行黏贴在下方:
这个程序特殊的地方在于,这个程序将显示的方式,进行了一次大的调整,是从高位开始显示。
void Display(unsigned char FirstBit,unsigned char Num)
{
unsigned char i;
for(i=0;i<Num;i++)
{
DataPort=0; //清空数据,防止有交叠重影
LATCH1=1; //段锁存
LATCH1=0;
DataPort=dofly_WeiMa[i+FirstBit]; //取位码
LATCH2=1; //位锁存
LATCH2=0;
DataPort=TempData[7-i]; //取显示数据,段码
//取反显示顺序,把左移变成右移
LATCH1=1; //段锁存
LATCH1=0;
Delay(200); // 扫描间隙延时,合理设置,避免太长闪烁,太短重影
}
}
[图3-1 主程序流程图]
main()
{
//参数定义部分
unsigned int i,j,k=7,m;
//i用于定义数码管的循环次数,j用于延时,k用于记录当前数码管有多少位数据需要循环。m为总的循环位数
unsigned char *pa=TempData,*pb=DuanMa;//定义两个无符号字符型指针,分别指向两个数组的首地址
//主程序部分
while(1)
{
j++;
if(j==20) //j的数值变化主要用于延时程序,也就是数码管的显示时间
{
j=0; //延时时间到,则重新赋初值
for(i=0;i<(8-k);i++) //将数码管的数据赋值到最右边位置
{
*(pa+k+i)=*(pb+i+m);//将字符数值中的信号传到数据缓冲数组TempData中
}
for(i=0;i<m;i++) //将8位数据进行左移,把右边空出来的数码管进行熄灭
*(pa+8-m+i)=0; //将移出的位的右边进行熄灭灯
if(k>0)
k--;
if(m<8&&k==0)
m++;
else if(m==8)
{m=0;k=7;}
}
Display(0,8);//从第一位开始显示8位数码管
}
}
要实现我们这个程序的目的,首先是需要进行将这个总的步数分为两种,第一种是从0
到76543210
这个阶段。这个时候,需要是一次在程序的左边进行补一位数字,然后将数字进行右移。
当程序右移结束的时候,移动到76543210
这个时候,则需要进入到另一个阶段了,这个时候,是不断地在数字的左边补一,并且继续执行对右边进行去除信息的功能。
为了便于实际的分析,就列一下自己计算的几个关键点把。
对于第一个阶段而言:
k=7,m=0时
*(pa+7+0)=*(pb+0+0)
也就是说,*(pa+7)=*(pb+0)
显示出:0
k=6,m=0时
*(pa+6+0)=*(pb+0+0)
也就是说,*(pa+6)=*(pb+0)
*(pa+6+1)=*(pb+1+0)
也就是说,*(pa+7)=*(pb+1)
显示出:1,0
k=5,m=0时
*(pa+5+0)=*(pb+0+0)
也就是说,*(pa+5)=*(pb+0)
*(pa+5+1)=*(pb+1+0)
也就是说,*(pa+6)=*(pb+1)
*(pa+5+2)=*(pb+2+0)
也就是说,*(pa+7)=*(pb+2)
显示出:2,1,0
其中,其中的其他过程就不进行编写了,下面列这一阶段最后时候
k=1,m=0时,
*(pa+1+0)=*(pb+0+0)
也就是说,*(pa+1)=*(pb+0)
*(pa+1+1)=*(pb+2+0)
也就是说,*(pa+2)=*(pb+1)
...
*(pa+1+6)=*(pb+6+0)
也就是说,*(pa+7)=*(pb+6)
在这个时候,可以发现,再执行k--
时,k已经等于0了,跳出了循环,进入了另一种情况。
此时显示出:6,5,4,3,2,1,0,空
进行下一个循环的时候,k=0,m=1
此时输出,
*(pa+0+0)=*(pb+0+1)
也就是说,*(pa+0)=*(pb+1)
*(pa+0+1)=*(pb+1+1)
也就是说,*(pa+1)=*(pb+2)
...
*(pa+0+6)=*(pb+6+1)
也就是说,*(pa+6)=*(pb+7)
*(pa+0+7)=*(pb+7+1)
也就是说,*(pa+7)=*(pb+6)
而后有一段清除高于*(pa+7)
位的程序。
也就是将
*(pa+7)=0
最终显示为:空,7,6,5,4,3,2,1
往后的结果类似。就不在一一列举了。
下面再记录下最后一个显示:
k=0,m=7时
*(pa+0+0)=*(pb+0+7)
也就是说,*(pa+0)=*(pb+7)
*(pa+0+1)=*(pb+1+7)
也就是说,*(pa+1)=*(pb+8)
...
*(pa+0+7)=*(pb+7+7)
也就是说,*(pa+7)=*(pb+14)
而后有段程序对于,
*(pa+8-7)=0
以及以上都进行清零。从而只留下了,*(pa+0)=7
这个数据。
显示效果为:空,空,空,空,空,空,空,7
最后在,
k=0,m=8时
*(pa+0+0)=*(pb+0+8)
也就是说,*(pa+0)=*(pb+8)
*(pa+0+1)=*(pb+1+8)
也就是说,*(pa+1)=*(pb+9)
...
*(pa+0+7)=*(pb+7+8)
也就是说,*(pa+7)=*(pb+15)
执行后面程序,则对
*(pa+8-8)=0
以及以上都进行清零。从而只留下了,从而整个数据都清零了。
显示效果为:空,空,空,空,空,空,空,空
这个程序,最终的结果,还是没有很好的实现目标。主要是没有实现从(6,5,4,3,2,1,0,空)
到
(7,6,5,4,3,2,1,0)
这个数字的过度。
结果直接跳过了这个过程,从(6,5,4,3,2,1,0,空)
跳到了(空,7,6,5,4,3,2,1)
这个显示效果了。
再有便是程序的独立性还是需要加强一下把。这个显示函数为了功能,进行了调整。
在学习这个程序的过程中,也算是感觉到,思维一定不能跳跃,不然分析这个程序,真的是,很容易无奈,要多花很多功夫。
《德飞莱LY-51S单片机开发板》的样例程序