点阵屏显示原理及实验详解.docx

上传人:b****1 文档编号:650033 上传时间:2023-04-29 格式:DOCX 页数:23 大小:23.98KB
下载 相关 举报
点阵屏显示原理及实验详解.docx_第1页
第1页 / 共23页
点阵屏显示原理及实验详解.docx_第2页
第2页 / 共23页
点阵屏显示原理及实验详解.docx_第3页
第3页 / 共23页
点阵屏显示原理及实验详解.docx_第4页
第4页 / 共23页
点阵屏显示原理及实验详解.docx_第5页
第5页 / 共23页
点阵屏显示原理及实验详解.docx_第6页
第6页 / 共23页
点阵屏显示原理及实验详解.docx_第7页
第7页 / 共23页
点阵屏显示原理及实验详解.docx_第8页
第8页 / 共23页
点阵屏显示原理及实验详解.docx_第9页
第9页 / 共23页
点阵屏显示原理及实验详解.docx_第10页
第10页 / 共23页
点阵屏显示原理及实验详解.docx_第11页
第11页 / 共23页
点阵屏显示原理及实验详解.docx_第12页
第12页 / 共23页
点阵屏显示原理及实验详解.docx_第13页
第13页 / 共23页
点阵屏显示原理及实验详解.docx_第14页
第14页 / 共23页
点阵屏显示原理及实验详解.docx_第15页
第15页 / 共23页
点阵屏显示原理及实验详解.docx_第16页
第16页 / 共23页
点阵屏显示原理及实验详解.docx_第17页
第17页 / 共23页
点阵屏显示原理及实验详解.docx_第18页
第18页 / 共23页
点阵屏显示原理及实验详解.docx_第19页
第19页 / 共23页
点阵屏显示原理及实验详解.docx_第20页
第20页 / 共23页
亲,该文档总共23页,到这儿已超出免费预览范围,如果喜欢就下载吧!
下载资源
资源描述

点阵屏显示原理及实验详解.docx

《点阵屏显示原理及实验详解.docx》由会员分享,可在线阅读,更多相关《点阵屏显示原理及实验详解.docx(23页珍藏版)》请在冰点文库上搜索。

点阵屏显示原理及实验详解.docx

点阵屏显示原理及实验详解

标题:

LED点阵屏学习攻略共享资料

LED点阵屏学习攻略

在经历了将近一个学期断断续续的点阵屏学习后,最后终于在AVR平台下完成了128*32点阵屏的无闪烁显示。

现把整个学习过程总结如下:

无论是51单片机还是AVR单片机,点阵屏的显示原理是一样的,所以首先从51讲起。

说明:

以下所有试验如无特殊说明均在KeiluVision3+Proteus6.9SP5下仿真完成。

一.基于51的点阵屏显示:

(1)点亮第一个8*8点阵:

    1.首先在Proteus下选择我们需要的元件,AT89C52、74LS138、MATRIX-8*8-GREEN(在这里使用绿色的点阵)。

在Proteus6.9中8*8的点阵总共有四种颜色,分别为MATRIX-8*8-GREEN,MATRIX-8*8-BLUE,MATRIX-8*8-ORANGE,MATRIX-8*8-RED。

在这里请大家牢记:

红色的为上列选下行选;其它颜色的为上行选下列选!

而所有的点阵都是高电平选中列,低电平选中行!

也就是说如果某一个点所处的行信号为低,列信号为高,则该点被点亮!

此结论是我们编程的基础。

  2.在选择完以上三个元件后,我们开始布线,具体如下图:

 

这里P2是列选,P3连接38译码器后作为行选。

选择38译码器的原因:

38译码器每次可输出相应一个I/O口的低电平,正好与点阵屏的低电平选中行相对,并且节省了I/O口,大大方便了我们的编程和以后的扩展。

3.下面让我们把它点亮,先看一个简单的程序:

(将奇数行偶数列的点点亮,效果如下图)

 

下面是源代码:

/************8*8LED点阵屏显示*****************/

#include

 

voiddelay(intz)//延时函数

{

      intx,y;

      for(x=0;x

             for(y=0;y<110;y++);

}

 

voidmain()

{

      while

(1)

      {

             P3=0;              //行选,选择第一行

             P2=0x55;           //列选,即该行显示的数据

             delay(5);    //延时 

      /*****下同*****/

             P3=2;            //第三行

             P2=0x55;

             delay(5);

 

             P3=4;          //第五行

             P2=0x55;

             delay(5);

 

             P3=6;             //第七行

             P2=0x55;

             delay(5);

      }    

}

上面的程序实现了将此8*8点阵的奇数行偶数列的点点亮的功能。

重点让我们看while循环内,首先是行选P3=0,此时38译码器的输入端为000,则输出端为01111111,即B0端为低电平,此时选中了点阵屏的第一行,接着列选我们给P2口赋0x55,即01010101,此时又选中了偶数列,紧接着延时。

然后分别对第三、五、七行进行相同的列选。

这样就点亮了此点阵屏奇数行偶数列交叉的点。

完成这个程序,我们会发现其实点阵屏的原理是如此简单,和数码管的动态显示非常相似,只不过换了一种方式而已。

4.完成了上面的点亮过程,下面我们让这个8*8的点阵屏显示一个汉字:

“明”

先看效果图:

 

源代码如下:

/************8*8LED点阵屏显示*****************/

#include

 

charcodetable[]={0x0f,0xe9,0xaf,0xe9,0xaf,0xa9,0xeb,0x11};//"明" 字编码

 

voiddelay(intz)//延时函数

{

      intx,y;

      for(x=0;x

             for(y=0;y<110;y++);

}

 

voidmain()

{

      intnum;

      while

(1)  //循环显示

      {

              for(num=0;num<8;num++)       //8行扫描P3行选,P2列选

             {

              P3=num;            //行选

              P2=table[num];  //列选

              delay(5);           //延时

             }

      }    

}

因为要显示一个汉字,这里我们使用了一个数组table[]来存储该字的编码,重点还是来看while循环,首先在for循环内完成对8*8点阵屏的8行依次扫描。

我们来分析第一行的情况即num=0的时候,首先P3=0,选中第一行,然后P2=table[0],即P2等于table数组中第一个数据0x0f,则此时就点亮了第一行相应的点。

接着延时,其他行同理。

这样我们就完成了一个最简单汉字的显示。

(2)16*16点阵的显示原理

1.虽然完成了上面8*8点阵的显示,但是由于点的数量太少以至于它的显示效果并不是很理想,事实上现在大部分点阵的汉字都是16*16显示的,下面让我们来学习16*16点阵的显示。

和上面一样我们先选择元件:

AT89C52,74LS138,,MATRIX-8*8-GREEN,因为要显示16*16的汉字,我们就不能再使用一个38译码器进行行选了,这里我们用两个38译码器组合成一个4选16的译码器(当然也可以使用74159)。

而MATRIX-8*8-GREEN点阵需要4个。

完成后如下图:

 

2.先来看看4选16的译码器是如何工作的,这里有4个输入端a、b、c、d,16个输出端H0~H15,如上图连线后即可完成类似于38译码器一样的工作。

只不过扩展到了16行选。

关于连线的原理这里不再赘述,只要明白38译码器的原理这个可以轻松理解。

接着完成全部布线。

如下图所示:

3.连好线后,P1作为行选,P2、P3一起作为列选。

现在16*16的点阵被分成两块并不完整的部分,我们可以整体移动(包括点阵屏、连线以及连接点,)来方便我们观察显示的效果(最好同时去掉仿真中电平的指示灯)。

接着我们来看一个程序,还是让此点阵屏显示一个汉字:

“明”。

先看效果图:

源代码如下:

/************16*16LED点阵屏显示*****************/

#include

 

charcodetable[]={0x00,0x20,0x20,0x7F,0x7E,0x21,0x22,0x21,

                       0x22,0x21,0x22,0x3F,0x3E,0x21,0x22,0x21,

                       0x22,0x21,0x22,0x3F,0x3E,0x21,0x22,0x21,

                       0x80,0x20,0x80,0x20,0x40,0x28,0x20,0x10};//“明”

voiddelay(intz)

{

      intx,y;

      for(x=0;x

             for(y=0;y<110;y++);

}

 

voidmain()

{

     intnum;

      while

(1)

      {

            for(num=0;num<16;num++)

             {

              P1=num;             //行选

              P2=table[2*num];  //列选

              P3=table[2*num+1]; //列选

              delay

(2);

             }

      }    

}

4..先来看这次使用的table数组,因为是16*16的点阵,所以总共有32个数据,其中第1、2个数据用于第一行的显示,第2、3个数据用于第二行的显示,以此类推,总共16行。

然后还是来看while循环内,同样for循环依次扫描16行,以第一行为例,即num=0时,首先P1=0,选中第一行,P2=table[0]、P3=table[1]送出列选数据,即第一行要显示的两个字节的数据。

其他行同理。

这样很轻松的我们就完成了16*16点阵的显示。

程序虽然完成了,但是回过头来看一看就会发现,我们在这里使用了P2与P3口一起来做列选,浪费了大量的I/O/资源,而且现在点阵屏的大小还只有16*16,如果想要扩展的更大,已经没有足够的I/O口可用了。

所以一定要想出更好的办法进行列选。

5.为了解决上面提到的问题,我们来学习一个新的元件:

74HC595。

它实质上是一个串行移位寄存器,能够实现“串入并出”的功能,关于它的使用我们还是用上一个列子来讲解,先来看看它的实现,如图:

可以看到这里我们仅使用了三个I/O口就完成了列选数据的发送。

主要来看74HC595是如何实现“串入并出”的,这里我们使用了两个595进行了级联,即第二个595的数据输入端连接了第一个595的级联输出口Q7’。

也就是说,我们只需要从第一个595的输入端串行输入数据,便可以实现把数据送入第二个595的功能。

而且595的数量可以进行无限的级联,而不管有多少个595,我们只需要一个数据输入端就可以,这样就大大节省了I/O资源。

对于595的具体使用还是来看程序。

源代码如下:

/************16*16LED点阵屏显示*****************/

#include

 

sbitR="P2"^0;   //数据输入端口

sbitCLK="P2"^1;     //时钟信号

sbitSTB="P2"^2;      //锁存端

charcodetable[]={0x00,0x20,0x20,0x7F,0x7E,0x21,0x22,0x21,

                          0x22,0x21,0x22,0x3F,0x3E,0x21,0x22,0x21,

                          0x22,0x21,0x22,0x3F,0x3E,0x21,0x22,0x21,

                          0x80,0x20,0x80,0x20,0x40,0x28,0x20,0x10};//“明”

voiddelay(intz)

{

      intx,y;

      for(x=0;x

             for(y=0;y<110;y++);

}

 

voidWriteByte(chardat)                    //写一个字节的数据

{

      chari;

      for(i=0;i<8;i++)           //循环8次把编码传给锁存器

             {

              dat=dat>>1;      //右移一位,取出该字节的最低位

              R=CY;              //将该字节的最低位传给R

              CLK=0;       //将数据移入595,上升沿

              CLK=1;                   

             }    

}

 

voidmain()

{

     intnum;

      while

(1)

      {

            for(num=0;num<16;num++)

             {

              WriteByte(table[2*num]);  //送出一个字节 

              WriteByte(table[2*num+1]);

              P1=num;    //行选

              STB=1;       //输出锁存器中的数据,下降沿

              STB=0;              

              delay

(2);

             }

      }    

}

先来看不同之处,这里我们首先位定义了R、CLK、STB,分别对应于74HC595的DS、SH_CP、ST_CP用以实现串行数据输入、数据移位以及并行数据输出。

然后来看WriteByte(chardat)函数,该函数实现了串行向595中输入一个字节数据的功能。

来看for循环,首先dat=dat>>1,把要输入的数据右移一位,这样最低位便进入移位寄存器CY中,紧接着我们让R=CY,把该位传给595的输入端,CLK一个上升沿的跳变就实现了把该位数据移入595的功能。

8次循环便可以将一个字节的数据送出。

重点还是看while循环内,同样也是16行的扫描,然后就是WriteByte(table[2*num])等同于上面的P2=table[2*num],WriteByte(table[2*num+1])等同于P3=table[2*num+1],完成列选,接着行选,然后有一个STB的下降沿的跳变,这个变化能够实现并行输出移位寄存器中的数据。

这样就完成了整个过程。

(3)16*16点阵的移位控制

点阵的移位一般有上、下、左、右的移动,这里我们重点讲上移和左移,其它同理。

1.      点阵的上移:

点阵的上移相对来说很简单,看效果图如下:

源代码:

(该程序实现了循环上移显示“邢台”)

/************16*16LED点阵屏显示*****************/

#include

 

sbitR="P2"^0;   //数据输入端口

sbitCLK="P2"^1;     //时钟信号

sbitSTB="P2"^2;      //锁存端

charcodetable[]={

/*-- 文字:

 邢 --*/

/*-- 宋体12; 此字体下对应的点阵为:

宽x高=16x16  --*/

     0x00,0x00,0xFE,0x3E,0x48,0x22,0x48,0x22,

     0x48,0x12,0x48,0x12,0x48,0x0A,0xFF,0x13,

     0x48,0x22,0x48,0x42,0x48,0x42,0x48,0x46,

     0x44,0x2A,0x44,0x12,0x42,0x02,0x40,0x02,

/*-- 文字:

 台 --*/

/*-- 宋体12; 此字体下对应的点阵为:

宽x高=16x16  --*/

      0x40,0x00,0x40,0x00,0x20,0x00,0x10,0x04,

     0x08,0x08,0x04,0x10,0xFE,0x3F,0x00,0x20,

     0x00,0x08,0xF8,0x1F,0x08,0x08,0x08,0x08,

     0x08,0x08,0x08,0x08,0xF8,0x0F,0x08,0x08,

};

 

voiddelay(intz)

{

      intx,y;

      for(x=0;x

             for(y=0;y<110;y++);

}

 

voidWriteByte(chardat)                    //写一个字节的数据

{

      chari;

      for(i=0;i<8;i++)           //循环8次把编码传给锁存器

             {

              dat=dat>>1;      //右移一位,取出该字节的最低位

              R=CY;              //将该字节的最低位传给R

              CLK=0;       //将数据送出,上升沿

              CLK=1;                   

             }    

}

 

voidmain()

{

     intnum,move,speed;

      while

(1)

      {

            if(++speed>8)  //移动速度控制

              {

                  speed=0;

                    move++;   //移位

                    if(move>16) //是否完成移位一个汉字

                           move=0; //从头开始

              }

              

              for(num=0;num<16;num++)

             {

              WriteByte(table[2*num+move*2]);   //送出一个字节 

              WriteByte(table[2*num+1+move*2]);

              P1=num;    //行选

              STB=1;       //输出锁存器中的数据,下降沿

              STB=0;              

              delay

(2);

             }

      }    

}

可以看到这个程序和静态显示的程序没有太大的差距,主要就是加入了一个move变量来控制移动,WriteByte(table[2*num+move*2])中当move变量变化的时候更改了写入595中的数据,正好实现了移动显示的效果。

而speed变量的if判断语句能够控制移动速度的大小。

下面重点讲左移。

2.      点阵的左移:

因为点阵的数据最终是一个一个字节的并行送出的,所以要实现点阵的左移,我们就需要考虑如何才能够动态的更改每一个发送字节的数据,而汉字的每一个字节的编码是固定的,这里我们可以使用一个数据缓冲区来完成点阵的左移。

重点说一下点阵左移中关键的一步操作temp=(BUFF[s]>>tempyid)|(BUFF[s+1]<<(8-tempyid))。

这里temp作为要发送的一个字节数据,它由数据缓冲区中的数据组合而成,并且动态的变化,大致来说就是首先第一个字节的数据右移tempyid位,第二个字节的数据左移8-tempyid位,两者相或后组成一个字节新的数据,只要我们一直不断地移位、相或、发送,就能实现左移的效果。

不太好理解,先来看实例(循环左移显示“邢台学院”),效果图如下:

见源代码:

#include

#defineucharunsignedchar

#defineuintunsignedint

ucharyid,h;                   //YID为移动计数器,H为行段计数器

uintzimuo;                 //字模计数器

ucharcodehanzi[];         //汉字字模

ucharBUFF[4];             //缓存

voidin_data(void);         //调整数据

voidrxd_data(void);       //发送数据

voidsbuf_out();             //16段扫描

 

ucharcodetable[]={//篇幅有限,省略编码};

 

voidmain(void)

{

 uchari,d=10;

 yid=0;

 zimuo=0;                                                 

 while

(1)

 {

      while(yid<16)                           //数据移位。

      {

             for(i=0;i

              {

              sbuf_out();

        }

              yid++;                       //移动一步

      }

  yid=0;

  zimuo=zimuo+32;                  //后移一个字,

  if(zimuo>=96)                      //到最后从头开始,有字数决定

  zimuo=0;

 }

}

/********************************/

voidsbuf_out()

       {

             for(h=0;h<16;h++) //16行扫描

                    {

                    in_data();                           //调整数据

                    rxd_data();              //串口发送数据

           P1=0x7f;              //关闭显示。

           P1_7=1;                      //锁存为高,595锁存信号

               P1=h;                   

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 总结汇报 > 学习总结

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2