|
一、課程設(shè)計(jì)目的和任務(wù) 實(shí)習(xí)目的任務(wù)是培養(yǎng)學(xué)生運(yùn)用有關(guān)課程的基礎(chǔ)理論和技能解決實(shí)際問(wèn)題,進(jìn)一步提高學(xué)生本專業(yè)必要的基本技能、方法和創(chuàng)新能力的重要環(huán)節(jié)之一。通過(guò)綜合實(shí)習(xí)要使學(xué)生受到設(shè)計(jì)方法的初步訓(xùn)練,能用文字、圖形和現(xiàn)代設(shè)計(jì)方法簡(jiǎn)要、系統(tǒng)、正確地表達(dá)設(shè)計(jì)成果。 利用點(diǎn)陣LED屏向右滾動(dòng)顯示“KST”:熟悉Keil軟件和STC-ISP-v4.80軟件的使用,單片機(jī)實(shí)驗(yàn)箱及其開(kāi)發(fā)環(huán)境;查閱點(diǎn)陣LED屏的工作原理,如何獲取圖形,結(jié)合原理圖了解芯片如何驅(qū)動(dòng)點(diǎn)陣LED屏工作,了解LED點(diǎn)陣的基本結(jié)構(gòu),學(xué)習(xí)LED點(diǎn)陣的掃描顯示方法。 二、分析與設(shè)計(jì) 1.設(shè)計(jì)任務(wù)分析: 為了吸引觀眾增強(qiáng)顯示效果,可以有多種顯示模式,最簡(jiǎn)單的顯示模式是靜態(tài)顯示。這里所說(shuō)的“靜態(tài)顯示模式”不同于靜態(tài)驅(qū)動(dòng)方式。與靜態(tài)顯示模式相對(duì)應(yīng),就有各種動(dòng)態(tài)顯示模式,它們所顯示的圖文都是能夠動(dòng)的。按照?qǐng)D文運(yùn)動(dòng)的特點(diǎn)又可以分為閃爍、平移、旋轉(zhuǎn)、縮放等多種顯示模式。產(chǎn)生不同顯示模式的方法,并不意味著一定要重新編寫(xiě)顯示數(shù)據(jù),可以通過(guò)一定的算法從原來(lái)的顯示數(shù)據(jù)直接生成。例如,按順序調(diào)整行號(hào),可以使顯示圖文產(chǎn)生上下平移;而順序調(diào)整列顯示數(shù)據(jù)的位置,就可以達(dá)到左右平移的目的;同時(shí)調(diào)整行列順序,就能得到對(duì)角線平移的效果。其它模式的數(shù)據(jù)刷新,也可找到相應(yīng)的算法。不過(guò)當(dāng)算法太復(fù)雜,太浪費(fèi)時(shí)間的話,也可以考慮預(yù)先生成刷新數(shù)據(jù),存儲(chǔ)備用。刷新的時(shí)間控制,要考慮運(yùn)動(dòng)圖形文字的顯示效果。刷新太慢,動(dòng)感不顯著;刷新太快了,中間過(guò)程看不清。一般刷新周期可控制在幾十毫秒范圍之內(nèi)。 而本實(shí)驗(yàn)用KST-51開(kāi)發(fā)板的點(diǎn)陣顯示KST向右移動(dòng)的顯示設(shè)計(jì)。由于只控制8*8點(diǎn)陣顯示屏,故不需要擴(kuò)展單片機(jī)的I/O接口。考慮到P0口需要接上拉電阻,使得電路較為復(fù)雜,因此利用單片機(jī)的P1口來(lái)控制點(diǎn)陣的行,用P2口控制點(diǎn)陣的列。 2。 設(shè)計(jì)方案論證: 本次設(shè)計(jì)向右移動(dòng)顯示需要利用二維數(shù)組來(lái)實(shí)現(xiàn),算法基本上和上下移動(dòng)相似。二維數(shù)組,他的使用也很簡(jiǎn)單。它的聲明方式是: 數(shù)據(jù)類型 數(shù)組名[數(shù)組長(zhǎng)度 1][數(shù)組長(zhǎng)度 2]; 與一維數(shù)組類似,數(shù)據(jù)類型是全體元素的數(shù)據(jù)類型,數(shù)組名是標(biāo)識(shí)符,數(shù)組長(zhǎng)度 1 和數(shù)組長(zhǎng)度 2 分別代表數(shù)組具有的行數(shù)和列數(shù)。數(shù)組元素的下標(biāo)一律從 0 開(kāi)始。 例如:unsigned char a[2][3];聲明了一個(gè)具有 2 行 3 列的無(wú)符號(hào)字符型的二維數(shù)組 a。 二維數(shù)組的數(shù)組元素總個(gè)數(shù)是兩個(gè)長(zhǎng)度的乘積。二維數(shù)組在內(nèi)存中存儲(chǔ)的時(shí)候,采用行優(yōu)先的方式來(lái)存儲(chǔ),即在內(nèi)存中先存放第 0 行的元素,再存放第一行的元素......,同一行中再按照列順序存放,剛才定義的那個(gè) a[2][3]的存放形式就如下表所示。 a[0][0] a[0][1] a[0][2] a[1][0] a[1][1] a[1][2] 二維數(shù)組的初始化方法分兩種情況,數(shù)組元素的數(shù)量可以小于數(shù)組元素個(gè)數(shù),沒(méi)有賦值的會(huì)自動(dòng)給 0。當(dāng)數(shù)組元素的數(shù)量等于數(shù)組個(gè)數(shù)的時(shí)候, 如下所示: unsigned char a[2][3] = {{1,2,3}, {4,5,6}}; 或者是 unsigned char a[2][3] = {1,2,3,4,5,6}; 當(dāng)數(shù)組元素的數(shù)量小于數(shù)組個(gè)數(shù)的時(shí)候,如下所示: unsigned char a[2][3] = {{1,2}, {3,4}}; 等價(jià)于 unsigned char a[2][3] = {1,2,0,3,4,0}; 而反過(guò)來(lái)的寫(xiě)法 unsigned char a[2][3] = {1,2,3,4}; 等價(jià)于 unsigned char a[2][3] = {{1,2,3}, {4,0,0}}; 此外,二維數(shù)組初始化的時(shí)候,行數(shù)可以省略,編譯系統(tǒng)會(huì)自動(dòng)根據(jù)列數(shù)計(jì)算出行數(shù),但是列數(shù)不能省略。 要進(jìn)行橫向做KST向右移動(dòng)的動(dòng)畫(huà),先把需要的圖片畫(huà)出來(lái),再逐一取模,如下圖所示,這個(gè)圖形共有30張圖片,通過(guò)程序每250ms改變一張圖片,就可以做出來(lái)動(dòng)畫(huà)效果了。因?yàn)闄M向移動(dòng)的圖片切換時(shí)的字模數(shù)據(jù)不是連續(xù)的,所以要對(duì)30張圖片分別取模。 3.硬件設(shè)計(jì)及原理圖: (1)LED點(diǎn)陣總體框圖:點(diǎn)陣電路大體上可以分成微機(jī)本身的硬件、顯示驅(qū)動(dòng)電路、控制信號(hào)電路三部分?刂齐娐凡糠职ㄒ粋(gè)51CUP和一些外圍電路。點(diǎn)陣包括顯示屏體、以及它的行和列的各個(gè)驅(qū)動(dòng)電路。此顯示電路采用掃描方式進(jìn)行顯示時(shí),每行有一個(gè)行驅(qū)動(dòng)器,從第一行開(kāi)始,按順序依次對(duì)各行進(jìn)行掃描。另一方面,根據(jù)各列鎖存的數(shù)據(jù)點(diǎn)亮相應(yīng)的LED。 (2)電路原理圖:點(diǎn)陣顯示模塊的硬件電路設(shè)計(jì)如下圖所示: (3)點(diǎn)陣的認(rèn)識(shí) 一個(gè)數(shù)碼管是8個(gè)LED組成,同理,一個(gè)8*8的點(diǎn)陣就是由64個(gè)LED小燈組成。如下圖: 在上圖中大方框外側(cè)的就是點(diǎn)陣LED的引腳圖,左側(cè)的8個(gè)引腳是接的內(nèi)部LED的陽(yáng)極,上側(cè)的8個(gè)引腳接的是內(nèi)部LED的陰極。那么如果把9引腳置成高電平,13引腳置成低電平的話,左上角的那個(gè)LED小燈就會(huì)亮了。特別注意,控制點(diǎn)陣左側(cè)引腳的74HC138是原理圖上的U4,8個(gè)引腳自上而下依次由U4的Y0~Y7輸出來(lái)控制。 從圖中(本圖的LED陣列采用共陰的接法)可以看出,8×8點(diǎn)陣共需要64個(gè)發(fā)光二極管組成,且每個(gè)發(fā)光二極管是放置在行線和列線的交叉點(diǎn)上。要實(shí)現(xiàn)顯示圖形或字體,只需考慮其顯示方式,通過(guò)編程控制各顯示點(diǎn)對(duì)應(yīng)LED陽(yáng)極和陰極端的電平,就可以有效的控制各顯示點(diǎn)的亮滅。當(dāng)采用按行掃描按列控制的驅(qū)動(dòng)方式時(shí),LED顯示屏8行的同名列共用一套列驅(qū)動(dòng)器。行驅(qū)動(dòng)器一行的行線連接到電源的一端,列驅(qū)動(dòng)器一列的列線連接到電源的另一端。應(yīng)用時(shí)還應(yīng)在各條行線或列線上接上限流電阻。掃描中控制電路將行線的1到 8輪流接通高電位,使連接到各該行的全部LED器件接通正電源,但具體那一個(gè)LED導(dǎo)通,還要看它的負(fù)電源是否接通,這就是列控制的任務(wù)了。當(dāng)對(duì)應(yīng)的某一列置0電平,則相應(yīng)的二極管就亮;反之則不亮。例如:如果想使屏幕左上角LED點(diǎn)亮,左下角LED熄滅的話,在掃描到第一行時(shí),第一列的電位就應(yīng)該為低,而掃描到第八行時(shí)第一列的電位就應(yīng)該為高。這樣行線上只管一行一行的輪流導(dǎo)通,列線上進(jìn)行通斷控制,實(shí)現(xiàn)了行掃描列控制的驅(qū)動(dòng)方式。 (4)8X8點(diǎn)陣共由64個(gè)發(fā)光二極管組成,且每個(gè)發(fā)光二極管是放置在行線和列線的交叉點(diǎn)上,當(dāng)對(duì)應(yīng)的某一列置0電平,某一行置1電平,則相應(yīng)的二極管就亮;8X8點(diǎn)陣的列輸入為C0~C7,行輸入為R0~R7,它們通過(guò)驅(qū)動(dòng)電路74HC138接至發(fā)光二極管的陰極和陽(yáng)極。要顯示某一個(gè)字母,首先要設(shè)計(jì)該字母的點(diǎn)陣形狀,編好行(或列)點(diǎn)陣碼數(shù)據(jù),然后在單片機(jī)的控制下對(duì)點(diǎn)陣進(jìn)行逐行(或列)掃描。在人眼的暫存效應(yīng)下我們會(huì)看到完整的字形,從而實(shí)現(xiàn)了字母在點(diǎn)陣顯示屏上的輸出。 4.程序流程圖和源代碼清單: 流程圖如下: 源代碼: #include <reg52.h> sbit ADDR0 = P1^0; sbit ADDR1 = P1^1; sbit ADDR2 = P1^2; sbit ADDR3 = P1^3; sbit ENLED = P1^4; unsigned char code image[30][8] = { {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, //動(dòng)畫(huà)幀1 {0xFE,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE}, //動(dòng)畫(huà)幀2 {0xFD,0xFE,0xFF,0xFF,0xFF,0xFF,0xFE,0xFD}, //動(dòng)畫(huà)幀3 {0xFB,0xFD,0xFE,0xFF,0xFF,0xFE,0xFD,0xFB}, //動(dòng)畫(huà)幀4 {0xF7,0xFB,0xFD,0xFE,0xFE,0xFD,0xFB,0xF7}, //動(dòng)畫(huà)幀5 {0xEF,0xF7,0xFB,0xFD,0xFC,0xFB,0xF7,0xEF}, //動(dòng)畫(huà)幀6 {0xDE,0xEE,0xF6,0xFA,0xF8,0xF6,0xEE,0xDE}, //動(dòng)畫(huà)幀7 {0xBD,0xDD,0xED,0xF5,0xF1,0xED,0xDD,0xBD}, //動(dòng)畫(huà)幀8 {0x7B,0xBB,0xDB,0xEB,0xE3,0xDB,0xBB,0x7B}, //動(dòng)畫(huà)幀9 {0xF7,0x76,0xB7,0xD7,0xC7,0xB6,0x76,0xF7}, //動(dòng)畫(huà)幀10 {0xEE,0xED,0x6F,0xAF,0x8F,0x6D,0xED,0xEE}, //動(dòng)畫(huà)幀11 {0xDC,0xDB,0xDF,0x5F,0x1C,0xDB,0xDB,0xDC}, //動(dòng)畫(huà)幀12 {0xB8,0xB7,0xBF,0xBF,0x38,0xB7,0xB7,0xB8}, //動(dòng)畫(huà)幀13 {0x70,0x6F,0x7F,0x7E,0x71,0x6F,0x6F,0x70}, //動(dòng)畫(huà)幀14 {0xE1,0xDE,0xFE,0xFD,0xE3,0xDF,0xDE,0xE1}, //動(dòng)畫(huà)幀15 {0xC3,0xBD,0xFD,0xFB,0xC7,0xBF,0xBD,0xC3}, //動(dòng)畫(huà)幀16 {0x87,0x7B,0xFB,0xF7,0x8F,0x7F,0x7B,0x87}, //動(dòng)畫(huà)幀17 {0x0E,0xF7,0xF7,0xEF,0x1F,0xFF,0xF7,0x0F}, //動(dòng)畫(huà)幀18 {0x1C,0xEF,0xEF,0xDF,0x3F,0xFF,0xEF,0x1F}, //動(dòng)畫(huà)幀19 {0x38,0xDE,0xDE,0xBE,0x7E,0xFE,0xDE,0x3E}, //動(dòng)畫(huà)幀20 {0x70,0xBD,0xBD,0x7D,0xFD,0xFD,0xBD,0x7D}, //動(dòng)畫(huà)幀21 {0xE0,0x7B,0x7B,0xFB,0xFB,0xFB,0x7B,0xFB}, //動(dòng)畫(huà)幀22 {0xC1,0xF7,0xF7,0xF7,0xF7,0xF7,0xF7,0xF7}, //動(dòng)畫(huà)幀23 {0x83,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF,0xEF}, //動(dòng)畫(huà)幀24 {0x07,0xDF,0xDF,0xDF,0xDF,0xDF,0xDF,0xDF}, //動(dòng)畫(huà)幀25 {0x0F,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF,0xBF}, //動(dòng)畫(huà)幀26 {0x1F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F,0x7F}, //動(dòng)畫(huà)幀27 {0x3F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, //動(dòng)畫(huà)幀28 {0x7F,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, //動(dòng)畫(huà)幀29 {0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF}, //動(dòng)畫(huà)幀30 }; void main() { EA = 1; //使能總中斷 ENLED = 0; //使能U4,選擇LED點(diǎn)陣 ADDR3 = 0; TMOD = 0x01; //設(shè)置T0為模式1 TH0 = 0xFC; //為T0賦初值0xFC67,定時(shí)1ms TL0 = 0x67; ET0 = 1; //使能T0中斷 TR0 = 1; //啟動(dòng)T0 while (1); } / * 定時(shí)器0中斷服務(wù)函數(shù) * / void InterruptTimer0() interrupt 1 { static unsigned char i = 0; //動(dòng)態(tài)掃描的索引 static unsigned char tmr = 0; //250ms軟件定時(shí)器 static unsigned char index = 0; //圖片刷新索引 TH0 = 0xFC; //重新加載初值 TL0 = 0x67; //以下代碼完成LED點(diǎn)陣動(dòng)態(tài)掃描刷新 P0 = 0xFF; //顯示消隱 switch (i) { case 0 :ADDR2 = 0;ADDR1 = 0;ADDR0 = 0; i++; P0 = image[index][0];break; case 1 :ADDR2 = 0;ADDR1 = 0;ADDR0 = 1; i++; P0 = image[index][1];break; case 2 :ADDR2 = 0;ADDR1 = 1;ADDR0 = 0; i++; P0 = image[index][2];break; case 3 :ADDR2 = 0;ADDR1 = 1;ADDR0 = 1; i++; P0 = image[index][3];break; case 4 :ADDR2 = 1;ADDR1 = 0;ADDR0 = 0; i++; P0 = image[index][4];break; case 5 :ADDR2 = 1;ADDR1 = 0;ADDR0 = 1; i++; P0 = image[index][5];break; case 6 :ADDR2 = 1;ADDR1 = 1;ADDR0 = 0; i++; P0 = image[index][6];break; case 7 :ADDR2 = 1;ADDR1 = 1;ADDR0 = 1; i=0; P0 = image[index][7];break; default:break; } //以下代碼完成每250ms改變一幀圖像 tmr++; if(tmr>=250) //達(dá)到250ms時(shí)改變一次圖片索引 { tmr = 0; index++; if(index >=30) //圖片索引達(dá)到30后歸零 { index = 0; } } } |
|