搜索
bottom↓
回复: 11

LED 点阵左移程序请教,左移,字走的不对。

[复制链接]

出0入0汤圆

发表于 2011-2-28 16:10:00 | 显示全部楼层 |阅读模式
硬件是74ls164控制行扫描,hc595级联控制列数据。字模取字方式是:16×16点阵,字的横向8点构成一字节,左边点在字节的低位,字符点阵四角按右上角→左上角→右下角→左下角取字。字静态显示没有问题。就是左移这个程序实现不了,现象是,一个字移完,下一个字移到一办,前一个字就突然跳成后一个字了。程序如下:

/*-----------------------------// Includes \\----------------------------------*/
#include <reg52.h>
#include <74HC595.H>
#include <74LS164.h>
#include <intrins.h>
typedef unsigned long uint32;
typedef unsigned int uint16;
typedef unsigned char uint8;
/*------------------// Hardware specific configuration \\----------------------*/
//端口定义

//控制管脚信号定义
//#define  HC595_RCK_H    HC595_RCK=1
//#define  HC595_RCK_L    HC595_RCK=0
//#define  HC595_SRCK_H   HC595_SRCK=1
//#define  HC595_SRCK_L   HC595_SRCK=0

uint8 BUFF[14];
//uint8 g_bSystemTime2Ms = 0 ;
//uint8 col ;
//uint8 disrow ;

/*此为16×16点阵中文字库文件,字的横向8点构成一字节,左边点在字节的高位,字符点阵四角
按左上角→右上角→左下角→右下角取字*/
//字体为黑色。程序中需用反码输出
uint8 code hzdot[7][16][2] = {
/*菜   CB2CB */
0x02,0x20,0x7F,0xFF,0x02,0x20,0x02,0x20,0x1F,0xFC,0x10,0x44,0x08,0x88,0x04,0x10,
0x00,0x80,0x7F,0xFE,0x01,0xC0,0x02,0xA0,0x0C,0x90,0x38,0x88,0x10,0x86,0x00,0x80,

/*鸟   CC4F1 */
0x00,0x40,0x00,0x20,0x0F,0xF8,0x08,0x08,0x08,0x48,0x0A,0x88,0x04,0x88,0x00,0x08,
0x3F,0xF8,0x20,0x00,0x20,0x00,0x2F,0xFF,0x20,0x00,0x20,0x00,0x14,0x00,0x08,0x00,

/*学   CD1A7 */
0x10,0x80,0x31,0x08,0x13,0x30,0x09,0x10,0x7F,0xFE,0x20,0x02,0x17,0xF1,0x02,0x00,
0x01,0x00,0x7F,0xFE,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x40,0x00,0x80,

/*习   CCFB0 */
0x00,0x00,0x3F,0xFC,0x20,0x00,0x20,0x10,0x20,0x20,0x20,0xC0,0x28,0x80,0x26,0x00,
0x21,0x80,0x20,0x60,0x20,0x1C,0x20,0x08,0x20,0x00,0x24,0x00,0x28,0x00,0x10,0x00,

/*单   CB5A5 */
0x04,0x10,0x0C,0x60,0x02,0x20,0x1F,0xFC,0x10,0x84,0x1F,0xFC,0x10,0x84,0x10,0x84,
0x1F,0xFC,0x10,0x84,0x00,0x80,0x7F,0xFF,0x00,0x80,0x00,0x80,0x00,0x80,0x00,0x80,

/*片   CC6AC */
0x02,0x00,0x02,0x08,0x02,0x08,0x22,0x08,0x7F,0xF8,0x00,0x08,0x00,0x08,0x00,0x08,
0x0F,0xF8,0x08,0x08,0x08,0x08,0x08,0x08,0x08,0x04,0x08,0x04,0x08,0x02,0x08,0x01,

/*机   CBBFA */
0x00,0x08,0x1F,0x08,0x11,0x08,0x11,0x7F,0x11,0x08,0x11,0x08,0x11,0x1C,0x11,0x2C,
0x11,0x2A,0x11,0x0A,0x10,0x89,0x50,0x88,0x50,0x48,0x50,0x48,0x60,0x28,0x00,0x08
};

uint8 code Hang[16][2] = {
0xff,0xfe,0xff,0xfd,0xff,0xfb,0xff,0xf7,0xff,0xef,0xff,0xdf,0xff,0xbf,0xff,0x7f,
0xfe,0xff,0xfd,0xff,0xfb,0xff,0xf7,0xff,0xef,0xff,0xdf,0xff,0xbf,0xff,0x7f,0xff};

/****************把字模移入数组的子函数********************/
void loadoneline(uint8 words , uint8 disrow )
{
   uint8 s;
   for(s=0;s<7;s++)                          //s为要显示的数字+1
   {
      BUFF[2*s] = hzdot [ words + s ][ disrow ][ 0 ] ;
      BUFF[2*s + 1] = hzdot [ words + s ][ disrow ][ 1 ] ;
   }
}


uint8 two_onebyte ( uint8 h1 , uint8 h2 , uint8 lie )
{
   uint8 temp , tempcol  ;
   if ( lie < 8 ) tempcol = lie;   else tempcol =  lie- 8 ;
   temp = ( h1 >> tempcol )|( h2<<(8-tempcol ));
   return temp;
}

/*******************发送一行的子函数************************/
void sendoneline( uint8 lie )
{
   uint8 s;
   uint8 inc ,temp0 ;
   
   if ( lie < 8 ) inc = 0 ; else inc = 1 ;
   for( s = 0 ; s <= 11 ; s ++ )         //s=2*要显示的数字-1
   {
      temp0 = two_onebyte( BUFF[s + inc +1 ],BUFF [ s + inc ] , lie );
          Ser_IN( ~temp0 ) ;          //8位列数据输出,低电平点亮。
   }
}

/*****************************************************************************
//*****************************************************************************/
void delay_1us(void)                 //1us延时函数
{
    _nop_  ;
}
void delay_nus(unsigned int n)       //N us延时函数
{
   unsigned int i=0;
   for (i=0;i<n;i++)
   delay_1us();
}
//*****************************************************************************
// 名称:main()
// 功能:MAIN Routine
// 入口:无
// 出口:无
// 说明:
//*****************************************************************************
void main( )
{
   uint8 i ;
   static  uint8 word=0 , speed =  5;
   uint8 col = 0 ,disrow ;
   //Timer0Init() ;
   while(1)
   {
     while ( col < 16 )
     {
        for ( i = 0 ; i < speed ; i ++ )
        {
           for ( disrow = 0 ; disrow < 16 ; disrow ++ )
           {
              loadoneline( word , disrow ) ;
              sendoneline( col ) ;
                          Par_OUT_disable ( ) ;     //并行输出禁止
              sendoneline( col ) ;
                          Par_OUT_Enable ( ) ;     //并行输出使能
              Par_OUT( ) ;
              LIE_SCAN( Hang[ disrow ][0]); //发送行选择数据,控制阳极
                          LIE_SCAN( Hang[ disrow ][1]); //发送行选择数据,控制阳极
                          delay_nus( 10 )  ;
           }       
        }
        col ++ ;
     }
     col = 0 ;
     word ++ ;
     if( word >=7)word = 0;//总字数
  }
}
//*****************************************************************************/

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

 楼主| 发表于 2011-2-28 17:02:13 | 显示全部楼层
怎么没人回复啊!自己顶下!

出0入0汤圆

发表于 2012-2-5 21:09:03 | 显示全部楼层
我知道speed那行不对,不是每行显示4次,应该是16行都显示完了,重新刷speed=4次一样的数据才开始移动

出0入0汤圆

发表于 2012-2-7 15:24:49 | 显示全部楼层
http://www.ourdev.cn/bbs/bbs_content.jsp?bbs_sn=5348754&bbs_page_no=1&search_mode=3&search_text=chenxiaolang&bbs_id=1006
这个里面有个左移的显示,实际可行,我试过了

出0入0汤圆

发表于 2012-2-8 09:59:32 | 显示全部楼层
#include<STC89C51.h>
#define uchar unsigned char
#define uint unsigned int
sbit RD1=P3^4; //红色显示信号
sbit GD1=P3^7;  //绿色显示信号
sbit SCLK=P3^3; //595移位脉冲 CLK 上升沿有效
sbit LAT=P3^2; //595输出使能 STR  上升沿有效
sbit OE=P3^5; //138 使能 低电平有效
uchar bdata Temp;
sbit D1 = Temp^7;
sbit D2 = Temp^6;
sbit D3 = Temp^5;
sbit D4 = Temp^4;
sbit D5 = Temp^3;
sbit D6 = Temp^2;
sbit D7 = Temp^1;
sbit D8 = Temp^0;
uchar data Buf[10];    //显示输出缓存,静态显示时为[8],而左移时需多取一个汉字,要不最后一个字显示会异常
uchar data  Scan;
uchar data  col;
uint word;
uchar code Disrow[16] = {0x00,0x04,0x08,0x0C,0x02,0x06,0x0A,0x0E,0x01,0x05,0x09,0x0D,0x03,0x07,0x0B,0x0F};              //如果行扫描引脚排列规则,则可不用此表
uchar code Hz[];
void LoadOneLine(uchar Scan);
void SendOneLine();
void delay();
uchar Two_Onebyte(uchar h1,uchar h2);
void main()
{
char i;   
while(1)
{
    for(col=0;col<16;col++)      //循环16次,点亮并移动一个汉字
   {
      for(i=0;i<10;i++)        //汉字在屏幕上的停留时间(即移动速度快慢)
   {
    for(Scan=0;Scan<16;Scan++) //16行显示循环
     {
         OE = 1;
         LoadOneLine(Scan);
         SendOneLine();
         P2 = Disrow[Scan];
        OE = 0;
         delay();delay();delay();//delay();delay();delay();     //亮度调整
     }
   }     
    }
  col = 0;
  word = word+32;
  if(word>=385)
  word = 0;
}
}

void delay() //1ms延时
{
uchar i;
for(i=0;i<110;i++);
}
void LoadOneLine(uchar Scan)
{
  uchar i;
  for(i=0;i<5;i++)
  {
    Buf[2*i] = ~Hz[word+32*i+Scan*2];
    Buf[2*i+1] = ~Hz[word+32*i+1+Scan*2];
  }
}
void SendOneLine() //写入数据到595
{
  uchar i = 0;
uchar inc;   
if(col<8)
inc = 0;
else
inc = 1;
  for(i=0+inc;i<=7+inc;i++)       //i<=2*要显示的字数-1
  {
  LAT = 0;
  Temp = Two_Onebyte(Buf,Buf);     
    SCLK = 0; RD1 = D1; SCLK = 1;
    SCLK = 0; RD1 = D2; SCLK = 1;   
    SCLK = 0; RD1 = D3; SCLK = 1;
    SCLK = 0; RD1 = D4; SCLK = 1;
    SCLK = 0; RD1 = D5; SCLK = 1;
    SCLK = 0; RD1 = D6; SCLK = 1;
    SCLK = 0; RD1 = D7; SCLK = 1;
    SCLK = 0; RD1 = D8; SCLK = 1;     
  }
LAT = 1;         //上升沿时输出一行数据到点阵
}
uchar Two_Onebyte(uchar h1,uchar h2)
{
uchar temp,tempcol;
if(col<8) tempcol=col;
else tempcol=col-8;    //每个字节8位,故tempcol不能大于8
temp=(h1<<tempcol)|(h2>>(8-tempcol));   //实现左移
return temp;
}


uchar code Hz[768]={
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
};

出0入0汤圆

发表于 2012-2-8 10:04:35 | 显示全部楼层
对比了下你的跟我的这个子程序,//实现左移这里有些不同。你自己再看下看。我的这个是可以正常左移的。而且左移的时候最好先送一个32个字节的00.这样它就会在开始有个过度。不至于显示的时候突然就把第一个字显示出来了。

uchar Two_Onebyte(uchar h1,uchar h2)  
{  
uchar temp,tempcol;  
if(col<8) tempcol=col;  
else tempcol=col-8;    //每个字节8位,故tempcol不能大于8  
temp=(h1<<tempcol)|(h2>>(8-tempcol));   //实现左移  
return temp;  
}


uint8 two_onebyte ( uint8 h1 , uint8 h2 , uint8 lie )
{
   uint8 temp , tempcol  ;
   if ( lie < 8 ) tempcol = lie;   else tempcol =  lie- 8 ;
   temp = ( h1 >> tempcol )|( h2<<(8-tempcol ));
   return temp;
}

出0入0汤圆

发表于 2012-11-26 15:04:46 | 显示全部楼层
mcu_mouse 发表于 2012-2-8 10:04
对比了下你的跟我的这个子程序,//实现左移这里有些不同。你自己再看下看。我的这个是可以正常左移的。而且 ...

你好,可以解释下左移的算法不?谢谢了。

出0入0汤圆

发表于 2012-11-26 15:07:05 | 显示全部楼层
temp=(h1<<tempcol)|(h2>>(8-tempcol));   //实现左移  
能不能解释一下这句,没有想明白,不胜感激!

出0入0汤圆

发表于 2012-11-26 23:11:51 | 显示全部楼层
jinniuxing88 发表于 2012-11-26 15:07
temp=(h1(8-tempcol));   //实现左移  
能不能解释一下这句,没有想明白,不胜感激! ...

你想像一下,这个的字模是取的行的,也就是说一个汉字,16*16点阵,一行就是2个字节,左移的时候就是把第一个字节的数据往高移一位,同时要把第二个字节的最高位补到第一个字节来。所以第二个右移就是把第二个字节的数据不要的移走再与第一个的或在一起就组成了一个新的数据。

出0入0汤圆

发表于 2012-11-27 13:54:19 | 显示全部楼层
mcu_mouse 发表于 2012-11-26 23:11
你想像一下,这个的字模是取的行的,也就是说一个汉字,16*16点阵,一行就是2个字节,左移的时候就是把第 ...

感谢你的回答,我再想一想,

出0入0汤圆

发表于 2014-2-24 22:30:59 | 显示全部楼层
正在研究LED点阵屏左移程序,学习了。谢谢~~~

出0入0汤圆

发表于 2015-11-14 11:11:46 | 显示全部楼层
左移程序,看看,谢谢~
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 00:54

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表