Shi_Tou 发表于 2011-2-28 16:10:00

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

硬件是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 \\----------------------*/
//端口定义

//控制管脚信号定义
//#defineHC595_RCK_H    HC595_RCK=1
//#defineHC595_RCK_L    HC595_RCK=0
//#defineHC595_SRCK_H   HC595_SRCK=1
//#defineHC595_SRCK_L   HC595_SRCK=0

uint8 BUFF;
//uint8 g_bSystemTime2Ms = 0 ;
//uint8 col ;
//uint8 disrow ;

/*此为16×16点阵中文字库文件,字的横向8点构成一字节,左边点在字节的高位,字符点阵四角
按左上角→右上角→左下角→右下角取字*/
//字体为黑色。程序中需用反码输出
uint8 code hzdot = {
/*菜   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 = {
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 = hzdot [ words + s ][ disrow ][ 0 ] ;
      BUFF = 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,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 ;
   staticuint8 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 ]); //发送行选择数据,控制阳极
                          LIE_SCAN( Hang[ disrow ]); //发送行选择数据,控制阳极
                          delay_nus( 10 );
         }       
      }
      col ++ ;
   }
   col = 0 ;
   word ++ ;
   if( word >=7)word = 0;//总字数
}
}
//*****************************************************************************/

Shi_Tou 发表于 2011-2-28 17:02:13

怎么没人回复啊!自己顶下!

wobushi66 发表于 2012-2-5 21:09:03

我知道speed那行不对,不是每行显示4次,应该是16行都显示完了,重新刷speed=4次一样的数据才开始移动

chenxiaolang 发表于 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
这个里面有个左移的显示,实际可行,我试过了

mcu_mouse 发表于 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;    //显示输出缓存,静态显示时为,而左移时需多取一个汉字,要不最后一个字显示会异常
uchar dataScan;
uchar datacol;
uint word;
uchar code Disrow = {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;
      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 = ~Hz;
    Buf = ~Hz;
}
}
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={
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,
};

mcu_mouse 发表于 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;
}

jinniuxing88 发表于 2012-11-26 15:04:46

mcu_mouse 发表于 2012-2-8 10:04 static/image/common/back.gif
对比了下你的跟我的这个子程序,//实现左移这里有些不同。你自己再看下看。我的这个是可以正常左移的。而且 ...

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

jinniuxing88 发表于 2012-11-26 15:07:05

temp=(h1<<tempcol)|(h2>>(8-tempcol));   //实现左移
能不能解释一下这句,没有想明白,不胜感激!

mcu_mouse 发表于 2012-11-26 23:11:51

jinniuxing88 发表于 2012-11-26 15:07 static/image/common/back.gif
temp=(h1(8-tempcol));   //实现左移
能不能解释一下这句,没有想明白,不胜感激! ...

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

jinniuxing88 发表于 2012-11-27 13:54:19

mcu_mouse 发表于 2012-11-26 23:11 static/image/common/back.gif
你想像一下,这个的字模是取的行的,也就是说一个汉字,16*16点阵,一行就是2个字节,左移的时候就是把第 ...

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

BowenQQ 发表于 2014-2-24 22:30:59

正在研究LED点阵屏左移程序,学习了。谢谢~~~

奮闘ing 发表于 2015-11-14 11:11:46

{:lol:}左移程序,看看,谢谢~
页: [1]
查看完整版本: LED 点阵左移程序请教,左移,字走的不对。