LED點陣編程.doc_第1頁
LED點陣編程.doc_第2頁
LED點陣編程.doc_第3頁
LED點陣編程.doc_第4頁
LED點陣編程.doc_第5頁
已閱讀5頁,還剩20頁未讀 繼續(xù)免費閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)

文檔簡介

一基于51的點陣屏顯示:(1)點亮第一個8*8點陣: 1.首先在Proteus下選擇我們需要的元件,AT89C52、74LS138、MATRIX-8*8-GREEN(在這里使用綠色的點陣)。在Proteus 7.5中8*8的點陣總共有四種顏色,分別為MATRIX-8*8-GREEN,MATRIX-8*8-BLUE,MATRIX-8*8-ORANGE ,MATRIX-8*8-RED。在這里請大家牢記:紅色的為上列選下行選;其它顏色的為上行選下列選!而所有的點陣都是高電平選中列,低電平選中行!也就是說如果某一個點所處的行信號為低,列信號為高,則該點被點亮!此結(jié)論是我們編程的基礎(chǔ)。 2.在選擇完以上三個元件后,我們開始布線,具體如下圖:這里P1是列選,P0連接38譯碼器后作為行選。選擇38譯碼器的原因:38譯碼器每次可輸出相應(yīng)一個I/O口的低電平,正好與點陣屏的低電平選中行相對,并且節(jié)省了I/O口,大大方便了我們的編程和以后的擴展。3.下面讓我們把它點亮,先看一個簡單的程序:(將奇數(shù)行偶數(shù)列的點點亮,效果如下圖)下面是源代碼:/*8*8LED點陣屏顯示*/#includevoid delay(int z) /延時函數(shù) int x,y; for(x=0;xz;x+) for(y=0;y110;y+);void main() while(1) P0=0; /行選,選擇第一行 P1=0x55; /列選,即該行顯示的數(shù)據(jù) delay(5); /延時 /*下同*/ P0=2; /第三行 P1=0x55; delay(5); P0=4; /第五行 P1=0x55; delay(5); P0=6; /第七行 P1=0x55; delay(5); 上面的程序?qū)崿F(xiàn)了將此8*8點陣的奇數(shù)行偶數(shù)列的點點亮的功能。重點讓我們看while循環(huán)內(nèi),首先是行選P3=0,此時38譯碼器的輸入端為000,則輸出端為01111111,即B0端為低電平,此時選中了點陣屏的第一行,接著列選我們給P2口賦0x55,即01010101,此時又選中了偶數(shù)列,緊接著延時。然后分別對第三、五、七行進行相同的列選。這樣就點亮了此點陣屏奇數(shù)行偶數(shù)列交叉的點。完成這個程序,我們會發(fā)現(xiàn)其實點陣屏的原理是如此簡單,和數(shù)碼管的動態(tài)顯示非常相似,只不過換了一種方式而已。4.完成了上面的點亮過程,下面我們讓這個8*8的點陣屏顯示一個漢字:“明”先看效果圖:源代碼如下:/*8*8LED點陣屏顯示*/#includechar code table=0x0f,0xe9,0xaf,0xe9,0xaf,0xa9,0xeb,0x11; /明 字編碼 void delay(int z) /延時函數(shù) int x,y; for(x=0;xz;x+) for(y=0;y110;y+);void main() int num; while(1) /循環(huán)顯示 for(num=0;num8;num+) /8行掃描 P3行選,P2列選 P03=num; /行選 P1=tablenum; /列選 delay(5); /延時 因為要顯示一個漢字,這里我們使用了一個數(shù)組table 來存儲該字的編碼,重點還是來看while循環(huán),首先在for循環(huán)內(nèi)完成對8*8點陣屏的8行依次掃描。我們來分析第一行的情況即num=0的時候,首先P3=0,選中第一行,然后P2=table0,即P2等于table數(shù)組中第一個數(shù)據(jù)0x0f,則此時就點亮了第一行相應(yīng)的點。接著延時,其他行同理。這樣我們就完成了一個最簡單漢字的顯示。(2)16*16點陣的顯示原理1.雖然完成了上面8*8點陣的顯示,但是由于點的數(shù)量太少以至于它的顯示效果并不是很理想,事實上現(xiàn)在大部分點陣的漢字都是16*16顯示的,下面讓我們來學(xué)習(xí)16*16點陣的顯示。和上面一樣我們先選擇元件:AT89C52,74LS138,,MATRIX-8*8-GREEN,因為要顯示16*16的漢字,我們就不能再使用一個38譯碼器進行行選了,這里我們用兩個38譯碼器組合成一個4選16的譯碼器(當然也可以使用74159)。而MATRIX-8*8-GREEN點陣需要4個。完成后如下圖:2.先來看看4選16的譯碼器是如何工作的,這里有4個輸入端a、b、c、d,16個輸出端H0H15,如上圖連線后即可完成類似于38譯碼器一樣的工作。只不過擴展到了16行選。關(guān)于連線的原理這里不再贅述,只要明白38譯碼器的原理這個可以輕松理解。接著完成全部布線。如下圖所示:3.連好線后,P1作為行選,P2、P3一起作為列選。現(xiàn)在16*16的點陣被分成兩塊并不完整的部分,我們可以整體移動(包括點陣屏、連線以及連接點,)來方便我們觀察顯示的效果(最好同時去掉仿真中電平的指示燈)。接著我們來看一個程序,還是讓此點陣屏顯示一個漢字:“明”。先看效果圖:源代碼如下:/*16*16LED點陣屏顯示*/#includechar code table=0x00,0x20,0x20,0x7F,0x7E,0x21,0x22,0x21, 0x22,0x21,0x22,0x3F,0x3E,0x21,0x22,0x21, 0x22,0x21,0x22,0x3F,0x3E,0x21,0x22,0x21, 0x80,0x20,0x80,0x20,0x40,0x28,0x20,0x10; / “明” void delay(int z) int x,y; for(x=0;xz;x+) for(y=0;y110;y+);void main() int num; while(1) for(num=0;num16;num+) P1=num; /行選 P2=table2*num; /列選 P3=table2*num+1; /列選 delay(2); 4.先來看這次使用的table數(shù)組,因為是16*16的點陣,所以總共有32個數(shù)據(jù),其中第1、2個數(shù)據(jù)用于第一行的顯示,第2、3個數(shù)據(jù)用于第二行的顯示,以此類推,總共16行。然后還是來看while循環(huán)內(nèi),同樣for循環(huán)依次掃描16行,以第一行為例,即num=0時,首先P1=0,選中第一行,P2=table0、P3=table1送出列選數(shù)據(jù),即第一行要顯示的兩個字節(jié)的數(shù)據(jù)。其他行同理。這樣很輕松的我們就完成了16*16點陣的顯示。程序雖然完成了,但是回過頭來看一看就會發(fā)現(xiàn),我們在這里使用了P2與P3口一起來做列選,浪費了大量的I/O/資源,而且現(xiàn)在點陣屏的大小還只有16*16,如果想要擴展的更大,已經(jīng)沒有足夠的I/O口可用了。所以一定要想出更好的辦法進行列選。5.為了解決上面提到的問題,我們來學(xué)習(xí)一個新的元件:74HC595。它實質(zhì)上是一個串行移位寄存器,能夠?qū)崿F(xiàn)“串入并出”的功能,關(guān)于它的使用我們還是用上一個列子來講解,先來看看它的實現(xiàn),如圖:可以看到這里我們僅使用了三個I/O口就完成了列選數(shù)據(jù)的發(fā)送。主要來看74HC595是如何實現(xiàn)“串入并出”的,這里我們使用了兩個595進行了級聯(lián),即第二個595的數(shù)據(jù)輸入端連接了第一個595的級聯(lián)輸出口Q7。也就是說,我們只需要從第一個595的輸入端串行輸入數(shù)據(jù),便可以實現(xiàn)把數(shù)據(jù)送入第二個595的功能。而且595的數(shù)量可以進行無限的級聯(lián),而不管有多少個595,我們只需要一個數(shù)據(jù)輸入端就可以,這樣就大大節(jié)省了I/O資源。對于595的具體使用還是來看程序。源代碼如下:/*16*16LED點陣屏顯示*/#includesbit R=P20; /數(shù)據(jù)輸入端口 sbit CLK=P21; / 時鐘信號 sbit STB=P22; / 鎖存端 char code table=0x00,0x20,0x20,0x7F,0x7E,0x21,0x22,0x21, 0x22,0x21,0x22,0x3F,0x3E,0x21,0x22,0x21, 0x22,0x21,0x22,0x3F,0x3E,0x21,0x22,0x21, 0x80,0x20,0x80,0x20,0x40,0x28,0x20,0x10; / “明” void delay(int z) int x,y; for(x=0;xz;x+) for(y=0;y110;y+);void WriteByte(char dat) /寫一個字節(jié)的數(shù)據(jù) char i; for(i=0;i1; /右移一位,取出該字節(jié)的最低位 R=CY; /將該字節(jié)的最低位傳給R CLK=0; /將數(shù)據(jù)移入595,上升沿 CLK=1; void main() int num; while(1) for(num=0;num1,把要輸入的數(shù)據(jù)右移一位,這樣最低位便進入移位寄存器CY中,緊接著我們讓R=CY,把該位傳給595的輸入端,CLK一個上升沿的跳變就實現(xiàn)了把該位數(shù)據(jù)移入595的功能。8次循環(huán)便可以將一個字節(jié)的數(shù)據(jù)送出。重點還是看while循環(huán)內(nèi),同樣也是16行的掃描,然后就是WriteByte(table2*num)等同于上面的P2=table2*num,WriteByte(table2*num+1)等同于P3=table2*num+1,完成列選,接著行選,然后有一個STB的下降沿的跳變,這個變化能夠?qū)崿F(xiàn)并行輸出移位寄存器中的數(shù)據(jù)。這樣就完成了整個過程。(3)16*16點陣的移位控制點陣的移位一般有上、下、左、右的移動,這里我們重點講上移和左移,其它同理。1. 點陣的上移:點陣的上移相對來說很簡單,看效果圖如下:源代碼:(該程序?qū)崿F(xiàn)了循環(huán)上移顯示“邢臺”)/*16*16LED點陣屏顯示*/#includesbit R=P20; /數(shù)據(jù)輸入端口 sbit CLK=P21; / 時鐘信號 sbit STB=P22; / 鎖存端 char code table=/*- 文字: 邢 -*/*- 宋體12; 此字體下對應(yīng)的點陣為:寬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; 此字體下對應(yīng)的點陣為:寬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;xz;x+) for(y=0;y110;y+);void WriteByte(char dat) /寫一個字節(jié)的數(shù)據(jù) char i; for(i=0;i1; /右移一位,取出該字節(jié)的最低位 R=CY; /將該字節(jié)的最低位傳給R CLK=0; /將數(shù)據(jù)送出,上升沿 CLK=1; void main() int num,move,speed; while(1) if(+speed8) /移動速度控制 speed=0; move+; /移位 if(move16) /是否完成移位一個漢字 move=0; /從頭開始 for(num=0;numtempyid) | (BUFFs+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)左移顯示“邢臺學(xué)院”),效果圖如下:見源代碼:#include #define uchar unsigned char#define uint unsigned intuchar yid,h; /YID為移動計數(shù)器,H為行段計數(shù)器 uint zimuo; /字模計數(shù)器 uchar code hanzi; /漢字字模 uchar BUFF4; /緩存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(yid16) /數(shù)據(jù)移位。 for(i=0;i=96) /到最后從頭開始,有字數(shù)決定 zimuo=0; /*/void sbuf_out() for(h=0;h=0;s-) /h為向后先擇字節(jié)計數(shù)器,zimuoo為向后選字計數(shù)器 BUFF2*s+1=tablezimuo+1+32*s+2*h; /把第一個字模的第一個字節(jié)放入BUFF0/中,第二個字模的第一個字節(jié)放入BUFF2中 BUFF2*s=tablezimuo+32*s+2*h; / 把第一個字模的第二個字節(jié)放入BUFF1中,/第二個字模的第二個字節(jié)放入BUFF3中 /*/void rxd_data(void) /串行發(fā)送數(shù)據(jù) char s; uchar inc,tempyid,temp; if(yid8) inc=0; else inc=1; for(s=0+inc;s2+inc;s+) /發(fā)送2字節(jié)數(shù)據(jù) if(yidtempyid)|(BUFFs+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ā)送,關(guān)于在移位過程中的具體實現(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(yid16)內(nèi),有控制移動速度的for循環(huán),即顯示幾次靜態(tài)的畫面移動一步,而zimuo變量為移位過程中漢字的選擇變量,它每32位的變化,正好是一個16*16漢字的編碼個數(shù)。這樣就完成了整個點陣左移的控制(這里使用了串口實現(xiàn)點陣的左移,當然我們也可以不用串口,關(guān)于非串口實現(xiàn)的左移后面介紹),它的過程比較復(fù)雜,需反復(fù)思考。(4)128*32點陣擴展顯示1. 128*32點陣的靜態(tài)顯示完成了16*16點陣的靜態(tài)與移動顯示之后,就已經(jīng)算是掌握了點陣屏顯示的主要部分,以后不管想要操縱什么樣的點陣屏,只要把握上面的原理,都能按照我們的想法進行顯示。所以接下來的講解不會再有上面那么詳細。下面來看128*32點陣是如何顯示的。這里的布線有點繁瑣,首先來看一下64*16點陣的布線,如下圖:前面已經(jīng)提到過,在該仿真環(huán)境下紅色點陣為上列選下行選。理解了64*16的點陣布線,我們來看一下128*32的仿真圖:這是一個完整的128*32的點陣屏,只是在上面小屏的基礎(chǔ)上級聯(lián)了更多的595,因為只有一個4選16的譯碼器,而該點陣有32行,這里我們使用兩個數(shù)據(jù)輸入端,分別對應(yīng)點陣屏的上、下半屏。下面以操作上半屏為例(下半屏同理)。看效果圖:見源代碼:#include #define uchar unsigned char#define uint unsigned intuchar yid,h; /YID為移動計數(shù)器,H為行段計數(shù)器 uint zimuo; /字模計數(shù)器 uchar code hanzi; /漢字字模 uchar BUFF18; /緩存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(yid16) /數(shù)據(jù)移位。 for(i=0;i=480) /到最后從頭開始,有字數(shù)決定 zimuo=0; /*/void sbuf_out() for(h=0;h=0;s-) /h為向后先擇字節(jié)計數(shù)器,zimuoo為向后選字計數(shù)器 BUFF2*s+1=tablezimuo+1+32*s+2*h; /把第一個字模的第一個字節(jié)放入BUFF0/中,第二個字模的第一個字節(jié)放入BUFF2中 BUFF2*s=tablezimuo+32*s+2*h; / 把第一個字模的第二個字節(jié)放入BUFF1中,/第二個字模的第二個字節(jié)放入BUFF3中 /*/void rxd_data(void) /串行發(fā)送數(shù)據(jù) char s; uchar inc,tempyid,temp; if(yid8) inc=0; else inc=1; for(s=0+inc;s8+inc;s+) /發(fā)送8字節(jié)數(shù)據(jù) if(yidtempyid)|(BUFFs+1(8-tempyid);/h1左移tempyid位后和h2右移8-tempyid相或,取出移位后的數(shù)據(jù) SBUF=temp;/把BUFF中的字節(jié)從大到小移位相或后發(fā)送輸出。 while(!TI); /注:這里使用了串口,串口數(shù)據(jù)的發(fā)送為最低位在前。 TI=0; /等待發(fā)送中斷 該程序同上面的左移程序大同小略,只有幾處不同。它同樣實現(xiàn)了上半屏循環(huán)左移顯示一系列漢字的功能。對該程序,就不再詳細講解。二基于AVR的點陣屏顯示(1)靜態(tài)顯示上面已經(jīng)講完了基于51的點陣屏顯示,相信大家已經(jīng)掌握了點陣屏顯示的原理,下面仍然依據(jù)該原理,我們使用AVR單片機來進行控制。下面的程序均在ICCAVR Version 6.31A環(huán)境下編寫并均在點陣實驗板上測試通過。首先來看一下128*32點陣屏兩行靜態(tài)顯示的程序,源代碼如下:#include#include#define uchar unsigned char#define uint unsigned int#include delay.h#include code.h#pragma data: data#define screen_size 8 /半屏顯示漢字個數(shù):8 32*128uchar BUFF_1screen_size*2+2; /緩存uchar BUFF_2screen_size*2+2; /緩存 uchar disrow; /disrow 為16行變量uchar temp_up,temp_down;uchar Move_up,Move_down;uchar temp_up,temp_down;uint zimo_up,zimo_down;#define HC595_data1_H() PORTB |= BIT(0)#define HC595_data1_L() PORTB &=BIT(0)#define HC595_data2_H() PORTB |= BIT(1)#define HC595_data2_L() PORTB &=BIT(1)#define HC595_clk_H PORTB |= BIT(2)#define HC595_clk_L PORTB &=BIT(2)#define HC595_lock_H PORTB |= BIT(3)#define HC595_lock_L PORTB &=BIT(3)/* 函數(shù)說明:595發(fā)送一個字節(jié)數(shù)據(jù) */void HC595_send_2byte(uchar byte1,uchar byte2) uchar i; HC595_lock_L; for (i=0x01;i!=0;i=i=0;s-) BUFF_12*s=pf+32*s+2*disrow; BUFF_12*s+1=pf+1+32*s+2*disrow; /*函數(shù)名:void Move_Down(const uchar *p,uint f)功能:下半屏緩存數(shù)據(jù) 左移輸入:輸出:/*/ void Move_Down(const uchar *p,uint f) signed char s; for(s=screen_size;s=0;s-) BUFF_22*s=pf+32*s+2*disrow; BUFF_22*s+1=pf+1+32*s+2*disrow; /*函數(shù)名:void display(void)功能:顯示刷新輸入:輸出:/*/ void display(void) uchar i = Move_up; uchar j =

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當內(nèi)容,請與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

最新文檔

評論

0/150

提交評論