首先还是讲一下芯片。先讲164芯片,它用作行扫描,行为低电平有效(0有效)。
,这个芯片叫做移位寄存器,根据芯片手册,把AB相连作为数据输入端,CLK作为时钟端,CLK是上升沿有效,来一个时钟,输出数据往右移动一次。若上电 时芯片输出为 1111 1111 1111 1111,16个高电平,上电时AB为0,时钟信号来了一个上升沿,则AB移入寄存器,这时输出为0111 1111 1111 1111,这时选中了一行,若AB仍然保持为0,再来一个时钟信号时,这时输出为0011 1111 1111 1111,已经移入了两个0了,选中了两行,而点阵是逐行扫描显示的,就是一行一行往下显示,每次只有一行才会显示,切换速度加快你就看起来它们是同时显 示的,上面有两行选中了所以不行。所以第一个时钟信号过后即输出为0111 1111 1111 1111时应该把AB设置为1,下一个时钟信号来时,由于AB为1了,所以输出为1011 1111 1111 1111,也就是说第二个时钟时选中了第二行,以此类推依次选中到16行,当输出为1111 1111 1111 1110时由于再移动一次最低位的0就移出去了,所以这时要把AB改为0了,再来时钟时输出为0111 1111 1111 1111,这就是行扫描。下面将列扫描,列扫描为高电平有效(1有效)。
,这是595芯片,也是一个移位寄存器,和164的不同是有锁存功能。锁存功能意思就是说你的时钟信号在给,数据也随着时钟信号一个一个输入到寄存器,但 是寄存器的输出仍然没有改变,直到锁存引脚有高脉冲时,已经移位好的数据才会输出到引脚。若行数据选中的是第1行时,列数据输出为1110 1110 1110 1110这16个数据时,那么就是隔一个灯亮3个灯。若没有锁存引脚那么,每来一个时钟信号,输出引脚跟着改变,灯的状态一直在变化,直到16次之后才会 正常,这样的话就乱了。
相信很多朋友都喜欢LED点阵屏吧,可是对于初学者而言,可能点阵的驱动会有点困难。现在就此讲解一下点阵的驱动方法。上几个图看看我做的点阵的效果吧。首先上个单色点阵的吧,
,这个有原理图,那么就给大家看看原理图吧,
这个是595芯片,串入并出,作为列输出,注意这个芯片有锁存输出,也就是说只有锁存脚有脉冲信号时输出才会改变,再看看行输出,就是控制选通每一行的,
,这个芯片和595主要的区别是没有锁存输出,为什么行不要锁存输出呢?因为每次选通一行,每来一个时钟信号改变一行,若行为低电平有效,164上电默认 输出为1,则先移入一个0进去,然后一直移入1,直到16行移完,再循环,这里没来一个时钟输出都会变一下,而如果列输出也这样的话,列数据是经过16次 的变化才得到最终的正确数据,而不是一次得到一个正确数据。然后继续下一个啊,这个是双色点阵
,这个其实是红色、绿色、红绿结合(橙色),这个我没原理图,但是这些都可以做,现在要自己分析了,不要原理图!对于大部分点阵都是逐行扫描的,行扫描一 般都是A、B、C、D四根线组成的,再经过译码形成16根行选通信号线,再加上列数据输入线、列时钟线、列锁存线基本就没什么线了,再加个OE吧,这个用 来控制亮度的,红、绿各有自己的数据线,但其他线都是公用的,先查查里面用的芯片,再先选通一行,再写入一个字节数据,看显示出来的和你的数据是怎么样 的。下面展示一下彩色点阵,有三原色的,RGB,扫描方式是分上下两屏同时16行扫描,数据断独立,控制端共用,无原理图
像这样的屏幕一般都有ABCD的,前面说了这个是行扫描,16行的,然后LAT(列锁存),CLK(时钟),每种颜色有独立的数据输入。先讲到这里吧,上传几个程序供大家参考,不是通用的啊,根据原理图更改相应程序。有兴趣的朋友可以交流交流啊。
前面发的程序是买点阵时送的,个人感觉不好,下面是我自己写的:
- /*--------16*48点阵屏的移动显示------------*/
- /*--------16*48点阵屏的移动显示------------*/
- /*--------16*48点阵屏的移动显示------------*/
- /*--------16*48点阵屏的移动显示------------*/
- /*--------16*48点阵屏的移动显示------------*/
- #include < reg51.h>
- #include < intrins.h>
- typedef unsigned char uchar
- typedef unsigned int uint
- #define DATE_OUT P1 //指定P1口做为输出
- sbit DATA=DATE_OUT^0; //列数据输出位
- sbit LCLK=DATE_OUT^1; //列扫描时钟位
- sbit LAT=DATE_OUT^2; //列数据锁存位
- sbit AB =DATE_OUT^3; //行数据输出位
- sbit HCLK =DATE_OUT^4; //行扫描时钟位
- uchar DatCnt = 0;
- idata unsigned char TempDat[6][16]={
- {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},/*" ",0第1个部分的,即第1个8列*/
- {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},/*" ",1第2个部分的,即第2个8列*/
- {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},/*" ",0第3个部分的,即第3个8列*/
- {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},/*" ",1第4个部分的,即第4个8列*/
- {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},/*" ",0第5个部分的,即第5个8列*/
- {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},/*" ",1第6个部分的,即第6个8列*/
- };//缓存数据
-
- //非常好用的字摸软件PCtoLCD2002完美版 字模选项:阳码、行列式、顺向
- code unsigned char DisplayDat[][16]={
- {0xFD,0xFD,0xFD,0xFC,0xC1,0xDD,0xDC,0xD1,0xDD,0xDC,0xC1,0xFD,0xFD,0xFE,0xFF,0xFF},
- {0xFF,0xFF,0xFF,0x1F,0xDF,0xDF,0x5F,0xDF,0xDF,0x1F,0xFF,0xFB,0xFB,0x03,0xFF,0xFF},/*"电",6*/
- {0xFF,0xFE,0xE1,0xFF,0xFD,0xFE,0xFE,0x80,0xFE,0xFE,0xFE,0xFE,0xF6,0xFA,0xFD,0xFF},
- {0xFF,0x0F,0xDF,0xBF,0x7F,0xFF,0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},/*"子",7*/
- {0xFF,0xFF,0xFF,0xE0,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0x81,0xFF,0xFF,0xFF},
- {0xFF,0xFF,0x0F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x03,0xFF,0xFF,0xFF,0xFF},/*"工",8*/
- {0xFF,0xF9,0xC7,0xF7,0xF1,0x87,0xF3,0xE4,0xD7,0xB7,0x76,0xF7,0xF7,0xF4,0xF7,0xFF},
- {0xFF,0xCF,0x2F,0x6F,0x4F,0x3F,0xC7,0x3F,0xBF,0x87,0x3F,0xBF,0x83,0x7F,0xFF,0xFF},/*"程",9*/
- {0xFF,0xFE,0xE1,0xFD,0xFB,0xF0,0xFD,0xFB,0xF7,0xE0,0xFA,0xF6,0xEE,0xDC,0xFE,0xFF},
- {0x9F,0x7F,0xFF,0xBF,0x7F,0xFF,0xBF,0xDF,0x0F,0xEF,0xFF,0x9F,0xE7,0xF7,0xFF,0xFF},/*"系",10*/
- {0xFD,0xFD,0xFD,0xFC,0xC1,0xDD,0xDC,0xD1,0xDD,0xDC,0xC1,0xFD,0xFD,0xFE,0xFF,0xFF},
- {0xFF,0xFF,0xFF,0x1F,0xDF,0xDF,0x5F,0xDF,0xDF,0x1F,0xFF,0xFB,0xFB,0x03,0xFF,0xFF},/*"电",6*/
- {0xFF,0xFE,0xE1,0xFF,0xFD,0xFE,0xFE,0x80,0xFE,0xFE,0xFE,0xFE,0xF6,0xFA,0xFD,0xFF},
- {0xFF,0x0F,0xDF,0xBF,0x7F,0xFF,0x01,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},/*"子",7*/
- {0xFF,0xFF,0xFF,0xE0,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0xFE,0x81,0xFF,0xFF,0xFF},
- {0xFF,0xFF,0x0F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0x03,0xFF,0xFF,0xFF,0xFF},/*"工",8*/
- {0xFF,0xF9,0xC7,0xF7,0xF1,0x87,0xF3,0xE4,0xD7,0xB7,0x76,0xF7,0xF7,0xF4,0xF7,0xFF},
- {0xFF,0xCF,0x2F,0x6F,0x4F,0x3F,0xC7,0x3F,0xBF,0x87,0x3F,0xBF,0x83,0x7F,0xFF,0xFF},/*"程",9*/
- {0xFF,0xFE,0xE1,0xFD,0xFB,0xF0,0xFD,0xFB,0xF7,0xE0,0xFA,0xF6,0xEE,0xDC,0xFE,0xFF},
- {0x9F,0x7F,0xFF,0xBF,0x7F,0xFF,0xBF,0xDF,0x0F,0xEF,0xFF,0x9F,0xE7,0xF7,0xFF,0xFF},/*"系",10*/
- {0xFD,0xFD,0xFD,0xFC,0xC1,0xDD,0xDC,0xD1,0xDD,0xDC,0xC1,0xFD,0xFD,0xFE,0xFF,0xFF},
- {0xFF,0xFF,0xFF,0x1F,0xDF,0xDF,0x5F,0xDF,0xDF,0x1F,0xFF,0xFB,0xFB,0x03,0xFF,0xFF},/*"电",11*/
- {0xF7,0xF7,0xF7,0xEF,0xE8,0xCF,0xAC,0x6F,0xEC,0xEF,0xEC,0xED,0xED,0xEC,0xED,0xFF},
- {0x7F,0xBF,0xFF,0x83,0x7F,0x8F,0x7F,0x8F,0x7F,0x8F,0x6F,0xEF,0x8F,0x7F,0xFF,0xFF},/*"信",12*/
- {0xFF,0xFF,0xFF,0xEF,0xCF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xE7,0xFF,0xFF,0xFF},/*"1",13*/
- {0xFF,0xFF,0xFF,0xE3,0xDB,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xEB,0xF7,0xFF,0xFF},/*"0",14*/
- {0xFF,0xFF,0xFF,0xE3,0xDB,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xDD,0xEB,0xF7,0xFF,0xFF},/*"0",15*/
- {0xFF,0xFF,0xFF,0xEF,0xCF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xE7,0xFF,0xFF,0xFF},/*"1",16*/
- {0xFE,0xFE,0xF2,0x8E,0xEE,0xEA,0xE2,0xCA,0xEA,0xEE,0xE9,0xE5,0x9B,0xFA,0xF7,0xFF},
- {0xFF,0xFF,0xE3,0x1F,0xDF,0xDF,0xC7,0x9F,0xDF,0xDF,0xDF,0xDF,0xC1,0x3F,0xFF,0xFF},/*"班",17*/
- {0xFF,0xFF,0xFD,0xFB,0xFB,0xF7,0xF7,0xF7,0xF7,0xF7,0xF7,0xFB,0xFB,0xFD,0xFE,0xFF},/*"(",0*/
- {0xFF,0xF8,0xF7,0xEF,0xDF,0xBF,0xBF,0xBE,0xBE,0xBF,0xBF,0xDF,0xEF,0xF7,0xF8,0xFF},
- {0xFF,0x1F,0xEF,0xF7,0xFB,0xFD,0xFD,0x7D,0x7D,0xFD,0xFD,0xFB,0xF7,0xEF,0x1F,0xFF},/*"⊙",1*/
- {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xC3,0xFF,0xFF,0xFF},/*"_",2*/
- {0xFF,0xF8,0xF7,0xEF,0xDF,0xBF,0xBF,0xBE,0xBE,0xBF,0xBF,0xDF,0xEF,0xF7,0xF8,0xFF},
- {0xFF,0x1F,0xEF,0xF7,0xFB,0xFD,0xFD,0x7D,0x7D,0xFD,0xFD,0xFB,0xF7,0xEF,0x1F,0xFF},/*"⊙",3*/
- {0xFF,0xFF,0xBF,0xDF,0xDF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xDF,0xDF,0xBF,0x7F,0xFF},/*")",4*/
- {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF},/*" ",5*/
- };
- /*下面函数扫描模式:点阵屏为16*48,我分成了6个16*8的,为了简便我采用
- 16进制写,6个16*8的如下排列
- 1 2 3 4 5 6
- 0xff 0xfe 0xfb 0xfc 0xfe 0x55 第1行 这些数据都是我随便写的,做个假设
- 0xff 0xfe 0xfb 0xfc 0xfe 0x55 第2行
- 0xff 0xfe 0xfb 0xfc 0xfe 0x55 第3行
- 0xff 0xfe 0xfb 0xfc 0xfe 0x55 第4行
- ... ... ... ... ... ... ...
- ... ... ... ... ... ... ...
- 0xff 0xfe 0xfb 0xfc 0xfe 0x55 第15行
- 0xff 0xfe 0xfb 0xfc 0xfe 0x55 第16行
- */
- void Display(uchar flag)
- {
- unsigned char i,j,temp,x; //定义变量
- DATE_OUT = 0XFF; //置位高电平做准备
- AB=0; //将列数据位清0,准备移位,行为低电平有效
- for(i=0;i<16;i++) //因为有16行,所以要16次循环,依次选中1行
- { //循环输出16行数据
- HCLK=0; //为列移位做准备,列移位为上升沿有效
- LAT=0; //为行锁存做准备,行锁存输出为上升沿有效
- for(x=6;x>0;x--) //分成了6个部分,所以循环6次,
- { //若为16*16的点阵,分成两个部分就可以了,循环两次
- if(flag == 1)
- {
- temp = TempDat[x-1][i]; //读取点阵数据做输出,这里用到ia目的是先读取点阵数据的第二位字节,因一行16个点由两个字节组成, //电路中的移位寄存器最后一位对应最后一列,所以要先输出一行中的第二个字节数据
- }
- if(flag == 0) //用于清屏
- temp = 0xff; //由于我的点阵里面用了8550三极管,相当于非门,所以这里高电平为灭
- for(j=0;j<8;j++) //移动列数据,移动6个字节后锁存输出才打开,因为1行的列数据分成了6个字节
- {
- LCLK = 0; //为列移位做准备
- DATA = temp&0x01; //将数据低位做输出,由电路图可知,移位寄存器的最后一位对应最后一列,因此先移最后一位
- temp >>= 1; //将数据缓冲右移一位,为下次输出做准备
- LCLK = 1; //将DATA上的数据移入寄存器
- } //移入单字节结束
- }
- HCLK = 1; //HCLK拉高,列数据移位,相应行拉低,三极管导通输出电量到相应行点阵管阳极(共阳)
- LAT = 1; //LAT拉高,将数据锁存输出到相应行的点阵发光管显示,显示一行后将保持到下一行显示开始
- AB = 1; //列数据位只在第一行时为0,其它时候都为1,当将这个0移入寄存器后,从第一位开始一直移位最后一位, //移位的过程,AB就必需是1,这是因为不能同时有两个及两个以上0的出现,否则显示出乱
- }
- j = 64;
- while(j--); //每一行的显示,保持16个移位时间,因此,最后一行的显示,也要加入保持时间,补尝显示的亮度
- HCLK = 0; //
- HCLK = 1; //将最后一行数据移出
- }
- void DisplayMoveLeft(uint DatNum,uint MoveSpeed)
- {
- uchar NextByte[16];//下半个汉字的数据
- uchar i,j=8,a,b;
-
- for(i=0;i<16;i++)
- {
- NextByte[i]=DisplayDat[DatCnt][i];
- }
- DatCnt++;
- if((DatNum*2)==DatCnt)DatCnt=0;
- while(j--)//8次移位
- {
- for(i=0;i<16;i++)//16个字节移位
- {
- for(a=0;a<5;a++)
- {
- TempDat[a][i]<<=1;
- if(TempDat[a+1][i]&0x80){TempDat[a][i]+=1;}
- }
- TempDat[5][i]<<=1;
- if(NextByte[i]&0x80)
- {
- TempDat[5][i]+=1;
- }
- NextByte[i]<<=1;
- }
- for(b=0;b<MoveSpeed;b++)
- {
- Display(1);
- }
- }
- }
- void main(void) //主入口函数
- {
- Display(0);
- while(1)
- {
- DisplayMoveLeft(30,12);
- }
- }
复制代码
|