找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 8501|回復: 9
收起左側(cè)

求助關于點陣移動的問題

[復制鏈接]
ID:29756 發(fā)表于 2011-7-26 11:47 | 顯示全部樓層 |閱讀模式

我用兩個138級聯(lián)作為行驅(qū)動器,8個595作為列驅(qū)動器,下面的程序能實現(xiàn)四個字的靜態(tài)顯示,請問如何實現(xiàn)字的左右移動和上下移動,不甚感激,謝謝。。ㄎ矣玫膮R編)
附件里面有原理圖和程序,請給予指教,萬分感謝!!

點陣.rar (26.35 KB, 下載次數(shù): 73)
回復

使用道具 舉報

ID:29972 發(fā)表于 2011-8-8 09:00 | 顯示全部樓層

自己以前找的,希望對你有用!

 

(2)移位控制... 21


點陣的移位一般有上、下、左、右的移動,這里我們重點講上移和左移,其它同理。

1.       點陣的上移:

點陣的上移相對來說很簡單,看效果圖如下:


源代碼:(該程序?qū)崿F(xiàn)了循環(huán)上移顯示“邢臺”)

/************16*16LED點陣屏顯示*****************/

#include<reg52.h>

 

sbit R="P2"^0;     //數(shù)據(jù)輸入端口

sbit CLK="P2"^1;       // 時鐘信號

sbit STB="P2"^2;        // 鎖存端

char code table[]={

/*--  文字:  邢  --*/

/*--  宋體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,

};

 

void delay(int z)

{

       int x,y;

       for(x=0;x<z;x++)

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

}

 

void WriteByte(char dat)                     //寫一個字節(jié)的數(shù)據(jù)

{

       char i;

       for(i=0;i<8;i++)            //循環(huán)8次把編碼傳給鎖存器

              {

                dat=dat>>1;       //右移一位,取出該字節(jié)的最低位

                R=CY;               //將該字節(jié)的最低位傳給R

                CLK=0;         //將數(shù)據(jù)送出,上升沿

                CLK=1;                   

              }    

}

 

void main()

{

      int num,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]);     //送出一個字節(jié) 

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

                P1=num;     //行選

                STB=1;         //輸出鎖存器中的數(shù)據(jù),下降沿

                STB=0;               

                delay(2);

              }

       }    

}

可以看到這個程序和靜態(tài)顯示的程序沒有太大的差距,主要就是加入了一個move變量來控制移動,WriteByte(table[2*num+move*2])中當move變量變化的時候更改了寫入595中的數(shù)據(jù),正好實現(xiàn)了移動顯示的效果。而speed變量的if判斷語句能夠控制移動速度的大小。下面重點講左移。

2.       點陣的左移:

因為點陣的數(shù)據(jù)最終是一個一個字節(jié)的并行送出的,所以要實現(xiàn)點陣的左移,我們就需要考慮如何才能夠動態(tài)的更改每一個發(fā)送字節(jié)的數(shù)據(jù),而漢字的每一個字節(jié)的編碼是固定的,這里我們可以使用一個數(shù)據(jù)緩沖區(qū)來完成點陣的左移。重點說一下點陣左移中關鍵的一步操作temp=(BUFF>>tempyid) | (BUFF[s+1]<<(8-tempyid))。這里temp作為要發(fā)送的一個字節(jié)數(shù)據(jù),它由數(shù)據(jù)緩沖區(qū)中的數(shù)據(jù)組合而成,并且動態(tài)的變化,大致來說就是首先第一個字節(jié)的數(shù)據(jù)右移tempyid位,第二個字節(jié)的數(shù)據(jù)左移8-tempyid位,兩者相或后組成一個字節(jié)新的數(shù)據(jù),只要我們一直不斷地移位、相或、發(fā)送,就能實現(xiàn)左移的效果。不太好理解,先來看實例(循環(huán)左移顯示“邢臺學院”),效果圖如下:


見源代碼:

#include <AT89x51.H>

#define uchar unsigned char

#define uint unsigned int

uchar yid,h;                     //YID為移動計數(shù)器,H為行段計數(shù)器

uint zimuo;                   //字模計數(shù)器

uchar code hanzi[];           //漢字字模

uchar BUFF[4];               //緩存

void in_data(void);           //調(diào)整數(shù)據(jù)

void rxd_data(void);         //發(fā)送數(shù)據(jù)

void sbuf_out();               //16段掃描

 

uchar code table[]={//篇幅有限,省略編碼};

 

void main(void)

{

 uchar i,d=10;

 yid=0;

 zimuo=0;                                                  

 while(1)

  {

       while(yid<16)                             //數(shù)據(jù)移位。

       {

              for(i=0;i<d;i++)                      //移動速度

               {

               sbuf_out();

         }

               yid++;                        //移動一步

       }

   yid=0;

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

   if(zimuo>=96)                       //到最后從頭開始,有字數(shù)決定

   zimuo=0;

  }

}

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

void sbuf_out()

         {

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

                     {

                     in_data();                            //調(diào)整數(shù)據(jù)

                     rxd_data();                //串口發(fā)送數(shù)據(jù)

            P1=0x7f;                //關閉顯示。

            P1_7=1;                       //鎖存為高,595鎖存信號

                  P1=h;                        //送行選

                                         

                     }

              }

 

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

void in_data(void)

{

 char s;

       for(s=1;s>=0;s--)                  //h為向后先擇字節(jié)計數(shù)器,zimuoo為向后選字計數(shù)器

       {

        BUFF[2*s+1]=table[zimuo+1+32*s+2*h]; //把第一個字模的第一個字節(jié)放入BUFF0

//中,第二個字模的第一個字節(jié)放入BUFF2中

        BUFF[2*s]=table[zimuo+32*s+2*h];     // 把第一個字模的第二個字節(jié)放入BUFF1中,

//第二個字模的第二個字節(jié)放入BUFF3中

       }

}

 

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

void rxd_data(void)                          //串行發(fā)送數(shù)據(jù)

{

  char s;

  uchar inc,tempyid,temp;

  if(yid<8)

    inc=0;

  else

    inc=1;

  for(s=0+inc;s<2+inc;s++)                //發(fā)送2字節(jié)數(shù)據(jù)

       {

         if(yid<8)

      tempyid=yid;

      else

      tempyid=yid-8;

     temp=(BUFF>>tempyid)|(BUFF[s+1]<<(8-tempyid));//h1左移tempyid位后和h2右移8-tempyid相或,取出移位后的數(shù)據(jù)    

 

       SBUF=temp;//把BUFF中的字節(jié)從大到小移位相或后發(fā)送輸出。

       while(!TI);  //注:這里使用了串口,串口數(shù)據(jù)的發(fā)送為最低位在前。

       TI=0;         //等待發(fā)送中斷 

       }

}

首先來看定義的數(shù)據(jù)緩沖區(qū)BUFF[ ],這里一開始將會存儲第一個漢字與第二個漢字的第一行的編碼,該緩沖區(qū)動態(tài)的存儲點陣屏每一行要發(fā)送的數(shù)據(jù),注意這里BUFF的大小為4個字節(jié),比16*16點陣屏要顯示的漢字多了一個漢字行的大小,這一點是必要的,這樣我們才能實現(xiàn)利用該緩沖區(qū)進行左移控制,接著來看in_data(void)函數(shù),利用該函數(shù),我們實現(xiàn)了動態(tài)的修改緩沖區(qū)中的數(shù)據(jù),這里不再詳述過程,重點看程序的注釋即可。然后看rxd_data(void)函數(shù),該函數(shù)的作用正是利用串口串行發(fā)送數(shù)據(jù),也就是上面提到的移位、相或然后發(fā)送,關于在移位過程中的具體實現(xiàn)細節(jié)以及如何協(xié)調(diào)的進行數(shù)據(jù)發(fā)送,首先來看inc變量,該變量決定了從BUFF緩沖區(qū)中的第一個還是第二個數(shù)據(jù)開始讀取,當移位開始后,在移完一個字節(jié)的數(shù)據(jù)之前我們都從BUFF數(shù)據(jù)緩沖區(qū)中的第一個字節(jié)開始讀取,當移完一個字節(jié)后,inc變成1,這時我們從BUFF數(shù)據(jù)緩沖區(qū)中的第二個字節(jié)開始讀取,于此同時后一個字節(jié)總是在和前一個字節(jié)的數(shù)據(jù)進行移位相或,達到慢慢向前推進的效果,這里有一個臨界點,就是當移位滿16位后,即一個漢字移出點陣屏后,這時候我們就需要將數(shù)據(jù)緩沖區(qū)中的數(shù)據(jù)進行更新,即后移一個字,這時數(shù)據(jù)緩沖區(qū)中的數(shù)據(jù)就變成了第二個漢字和第三個漢字的第一行漢字的編碼,以此類推。下面來看sbuf_out()函數(shù),該函數(shù)實現(xiàn)了16行的掃描,最后來看while循環(huán)內(nèi),這時主函數(shù)內(nèi)已經(jīng)很簡單了,首先在while(yid<16)內(nèi),有控制移動速度的for循環(huán),即顯示幾次靜態(tài)的畫面移動一步,而zimuo變量為移位過程中漢字的選擇變量,它每32位的變化,正好是一個16*16漢字的編碼個數(shù)。這樣就完成了整個點陣左移的控制(這里使用了串口實現(xiàn)點陣的左移,當然我們也可以不用串口,關于非串口實現(xiàn)的左移后面介紹),它的過程比較復雜,需反復思考。

回復

使用道具 舉報

ID:28364 發(fā)表于 2012-4-21 19:54 | 顯示全部樓層
很好,很好。
回復

使用道具 舉報

ID:41928 發(fā)表于 2012-6-20 15:58 | 顯示全部樓層

期待中.....

回復

使用道具 舉報

ID:42903 發(fā)表于 2012-10-23 15:31 | 顯示全部樓層

很好哦

回復

使用道具 舉報

ID:42903 發(fā)表于 2012-10-23 16:13 | 顯示全部樓層
二樓好無私啊  謝謝啦
回復

使用道具 舉報

ID:45810 發(fā)表于 2012-10-26 17:11 | 顯示全部樓層
真心非常感謝樓主。
回復

使用道具 舉報

ID:21740 發(fā)表于 2013-9-5 18:35 | 顯示全部樓層
明天試試看!謝謝分享!
回復

使用道具 舉報

ID:52286 發(fā)表于 2013-10-14 00:28 | 顯示全部樓層
支持支持、、
回復

使用道具 舉報

ID:130419 發(fā)表于 2016-10-11 21:12 | 顯示全部樓層
16*128用138和595可不可以玩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網(wǎng)

快速回復 返回頂部 返回列表