注册 登录
电子工程世界-论坛 返回首页 EEWORLD首页 频道 EE大学堂 下载中心 Datasheet 专题
chenht7的个人空间 https://home.eeworld.com.cn/space-uid-490705.html [收藏] [复制] [分享] [RSS]
日志

STC-1-用指针实现数码管循环右移

已有 1099 次阅读2019-6-21 22:41 |个人分类:STC

1. 功能

实现对八位数码管的电路中,让数据从0到7进行循环往右进行显示。

如下图

位数 1 2 3 4 5 6 7 8

显示 0

1 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

2. 硬件电路


[图1-1 硬件电路图]

2.1 单片机控制电路

单片机的电路采用基本电路来进行实现,目前采用的引脚为P0脚作为八段数据的信号发出脚。P2脚的P2.2跟P2.3引脚分别用作数据信号锁存脚与地址信号锁存脚。从而实现两个硬件的连接,从而得到不同的功能。

这些引脚的改变,可以在对应的程序中进行对于位设置进行配置,可以方便进行改变。

2.2 外围电路

目前用于驱动八段共阴数码管的器件是74LS373,选用的原因只是因为在Proteus中,这个芯片,有对应的仿真的内容,那就只有先用这个来进行搭接。

在实际的电路当中,有些开发板会采用的芯片为,74HC5730来做,当然也都是可以的了。

对共阴数码管进行驱动的时候,需要对于数据引脚的数据收发进行对应配置,具体的操作依据数据手册来进行设置。目前就开始具体地实现程序的配置。

3.软件

3.1 相关程序

由功能可知:

需要实现数码管的显示<--需要配置对应的延时程序,从而控制显示的时间。

驱动373进行数码管显示<--配置关于数码管信号发送的程序。

其他杂散的,关于引脚定义,段码和位码常量的定义。

以上这些程序的定义就先不在该文章中写了,防止累赘。

3.2 关键程序-Display()

在这次的程序中,这个程序的编写,有点欠缺,无法满足各个子程序独立的效果,只能把这个程序先另外拎出来,进行黏贴在下方:

这个程序特殊的地方在于,这个程序将显示的方式,进行了一次大的调整,是从高位开始显示。

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.3 主程序

[图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位数码管
}

}

要实现我们这个程序的目的,首先是需要进行将这个总的步数分为两种,第一种是从076543210这个阶段。这个时候,需要是一次在程序的左边进行补一位数字,然后将数字进行右移。

当程序右移结束的时候,移动到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以及以上都进行清零。从而只留下了,从而整个数据都清零了。

显示效果为:空,空,空,空,空,空,空,空


4. 总结

这个程序,最终的结果,还是没有很好的实现目标。主要是没有实现从(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)这个显示效果了。

再有便是程序的独立性还是需要加强一下把。这个显示函数为了功能,进行了调整。

在学习这个程序的过程中,也算是感觉到,思维一定不能跳跃,不然分析这个程序,真的是,很容易无奈,要多花很多功夫。


5. 参考

  1. 《德飞莱LY-51S单片机开发板》的样例程序

评论 (0 个评论)

facelist doodle 涂鸦板

您需要登录后才可以评论 登录 | 注册

热门文章