打印

LED点阵屏调试手记,过于相信经验,导致浪费了2-3个小时。

[复制链接]
8882|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
oufuqiang|  楼主 | 2009-11-15 02:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
今天在柳州的旧货市场淘到一块80X16的点阵屏。老板开价25块,但是点阵屏的板子很脏,而且PCB上的印制线也有被刮断的线,需要维修才能使用。经过一番讨价还价,以18块钱成交。从外观上看,这是一块双色屏,接口也是主流接口,信号线分别有ABCD四根行选择线,DR、DG两条点阵数据线,分别是红点阵数据和绿点阵数据。三根控制线,分别是CLK,STB,OE。和常见的屏是一样的。回来之后就对这块屏进行清洗,晾干。吃完饭之后就开始进行调试和驱动程序的编写。因为上个星期买到一个小LED点阵已经调试成功,所以受前一次经验的影响,让我走了一个大弯路。实在是不应该,足足浪费我2-3个小时。
        首先说说原来的小点阵芯片情况:小点阵使用2片138做行选择译码,595做控制输出,当然前面还有74HC245做信号的缓冲。小点阵屏只要接上电源,并将OE拉低,点阵即可点亮。随后就可以依次进行ABCD\SDA\SCK\STB的信号调试了。小屏的调试过程中还是很顺利的。在后来的驱动程序编写中虽然有些困难,但是依然较为顺利的完成了。
        再看看这次的大点阵屏:采用的芯片基本一致,也是138+595+245,但是这块屏上多了一块74HC04,经过观察,发现该74HC04是与译码芯片138相连的。因此猜测是用于信号整形,应该没有太多的不同。
        首先是修复受损的PCB导线。用砂纸轻轻打磨阻焊层,然后用剪下的电阻管脚连接断裂处,再用万用表检测连通情况确认修复成功后给打过补丁的地方封上硅胶保护。修复完成后按原方法给屏接上电源后,拉低OE,屏不亮。不管OE接高电平还是低电平,屏始终不亮。晕倒了。于是怀疑是不是还有线没有补好,就又回头花了10分钟寻找,无果。于是怀疑该屏是不是被雷击过,遂拆下信号缓冲芯片74HC245进行测试,结果没有问题,又将74HC04拆下测试,也没有问题。再将其焊回电路板。这一拆一试就花了我一个小时的时间,因为我没有热风枪,用电烙铁堆焊拆贴片的芯片是比较麻烦的。再次怀疑PCB板有霉断的地方,又用万用表检测,花去20分钟。无果。于是进入盲试阶段,将信号线全部接到轻触开关上,随意的按动开关。起初按动的速度比较慢,屏没有反应,后来有一次不经意的快速按动了一下按钮,屏闪了一下。黑黑,这让我很兴奋。仔细一看,原来按动的是D信号线,但再次按动D,屏也不闪。结果快速的按动D信号线(即快速的给D发送0,1电平),屏跟着闪烁起来了。倒塌了,难道这个屏对于慢速的扫描信号不认同的,之后行扫描频率达到一定值时才允许通过吗?马上写一个程序测试。
void main()
  {
  speed=25;
  while(1)
    {
P0--;
delay(speed);
if(KEY==0)
   {speed++;}
if(KEY2==0)
   {speed--;}
}
  }
        果然不出所料,当ABCD扫描频率低时,屏不工作,随着扫描频率的增加,LED屏开始隔行点亮,当频率在20多HZ以上时,LED逐行点亮了。
        此时再回头看看74HC04的外围电路不像我们常用的都是接数字逻辑元件,而是接了两颗贴片的1N4148,电阻,电容等元件。原来这个74HC04跟外围元件构成了触发器,当频率不足时就会关闭138的输出,屏自然不亮了。
        接下来开始测试CLK\SDA\STB\RED信号,都很顺利,最后测试GREEN信号时发现不起作用,这是为什么呢?原来虽然点阵用的是双色的点阵,但是电路板上的另一串控制绿色点的595并没有焊接,所以就没有绿色了。于是想用镊子手动给8X8点阵加电压点亮绿色的点,却怎么也点不亮,仔细观察8X8的点阵发现虽然每颗LED里面都有3个电极,但是实际上只安装了一颗LED管芯,倒塌了。看来这块屏没有什么神秘之处了。紧接着就开始程序的移植,把原来驱动小点阵的程序修改修改,就成功的驱动了这块点阵。在程序上倒是没有费太多的周折。
        由于这次过于相信自己的经验而导致浪费了大量的时间,这确实不应该,希望有玩LED点阵的朋友不要犯同样的错误了。
■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
        附:程序

相关帖子

沙发
oufuqiang|  楼主 | 2009-11-15 03:01 | 只看该作者
#include <reg52.h>

sbit UPD = P1^4;//更新允许.上跳变更新输出
sbit CLK = P1^5;//移位时钟,上升沿移动数据
sbit SDA = P1^6;//数据线,低电平点亮LED
sbit OEN = P1^7;//输出允许控制,低电平允许显示
sbit SPEEDUP=P2^0;//滚屏速度增加
sbit SPEEDDOWN=P2^1;//滚屏速度减慢
sbit pause=P2^2;//暂停滚屏
sbit turnleft=P2^3;//左转
sbit turnright=P2^4;//右转
sbit slow_down=P2^5;//刹车
bit gunping;//是否滚屏
bit disp_on;//是否显示
bit disp_flash;//是否闪烁显示
unsigned int zhou_ping,speed;//走屏计数变量,速度控制变量
unsigned int pian_yi_liang;//刷新显示偏移量
unsigned char hang;//当前扫描行
unsigned char san_shuo;//闪烁计数变量
unsigned char *disp;//显示指针
unsigned char code linescan[]={15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0};
unsigned char code right[]={点阵数据};
unsigned char code left[]={点阵数据};
unsigned char code STOP[]={点阵数据};
unsigned char code LEDDOT[]={点阵数据};

void send595(unsigned char sendata)
  {
  if(disp_on)
  {
  CLK=0;//拉低时钟线
  SDA=sendata&0x01;//提取最低位
  CLK=1;//数据移入
  CLK=0;
  SDA=sendata&0x02;//提取最低位
  CLK=1;//数据移入
  CLK=0;
  SDA=sendata&0x04;//提取最低位
  CLK=1;//数据移入
  CLK=0;
  SDA=sendata&0x08;//提取最低位
  CLK=1;//数据移入
  CLK=0;
  SDA=sendata&0x10;//提取最低位
  CLK=1;//数据移入
  CLK=0;
  SDA=sendata&0x20;//提取最低位
  CLK=1;//数据移入
  CLK=0;
  SDA=sendata&0x40;//提取最低位
  CLK=1;//数据移入
  CLK=0;
  SDA=sendata&0x80;//提取最低位
  CLK=1;//数据移入
  CLK=0;
  }
  else
  {
  SDA=1;CLK=0;
  CLK=1;CLK=0;CLK=1;CLK=0;CLK=1;CLK=0;CLK=1;CLK=0;
  CLK=1;CLK=0;CLK=1;CLK=0;CLK=1;CLK=0;CLK=1;CLK=0;
  }
  }

void ledlinesend(unsigned int line)
  {
  unsigned char sdata;//临时数据
  UPD=0;//冻结595输出
  sdata=disp[line*10];//取对应行第一字节数据
  send595(sdata);
  sdata=disp[line*10+1];//取对应行第一字节数据
  send595(sdata);
  sdata=disp[line*10+2];//取对应行第一字节数据
  send595(sdata);
  sdata=disp[line*10+3];//取对应行第一字节数据
  send595(sdata);
  sdata=disp[line*10+4];//取对应行第一字节数据
  send595(sdata);
  sdata=disp[line*10+5];//取对应行第一字节数据
  send595(sdata);
  sdata=disp[line*10+6];//取对应行第一字节数据
  send595(sdata);
  sdata=disp[line*10+7];//取对应行第一字节数据
  send595(sdata);
  sdata=disp[line*10+8];//取对应行第一字节数据
  send595(sdata);
  sdata=disp[line*10+9];//取对应行第一字节数据
  send595(sdata);
  UPD=1;//595输出
  }
void LED_shuaxin(void)
  {
  hang++;
  OEN=1;//关闭显示(黑屏)
  ledlinesend((hang&0x0f)+pian_yi_liang);
  P3=linescan[hang&0x0f];
  OEN=0;//显示
  }
void Timer0(void) interrupt 1
  {
  TH0=(65536-2000)/256;
  TL0=(65536-2000)%256;
  zhou_ping++;//走屏速度延时变量
if(zhou_ping>=speed)//判断毫秒数是否到达预定速度
   {
   zhou_ping=0;//辅助变量复位
   if(gunping)//是否允许滚屏
     {
  pian_yi_liang=pian_yi_liang+16;//换一屏数据
  }
   if(pian_yi_liang>288)//判断内容是否显示完毕
     {
  pian_yi_liang=0;//返回头头开始
  }
   if(pause==0)//判断滚屏暂停按钮是否按下
     {
  gunping=!gunping;//启动、暂停
  }
   }
  LED_shuaxin();//每毫秒刷新一次LED屏
  }
void Timer1(void) interrupt 3 using 1
  {
  TH1=(65536-50000)/256;//置初值
  TL1=(65536-50000)%256;
  san_shuo++;//闪烁辅助变量
  if(san_shuo>=3&&disp_flash)//闪烁频率控制,是否闪烁
    {
san_shuo=0;//辅助变量清零
disp_on=!disp_on;//闪烁
}
  if(SPEEDUP==0&&speed>=200)//调整内容切换频率
{
speed-=10;//增加速度
}
  if(SPEEDDOWN==0&&speed<10000)//调整内容切换频率
{
speed+=10;//降低速度
}
  }

void init(void)
  {
  TMOD=0X11;//定时器方式1
  ET0=1;//打开T0中断
  ET1=1;//打开T1中断
  TR0=1;//T0运行
  TR1=1;//T1运行
  PX0=1;//T0优先
  EA=1;//总中断使能
  }
void main(void)
  {
  speed=2000;//开机设置内容更新频率
  disp=&LEDDOT;//置显示指针
  init();//初始化
  disp_on=1;//打开显示
  gunping=0;//允许切换内容
  while(1)
    {
   if(turnleft==0)//左转?
     {
  disp=&left;
  pian_yi_liang=0;
  disp_flash=1;
  gunping=0;
  while(turnleft==0);
  disp=&LEDDOT;
  disp_flash=0;
  gunping=1;
  disp_on=1;
  }
   if(turnright==0)//右转??
     {
  disp=&right;
  pian_yi_liang=0;
  disp_flash=1;
  gunping=0;
  while(turnright==0);
  disp=&LEDDOT;
  disp_flash=0;
  gunping=1;
  disp_on=1;
  }
   if(slow_down==0)//刹车??
     {
  disp=&STOP;
  pian_yi_liang=0;
  disp_flash=1;
  gunping=0;
  while(slow_down==0);
  disp=&LEDDOT;
  disp_flash=0;
  gunping=1;
  disp_on=1;
  }
}
  }

使用特权

评论回复
板凳
ningling_21| | 2009-11-15 09:07 | 只看该作者
手头有一个LED模块组成的小点阵,16×32个点的,但是很奇怪,只能当作16个点的流水灯来用,
上面的控制芯片是4个595+MOS管,引出脚STB,CLK,DAT,VCC,GND,没有看到138之类的其他芯片......

使用特权

评论回复
地板
xwj| | 2009-11-15 10:21 | 只看该作者
LS再去查查,应该是你没用对

使用特权

评论回复
5
宇容创行| | 2009-11-15 20:15 | 只看该作者
就是个狗,防止死机烧坏某一行用的

使用特权

评论回复
6
lidaji0| | 2011-11-29 23:04 | 只看该作者
学习了

使用特权

评论回复
7
huzaizai007| | 2011-11-30 11:02 | 只看该作者
还有这种设计……受教了……

使用特权

评论回复
8
zxcscm| | 2011-11-30 12:02 | 只看该作者
宝贵经验 感谢分享

使用特权

评论回复
9
fangfei036| | 2012-5-31 09:54 | 只看该作者
简直是雪中送炭啊

使用特权

评论回复
10
5swords| | 2015-10-18 00:08 | 只看该作者
:D

使用特权

评论回复
11
xiao_huang| | 2015-10-21 22:39 | 只看该作者
中断里面太多东西了

使用特权

评论回复
12
xiao_huang| | 2015-10-21 22:44 | 只看该作者
xiao_huang 发表于 2015-10-21 22:39
中断里面太多东西了

函数不应使用不属于自己模块的全局变量

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

106

主题

1410

帖子

20

粉丝