《MCS-51單片機(jī)原理及嵌入式系統(tǒng)應(yīng)用》課件第7章_第1頁(yè)
《MCS-51單片機(jī)原理及嵌入式系統(tǒng)應(yīng)用》課件第7章_第2頁(yè)
《MCS-51單片機(jī)原理及嵌入式系統(tǒng)應(yīng)用》課件第7章_第3頁(yè)
《MCS-51單片機(jī)原理及嵌入式系統(tǒng)應(yīng)用》課件第7章_第4頁(yè)
《MCS-51單片機(jī)原理及嵌入式系統(tǒng)應(yīng)用》課件第7章_第5頁(yè)
已閱讀5頁(yè),還剩243頁(yè)未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡(jiǎn)介

第7章MCS-51系列單片機(jī)與鍵盤(pán)、顯示 器、ADC和DAC的接口設(shè)計(jì)7.1MCS-51單片機(jī)系統(tǒng)的鍵盤(pán)設(shè)計(jì)7.2MCS-51單片機(jī)系統(tǒng)的顯示器接口和編程控制7.3MCS-51單片機(jī)與ADC和DAC的接口習(xí)題七7.1.1非編碼式鍵盤(pán)的接口設(shè)計(jì)和編程利用MCS-51單片機(jī)實(shí)現(xiàn)的最簡(jiǎn)單的鍵盤(pán)如圖7-1所示。圖中利用8051單片機(jī)的P1口構(gòu)成F1(功能1鍵)、F2(功能2鍵)、F3(功能3鍵)、F4(功能4鍵)、▲(向上翻頁(yè))、▼(向下翻頁(yè))、ENT(確認(rèn))和ESC(取消)等8個(gè)按鍵。7.1MCS-51單片機(jī)系統(tǒng)的鍵盤(pán)設(shè)計(jì)圖7-1利用P1口構(gòu)成8個(gè)按鍵的電路圖7-1中P1口的8個(gè)位作為按鍵使用時(shí),它們都作為輸入口,識(shí)別這些按鍵的軟件非常簡(jiǎn)單,P1口的各個(gè)位狀態(tài)代表各按鍵的狀態(tài)。按照?qǐng)D7-1這樣利用n位輸入端口構(gòu)成的n個(gè)鍵的原理稱為“獨(dú)立式”按鍵結(jié)構(gòu)。識(shí)別按鍵的程序如下:#define

F1_Key

0x01

//定義常量表示鍵盤(pán)碼#define

F2_Key

0x02#define

F3_Key

0x03#define

F4_Key

0x04#define

UP_Key

0x05

//向上翻頁(yè)鍵的鍵值=5#define

DOWN_Key

0x06 //向下翻頁(yè)鍵的鍵值=6#define

ENT_Key

0x07

//確認(rèn)鍵的鍵值=7#define

ESC_Key

0x08

//取消鍵的鍵值=8unsignedcharGetKeyPadCode(void){

unsignedcharkey;

key=P1;

if(P1==0xFF)

//判斷P1口的8個(gè)位是否全為“1”,如果全為“1”表示無(wú)按鍵

return0xF0;

//如果沒(méi)有鍵按下,則返回0XF0

switch(key)

{

case0xFE:key=F1_Key;

break; //返回F1鍵的鍵值

case0xFD:key=F2_Key;

break; //返回F2鍵的鍵值

case0xFB:key=F3_Key;

break; //返回F3鍵的鍵值

case0xF7:key=F4_Key;

break; //返回F4鍵的鍵值

case0xEF:key=UP_Key;

break; //返回向上翻頁(yè)鍵的鍵值

case0xDF:key=DOWN_Key;break; //返回向下翻頁(yè)鍵的鍵值

case0xBF:key=ENT_Key;break;//返回確認(rèn)鍵的鍵值

case0x7F:key=ESC_Key;break;//返回取消鍵的鍵值

default:key=0xF0;break;

}

return(key);}上面的程序根據(jù)P1口的8個(gè)位中低電平的位置識(shí)別被按下的鍵,然后返回相應(yīng)的鍵碼。程序比較簡(jiǎn)單,得到整個(gè)鍵碼的執(zhí)行過(guò)程大約需要幾十微秒。但是,按鍵被按下是一個(gè)機(jī)械觸點(diǎn)的接觸(閉合)過(guò)程,按鍵被釋放是一個(gè)機(jī)械觸點(diǎn)的斷開(kāi)過(guò)程,在這兩個(gè)機(jī)械觸點(diǎn)動(dòng)作過(guò)程中會(huì)出現(xiàn)機(jī)械觸點(diǎn)抖動(dòng),觸點(diǎn)的機(jī)械抖動(dòng)期間會(huì)造成P1口相應(yīng)的位出現(xiàn)電平抖動(dòng)(即不穩(wěn)定電平),如圖7-2所示。另外,由于外界的振動(dòng)也可能造成系統(tǒng)按鍵的觸點(diǎn)誤動(dòng)作。由于觸點(diǎn)的機(jī)械特性造成的電平抖動(dòng)時(shí)間一般為5~10ms,如果在此期間連續(xù)快速掃描鍵碼,容易使CPU錯(cuò)誤響應(yīng)按鍵。圖7-2按鍵被按下和釋放時(shí)的電平抖動(dòng)示意圖為了保證單片機(jī)能夠正確處理和響應(yīng)鍵盤(pán),保證鍵穩(wěn)定閉合一次,單片機(jī)只響應(yīng)一次,系統(tǒng)對(duì)鍵盤(pán)的掃描過(guò)程必須有過(guò)濾電平抖動(dòng)的處理程序。由于機(jī)械觸點(diǎn)的抖動(dòng)時(shí)間大約在10ms以內(nèi),簡(jiǎn)單的“去抖動(dòng)”處理就是連續(xù)讀鍵盤(pán)至少兩次,每次間隔大于20ms。如果連續(xù)兩次得到的鍵碼是相同的,那么表示按鍵的狀態(tài)(按下?tīng)顟B(tài)或釋放狀態(tài))是穩(wěn)定的,然后CPU就可以響應(yīng)按鍵的動(dòng)作。采用查詢等待方式掃描鍵盤(pán)的程序如下:unsignedcharidataNowKeyCode=0;

//定義一個(gè)全局變量存儲(chǔ)當(dāng)前的按鍵unsignedcharScanKeyPad(void)

//掃描鍵盤(pán)程序,有鍵按下時(shí)返回1,否則返回0{

unsignedchark1,k2;

do{ //循環(huán)掃描鍵碼,直至連續(xù)兩次得到相同的鍵碼

k1=GetKeyPadCode();

//調(diào)讀鍵碼的函數(shù),將返回的鍵碼暫存在變量k1中

if(k1==0xFF)

//判斷是否有鍵按下

if(k1==0xFF)

//判斷是否有鍵按下

return0;

//如果沒(méi)有按鍵動(dòng)作,返回0

Delay(200);

//延時(shí)20ms

k2=GetKeyPadCode();

//調(diào)讀鍵碼的函數(shù),將返回的鍵碼暫存在變量k2中

if(k2==0xFF)

//判斷是否有鍵按下

return0;

//如果沒(méi)有按鍵動(dòng)作,返回0

}while(k1!=k2);

//如果連續(xù)兩次得到的鍵碼不相同,繼續(xù)掃描鍵碼

NowKeyCode=k1;

//保存當(dāng)前被按下鍵的鍵碼在變量NowKeyCode中

return1;

//有鍵被按下,返回1,鍵碼保存在變量NowKeyCode中

}采用這種查詢等待方式掃描鍵盤(pán)的程序在嵌入式實(shí)時(shí)控制系統(tǒng)中是非常不合理的,當(dāng)有鍵被按下或釋放時(shí),系統(tǒng)CPU執(zhí)行上面的ScanKeyPad()子程序至少需要20ms的時(shí)間,在此期間其他任務(wù)都被迫終止(除了中斷服務(wù)程序外),造成嵌入式實(shí)時(shí)系統(tǒng)的實(shí)時(shí)性降低。為了不影響系統(tǒng)的實(shí)時(shí)性,CPU對(duì)鍵盤(pán)處理可以采用定時(shí)掃描方式,由MCS-51單片機(jī)內(nèi)部的定時(shí)器產(chǎn)生定時(shí)中斷,定時(shí)喚醒CPU掃描鍵盤(pán)。下面的程序是采用定時(shí)器0定時(shí)20ms,產(chǎn)生20ms定時(shí)中斷,當(dāng)定時(shí)器溢出時(shí),主程序得到T0中斷服務(wù)程序發(fā)來(lái)的Over20ms的消息,然后進(jìn)入鍵盤(pán)掃描任務(wù)。unsignedcharidataOver20ms;

//全局變量,T0溢出標(biāo)志unsignedcharidataNowKeyCode,OldKeyCode;

//KeyPadTask()必需的全局變量unsignedcharidataKeyPadWatCnt;

//KeyPadTask()必需的全局變量voidInit_8051(void){

EA=0;

//初始化T0之前關(guān)閉中斷

TR0=0;

//T0定時(shí)器停止工作

TMOD=0x01;

//設(shè)置T0工作模式為定時(shí)器,工作方式為方式1

TL0=0xDF;

//fosc=12MHz,要求定時(shí)20ms

TH0=0xB1;

//裝入T0定時(shí)器初始值

IE=0x82;

//允許T0和T1中斷請(qǐng)求

Over20ms=0; //將“20ms定時(shí)時(shí)間到”的標(biāo)志清零

TR0=1;

//啟動(dòng)T0開(kāi)始定時(shí)

EA=1;

//中斷總使能位置位

//其他初始化程序}interrupt[0x0B]voidT0_ISR(void) //T0中斷服務(wù)程序{

TL0=0xDF;

//fosc=12MHz,要求定時(shí)20ms

TH0=0xB1;

//重新裝入T0定時(shí)器初始值

Over20ms=1; //20ms定時(shí)時(shí)間到,向主程序發(fā)送標(biāo)志}voidmain(void){

Init_8051();

//初始化程序

while(1)

{

//實(shí)時(shí)系統(tǒng)的任務(wù)之一是處理鍵盤(pán)任務(wù)

if(Over20ms)

//判斷是否有T0中斷的標(biāo)志

{

//當(dāng)收到T0中斷的標(biāo)志,處理鍵盤(pán)

Over20ms=0;

//將T0中斷服務(wù)程序發(fā)送來(lái)的標(biāo)志清零

KeyPadTask(); //處理鍵盤(pán)任務(wù)

}

//othertaskrunninghere //實(shí)時(shí)系統(tǒng)的其他任務(wù)的執(zhí)行和響應(yīng)

}}voidKeyPadTask(void)

//處理鍵盤(pán)任務(wù){(diào)

unsignedcharnowk;

nowk=GetKeyPadCode();

if(nowk==0xF0)

//判斷是否有按鍵

{

//當(dāng)前沒(méi)有任何鍵被按下時(shí),將各變量還原

KeyPadWatCnt=0;

//鍵盤(pán)“去抖動(dòng)”計(jì)數(shù)器清零

OldKeyCode=0;

//保存前一次鍵碼的變量清零

NowKeyCode=0;

//存儲(chǔ)“已經(jīng)響應(yīng)過(guò)的按鍵”變量清零

return;

//沒(méi)有按鍵被按下,直接返回

}

if(OldKeyCode!=nowk)

//判斷是否是新的按鍵

{

OldKeyCode=nowk; //保存新的鍵碼在變量OldKeyCode中

KeyPadWatCnt=0; //鍵盤(pán)“去抖動(dòng)”計(jì)數(shù)器清零

return;

//保存新的鍵碼后直接返回

}

//本次得到的鍵碼與前一次的鍵碼相同,繼續(xù)向下運(yùn)行

if((KeyPadWatCnt++)>0x02)

//判斷是否已經(jīng)有連續(xù)兩次相同的鍵碼

{

if(NowKeyCode==OldKeyCode)

//判斷當(dāng)前的按鍵是否已經(jīng)被響應(yīng)

return;

//當(dāng)前的按鍵已經(jīng)被響應(yīng),就不能響應(yīng)兩次

NowKeyCode=OldKeyCode;

//有連續(xù)兩次相同的鍵碼,說(shuō)明有鍵被穩(wěn)定按下, 將被響應(yīng)的按鍵保存在NowKeyCode變量中

//KeyPadProFun(); //處理、響應(yīng)未響應(yīng)的按鍵動(dòng)作

}}按照上面程序的執(zhí)行過(guò)程,MCS-51單片機(jī)每隔20ms執(zhí)行一次鍵盤(pán)任務(wù)(執(zhí)行一次KeyPadTask()子程序)。如果沒(méi)有按鍵動(dòng)作,執(zhí)行過(guò)程僅需要幾微秒時(shí)間;當(dāng)有鍵被按下或釋放時(shí),不考慮鍵盤(pán)響應(yīng)(執(zhí)行KeyPadProFun()子程序)的時(shí)間,僅需要大約幾十微秒的時(shí)間。這比前面以“查詢等待方式”實(shí)現(xiàn)的程序的執(zhí)行速度提高了1000倍左右,在實(shí)時(shí)性要求比較高的應(yīng)用系統(tǒng)中,定時(shí)掃描方式實(shí)現(xiàn)處理鍵盤(pán)的程序更合理。利用MCS-51單片機(jī)的I/O端口擴(kuò)展獨(dú)立式按鍵在按鍵個(gè)數(shù)較少的系統(tǒng)中可以使用。如果系統(tǒng)需要按鍵的個(gè)數(shù)比較多,則這種方式需要占用系統(tǒng)大量的I/O端口,非常浪費(fèi)系統(tǒng)的資源。當(dāng)系統(tǒng)需要按鍵的個(gè)數(shù)比較多時(shí)采用行列式矩陣結(jié)構(gòu)的鍵盤(pán)更合理,即利用MCS-51系列單片機(jī)的I/O端口相互交叉形成的行列式鍵盤(pán),這種方法不僅節(jié)省I/O端口,而且鍵盤(pán)掃描和鍵盤(pán)識(shí)別的軟件也比較簡(jiǎn)單。圖7-3是采用行列式方法,利用8051的P1口構(gòu)成16個(gè)按鍵的電路。這個(gè)4×4的行列式鍵盤(pán)的行線是P1.0~P1.3,列線是P1.4~P1.7,形成4×4=16個(gè)交叉點(diǎn),每個(gè)交叉點(diǎn)連接一個(gè)按鍵。16個(gè)按鍵分別為:數(shù)字鍵“1”(P1.0與P1.7的交叉點(diǎn))、數(shù)字鍵“2”(P1.0與P1.6的交叉點(diǎn))、數(shù)字鍵“3”(P1.0與P1.5的交叉點(diǎn))、功能鍵“Fn”(P1.0與P1.4的交叉點(diǎn))、數(shù)字鍵“4”(P1.1與P1.7的交叉點(diǎn))、數(shù)字鍵“5”(P1.1與P1.6的交叉點(diǎn))、數(shù)字鍵“6”(P1.1與P1.5的交叉點(diǎn))、向上翻頁(yè)鍵“▲”(P1.1與P1.4的交叉點(diǎn))、數(shù)字鍵“7”(P1.2與P1.7的交叉點(diǎn))、數(shù)字鍵“8”(P1.2與P1.6的交叉點(diǎn))、數(shù)字鍵“9”(P1.2與P1.5的交叉點(diǎn))、向下翻頁(yè)鍵“▼”(P1.2與P1.4的交叉點(diǎn))、“CLR”(P1.3與P1.7的交叉點(diǎn))、數(shù)字鍵“0”(P1.3與P1.6的交叉點(diǎn))、“ESC”(P1.3與P1.5的交叉點(diǎn))、“ENT”(P1.3與P1.4的交叉點(diǎn))。當(dāng)沒(méi)有任何鍵按下時(shí),所有的交叉點(diǎn)都是斷開(kāi)的,由于列線的上拉電阻作用,使其保持高電平。如果行線P1.0~P1.3被軟件設(shè)置為低電平,當(dāng)有任何按鍵被按下時(shí),該鍵所在的行線和列線被按鍵短路,那么相應(yīng)的列線就變?yōu)榈碗娖?。圖7-3利用P1口構(gòu)成16個(gè)按鍵的電路行列式結(jié)構(gòu)鍵盤(pán)的鍵碼識(shí)別過(guò)程如下:MCS-51單片機(jī)軟件首先設(shè)置P1.0~P1.3(行線)都輸出低電平,列線P1.4~P1.7為輸入端口,讀列線的狀態(tài)并判斷。如果列線都為高電平,說(shuō)明沒(méi)有任何交叉點(diǎn)閉合,即沒(méi)有任何鍵被按下;如果有任何列線為低電平,說(shuō)明有鍵被按下,并且根據(jù)低電平列線的位置可以確定被按下的鍵在哪一列。譬如數(shù)字鍵“0”被按下,低電平的列線是P1.6,軟件根據(jù)P1.6為低電平這個(gè)條件可以準(zhǔn)確地確定被按下的鍵肯定是數(shù)字鍵“2”、“5”、“8”和“0”4個(gè)鍵中的某一個(gè),但是具體是哪一個(gè)鍵還不能確定,需要利用行線掃描查找鍵的準(zhǔn)確位置。保存低電平列線的位置后,軟件將行線全部設(shè)置為高電平,然后僅將第一行線P1.0置為低電平,判斷P1.6(前面確定的低電平的列線位置)是否為低電平,由于P1.0和P1.6的交叉點(diǎn)并未閉合,因而此時(shí)P1.6為高電平,軟件可以確定不是數(shù)字鍵“2”;需要繼續(xù)查找,將行線P1.0置為高電平,并且將第二行線P1.1置為低電平,然后判斷P1.6的電平狀態(tài),如此重復(fù),直到對(duì)應(yīng)行線為低電平時(shí),列線P1.6也為低電平,它們的交叉點(diǎn)就是被按下的鍵的位置。當(dāng)使用n個(gè)雙向I/O端口構(gòu)成行列式鍵盤(pán)時(shí),鍵的個(gè)數(shù)可以利用下面的式子確定:

n為偶數(shù)n個(gè)雙向I/O端口構(gòu)成的按鍵個(gè)數(shù)=

n為奇數(shù)當(dāng)n=8時(shí),構(gòu)成的按鍵個(gè)數(shù)為16個(gè);當(dāng)n=16時(shí),構(gòu)成的按鍵個(gè)數(shù)為64個(gè)。下面的程序是識(shí)別4×4的行列式鍵盤(pán)的程序:#define

Numeric0Key

0x0

//定義常數(shù)表示相應(yīng)的鍵碼#define

Numeric1Key

0x01#define

Numeric2Key

0x02#define

Numeric3Key

0x03#define

Numeric4Key

0x04#define

Numeric5Key

0x05#define

Numeric6Key

0x06#define

Numeric7Key

0x07#define

Numeric8Key

0x08#define

Numeric9Key

0x09#define

CLRKey

0x0A#define

FnKey

0x0B#define

PageUpKey

0x0C#define

PageDownKey

0x0D#define

ESCKey

0x0E#define

ENTKey

0x0F

//所有正常鍵碼的高4位都為“0”codeunsignedcharKeyPadPositionTable[]={

0xB7,0x7E,0xBE,0xDE,0x7D,0xBD,0xDD,0x7B,0xBB,0xDB,

//數(shù)字鍵“0”~“9”

0x7E,0xEE,0xED,0xEB,0xD7,0xE7

//CLR、Fn、▲、▼、ESC、ENT鍵}unsignedcharGetKeyPadCode(void)

//識(shí)別4×4的行列式鍵盤(pán)的鍵碼的子程序{

//如果無(wú)鍵,返回0xF0;否則返回鍵碼

unsignedcharkey,column,line,i;

key=P1;

P1=key&0xF0;

//設(shè)置P1.0~P1.3(行線)為低電平

for(key=4;key>0;key--);

//延時(shí)4微秒,等待輸出電平狀態(tài)穩(wěn)定

key=P1;

//讀P1.4~P1.7(列線)的狀態(tài)

if((key&0xF0)==0xF0)

//判斷是否有列線為低電平

return(0xF0);

//如果所有列線都為高電平,即無(wú)任何鍵被按下,則返回

column=key&0xF0;

//保存列線的狀態(tài)在變量column中

line=0xFE;

//首先置P1.0為低電平

for(i=0;i<4;i++)

//行線被逐個(gè)置低電平,確定鍵的位置

{

P1=line;

//將惟一的低電平信號(hào)寫(xiě)到P1口

for(key=2;key>0;key--);

//延時(shí)2微秒,等待輸出電平狀態(tài)穩(wěn)定

key=P1;

if((key&0xF0)==column)

//比較低電平的列線

break;

//被按下的鍵位置被確定,終止循環(huán)

line<<=1;

//低電平的位置左移一位

}

P1=0xF0;

//重新將所有的行線置為低電平狀態(tài)

if(i==4)

return(0xF0);

//查找按鍵的位置操作失敗,認(rèn)為沒(méi)有按鍵,返回

key=line&column;

//合并行線和列線的狀態(tài),其中高低4位各有一個(gè)“0”

for(i=0;i<16;i++)

//根據(jù)行列交叉點(diǎn)在鍵盤(pán)位置表中快速查找位置

if(key==KeyPadPositionTable[i])

break;

//如果找到,終止查找

if(i!=16)

returni;

//已經(jīng)找到鍵的位置和鍵碼,返回鍵碼

return(0xF0);

//在表中未找到響應(yīng)的鍵位置,認(rèn)為沒(méi)有鍵

}比較獨(dú)立式鍵盤(pán)的讀取鍵碼子程序GetKeyPadCode()和4×4的行列式鍵盤(pán)的讀取鍵碼子程序GetKeyPadCode(),MCS-51單片機(jī)執(zhí)行兩個(gè)子程序的時(shí)間有較大差異,后者大約是前者的5倍,后者估計(jì)需要0.1ms左右。顯然,實(shí)現(xiàn)相同個(gè)數(shù)的按鍵時(shí),獨(dú)立式鍵盤(pán)的鍵碼識(shí)別速度較快,但是需要占用較多的I/O端口;行列式鍵盤(pán)的鍵碼識(shí)別速度相對(duì)較慢,但是能夠有效地節(jié)省I/O端口的資源。圖7-3中擴(kuò)展的鍵盤(pán)允許應(yīng)用程序以中斷方式處理和響應(yīng)鍵盤(pán),所有的行線都保持低電平狀態(tài),一旦有任何按鍵被按下時(shí),INT0引腳處會(huì)出現(xiàn)低電平的中斷請(qǐng)求信號(hào),在INT0中斷服務(wù)程序中向主程序發(fā)送“有按鍵動(dòng)作”的消息(標(biāo)志)。當(dāng)主程序收到該消息時(shí),才運(yùn)行鍵盤(pán)處理和響應(yīng)的任務(wù),CPU在沒(méi)有按鍵的時(shí)間中可以處理和響應(yīng)其他任務(wù)。這種方法比較適合嵌入式實(shí)時(shí)控制系統(tǒng)軟件對(duì)行列式鍵盤(pán)的處理。7.1.2其他方式的鍵盤(pán)接口在上一節(jié)中利用MCS-51系列單片機(jī)的P1口擴(kuò)展獨(dú)立式鍵盤(pán)和行列式鍵盤(pán)是比較常用的非編碼式鍵盤(pán)接口設(shè)計(jì),但是,P1口是支持位操作的雙向I/O端口,是MCS-51單片機(jī)的寶貴資源,往往更希望把它們作為擴(kuò)展串行接口的器件的I/O線使用。為MCS-51單片機(jī)系統(tǒng)擴(kuò)展鍵盤(pán)還有其他方法,如利用第六章中提到的“擴(kuò)展的外部I/O通道”構(gòu)成行列式開(kāi)關(guān)矩陣,是利用外部擴(kuò)展資源實(shí)現(xiàn)行列式鍵盤(pán)的方法之一。這種行列式鍵盤(pán)與前面講到的行列式鍵盤(pán)的鍵碼識(shí)別原理相同,無(wú)非是P1口和兩個(gè)外部I/O通道(一個(gè)是只讀的三態(tài)緩沖門(mén),另一個(gè)是只寫(xiě)的鎖存器)之間的訪問(wèn)方式不同而已。圖7-4是利用MCS-51單片機(jī)擴(kuò)展的I/O通道實(shí)現(xiàn)16個(gè)按鍵的電路,電路中擴(kuò)展了一個(gè)8位的三態(tài)緩沖門(mén)(U2)74HC244和一個(gè)8位D型鎖存器(U3)74HC374,其中三態(tài)緩沖門(mén)的低4位作為輸入口使用,是4×4鍵盤(pán)的4根列線;鎖存器的低4位作為輸出口使用,是鍵盤(pán)的4根行線。這個(gè)電路的鍵碼識(shí)別方法與前一節(jié)中的4×4行列式鍵盤(pán)相同。圖7-4利用擴(kuò)展的I/O通道構(gòu)成16個(gè)按鍵的電路另外,也可以利用專用的鍵盤(pán)/顯示器接口芯片——Intel公司的8279實(shí)現(xiàn)鍵盤(pán)的接口。它屬于一種專用編碼式鍵盤(pán)芯片,是Intel公司提供的通用鍵盤(pán)/顯示器接口芯片。利用8279可以實(shí)現(xiàn)對(duì)鍵盤(pán)和動(dòng)態(tài)掃描LED顯示器的自動(dòng)掃描,自動(dòng)識(shí)別鍵盤(pán)的鍵碼。在MCS-51系列單片機(jī)系統(tǒng)中擴(kuò)展8279芯片實(shí)現(xiàn)鍵盤(pán)和LED顯示器,不僅可以大大節(jié)省單片機(jī)對(duì)鍵盤(pán)和顯示器的操作時(shí)間,從而減輕單片機(jī)執(zhí)行程序的負(fù)荷,提高嵌入式實(shí)時(shí)系統(tǒng)的實(shí)時(shí)性,而且控制程序簡(jiǎn)單,顯示穩(wěn)定,不會(huì)出現(xiàn)誤動(dòng)作。

PDIP封裝的8279芯片一共有40個(gè)引腳,其內(nèi)部包括鍵盤(pán)輸入控制邏輯塊、I/O控制和數(shù)據(jù)緩沖塊、掃描計(jì)數(shù)器、接口和譯碼控制邏輯、FIFORAM(FirstInFirstOutRAM)隊(duì)列等。8279提供4根鍵盤(pán)和顯示器的掃描輸出線及8根鍵盤(pán)狀態(tài)反饋線,利用它們可以直接構(gòu)成4×8=32個(gè)鍵的行列式鍵盤(pán)。有關(guān)Intel8279的詳細(xì)說(shuō)明和接口設(shè)計(jì)、編程方法等請(qǐng)參考相關(guān)資料。隨著CPLD和FPGA技術(shù)的迅速發(fā)展,以“單片機(jī)+CPLD/FPGA”為核心設(shè)計(jì)、實(shí)現(xiàn)的嵌入式控制系統(tǒng)越來(lái)越多,將傳統(tǒng)的單片機(jī)外圍器件(除了大容量存儲(chǔ)器外)絕大多數(shù)都可以集成在一片CPLD/FPGA內(nèi)部,即使是一個(gè)功能強(qiáng)大、復(fù)雜的單片機(jī)系統(tǒng)也都是“單片機(jī)+CPLD/FPGA”的2片結(jié)構(gòu),這種方法既能夠發(fā)揮CPLD和FPGA的靈活性,而且開(kāi)發(fā)的系統(tǒng)可以適用于多種目的,系統(tǒng)的結(jié)構(gòu)比較簡(jiǎn)單,可靠性得以提高。8279作為一種傳統(tǒng)的鍵盤(pán)和顯示器專用接口芯片,其功能完全可以集成到CPLD/FPGA內(nèi)部,而不需要專門(mén)擴(kuò)展這些接口芯片。常用的編碼式專用鍵盤(pán)接口擴(kuò)展芯片還有74HC922和74HC923,它們是屬于74系列的專用集成電路。74HC922提供行線X1~X4和列線Y1~Y4,并且都具有內(nèi)部上拉電阻,利用行線和列線可以直接構(gòu)成4×4=16個(gè)鍵的行列式鍵盤(pán);74HC923具有4根行線和5根列線,可以構(gòu)成4×5=20個(gè)鍵的行列式鍵盤(pán)。74HC922采用4位并行三態(tài)數(shù)據(jù)總線輸出鍵碼,可以與MC-51系列單片機(jī)的數(shù)據(jù)總線直接連接,并且具有“有按鍵和鍵碼”的標(biāo)志信號(hào)(或握手信號(hào)線)。74HC923則采用5位并行三態(tài)數(shù)據(jù)總線輸出鍵碼。

74HC922與74HC923的引腳排列(PDIP封裝)和名稱如圖7-5所示。表7-1列出了74HC923的引腳名稱和功能。圖7-574HC922/3鍵盤(pán)編碼器引腳排列和名稱與其他專用的鍵盤(pán)編碼器芯片相比,74HC922和74HC923都屬于低成本的鍵盤(pán)接口擴(kuò)展芯片,它們具有功能單一、接口簡(jiǎn)單、使用操作簡(jiǎn)單等優(yōu)點(diǎn)。它們?cè)贛CS-51單片機(jī)系統(tǒng)使用時(shí),器件的外部?jī)H需要兩個(gè)電容,一個(gè)是掃描時(shí)鐘振蕩器電容,另一個(gè)是鍵盤(pán)“去抖動(dòng)”電容。器件的三態(tài)數(shù)據(jù)輸出總線可以與MCS-51系列單片機(jī)的數(shù)據(jù)總線直接連接,僅占用單片機(jī)的一個(gè)I/O擴(kuò)展地址資源,MCS-51單片機(jī)執(zhí)行外部讀操作就可以將鍵碼讀入CPU內(nèi)部寄存器。74HC922和74HC923都帶有DataValid信號(hào)輸出,當(dāng)有且僅有一個(gè)鍵被按下而且觸點(diǎn)穩(wěn)定閉合時(shí),該信號(hào)輸出一個(gè)有效的低電平脈沖,可以和MCS-51單片機(jī)的外部中斷輸入引腳INT0或INT1連接,實(shí)現(xiàn)中斷方式處理和響應(yīng)鍵盤(pán)。圖7-6是利用74HC922擴(kuò)展4×4結(jié)構(gòu)的行列式鍵盤(pán)電路。圖7-6利用74HC922擴(kuò)展4×4結(jié)構(gòu)行列式鍵盤(pán)電路程序使用INT0中斷方式處理和響應(yīng)鍵盤(pán),當(dāng)有鍵被按下時(shí),DAV輸出有效信號(hào)向8051單片機(jī)申請(qǐng)中斷。在8051的INT0中斷服務(wù)程序中,首先從74HC922中將鍵碼讀出存放在變量CurrentKeyCode中,并且在讀鍵碼的同時(shí)將中斷請(qǐng)求信號(hào)復(fù)位,得到正確的鍵碼后,INT0中斷服務(wù)程序置HaveKeyActive標(biāo)志有效,向主程序發(fā)送消息,鍵盤(pán)的響應(yīng)和處理在主程序中完成。#include<io51.h>#define

KeyPortAdr*(unsignedchar*)(0x010000)

//74HC922的地址unsignedcharidataCurrentKeyCode,HaveKeyActive=0;interrupt[0x03]voidINT0_ISR(void){

CurrentKeyCode=KeyPortAdr;

//將鍵碼讀到變量CurrentKeyCode中

CurrentKeyCode&=0x0F;

//僅低4位有效,所以屏蔽高4位

HaveKeyActive=1; //有按鍵被按下,向主程序發(fā)送消息}…voidmain(void){

//初始化程序,包括中斷INT0的初始化

while(1){

if(HaveKeyActive) //檢查是否有中斷INT0的消息

{

HaveKeyActive=0;

//標(biāo)志被清除

//KeyPadProFun();

//處理、響應(yīng)按鍵動(dòng)作

}

//其他任務(wù)

}}7.2MCS-51單片機(jī)系統(tǒng)的顯示器接口和編程控制在以MCS-51單片機(jī)為核心的嵌入式控制系統(tǒng)中常用的顯示器包括段式LED(LightEmittingDiode,發(fā)光二極管)顯示器、點(diǎn)陣LED顯示器、段式LCD(LiquidCrystalDisplay,液晶顯示器)、字符型LCD、圖形點(diǎn)陣LCD、段式VFD(VacuumFluorescentDisplay,真空熒光顯示器)、字符型VFD、圖形點(diǎn)陣VFD等。所有的LED顯示器都是將多個(gè)發(fā)光二極管組合而成。段式LED顯示器應(yīng)用最廣泛,它是一種低成本、高可靠性、高穩(wěn)定性的顯示器,而且亮度也比較高,使用壽命長(zhǎng);點(diǎn)陣LED顯示器作為戶外文字廣告和信息牌被廣泛使用。LED顯示器的缺點(diǎn)是消耗功率大,容易發(fā)熱,體積相對(duì)較大。

LCD顯示器具有功耗低、體積小等優(yōu)點(diǎn),它們被廣泛使用于各種手持設(shè)備、智能終端設(shè)備,目前LCD顯示器作為一種綠色平板顯示器已經(jīng)逐步成為PC的主流顯示終端。段式LCD可以適用于各類數(shù)字型儀表;字符型LCD能夠顯示ASCII字符和簡(jiǎn)單的圖形,在各種嵌入式系統(tǒng)中被廣泛使用;圖形點(diǎn)陣LCD能夠顯示各種圖形、曲線和漢字,在高檔儀器和嵌入式終端中被廣泛使用。LCD顯示器必須采用交流掃描信號(hào),缺點(diǎn)是容易被干擾,而且使用壽命相對(duì)較短。

VFD顯示器具有亮度高、穩(wěn)定性高、壽命長(zhǎng)等優(yōu)點(diǎn),但是所有的VFD器件都必須使用高壓驅(qū)動(dòng)電路,而且它們消耗的電流較大。VFD顯示器應(yīng)用最頻繁的領(lǐng)域是家用電器。7.2.1LED顯示器的接口所有的LED顯示器件都是由若干LED組合而成的,當(dāng)某一個(gè)LED導(dǎo)通時(shí),該LED表示的點(diǎn)或段(筆畫(huà))被點(diǎn)亮,單片機(jī)控制多個(gè)不同的點(diǎn)或段的亮或滅,可以顯示出不同的數(shù)碼或字符。常用段式LED顯示器包括“七段”結(jié)構(gòu)LED顯示器和“米字”結(jié)構(gòu)LED顯示器。它們都有共陰極和共陽(yáng)極兩種結(jié)構(gòu),其中共陰極LED顯示器內(nèi)部所有發(fā)光二極管的陰極連接在一起,而所有發(fā)光二極管的陽(yáng)極各自獨(dú)立;共陽(yáng)極LED顯示器內(nèi)部發(fā)光二極管的陽(yáng)極連接在一起,而所有發(fā)光二極管的陰極各自獨(dú)立。圖7-7是“七段”結(jié)構(gòu)的段式LED顯示器的內(nèi)部結(jié)構(gòu)和外型、引腳的示意圖,其中“dp”段是小數(shù)點(diǎn)指示段?!懊鬃帧毙徒Y(jié)構(gòu)的LED顯示器的內(nèi)部結(jié)構(gòu)僅比“七段”結(jié)構(gòu)的LED顯示器多了5段,增加的5段從外型上看,是將原來(lái)的“g”段改成兩段,并在“8”字中間增加“X”形狀的4段,成為“米”字形狀。圖7-7“七段”結(jié)構(gòu)的LED顯示器的內(nèi)部結(jié)構(gòu)和外型、引腳示意圖(a)共陰極結(jié)構(gòu);(b)共陽(yáng)極結(jié)構(gòu);(c)外型和引腳排列按照?qǐng)D7-7中的“七段”結(jié)構(gòu)LED顯示器的外型和段的位置,“七段”LED顯示器顯示碼與控制碼的對(duì)照表如表7-2所示。段式LED顯示器的控制方式分為靜態(tài)顯示控制和動(dòng)態(tài)顯示控制兩種。所謂“靜態(tài)顯示控制”,就是當(dāng)一個(gè)LED顯示器顯示某字符時(shí),控制碼控制相應(yīng)的LED段處于恒定的導(dǎo)通狀態(tài),靜態(tài)顯示控制在電路上需要將控制碼鎖存在LED顯示器的各段輸入引腳,如果有多位LED顯示器,每個(gè)位必需一個(gè)8位鎖存器,MCS-51單片機(jī)僅在需要更改顯示器的顯示內(nèi)容時(shí),才重新將新的控制碼鎖存在8位鎖存器中。靜態(tài)顯示控制的LED顯示器的亮度與各段的導(dǎo)通電流大小有關(guān),靜態(tài)控制的顯示是非常穩(wěn)定的。所謂“動(dòng)態(tài)顯示控制”,就是多位顯示器逐個(gè)掃描,任意時(shí)刻僅有某一個(gè)顯示器是亮的,而其他各位都不亮,一個(gè)位亮一定時(shí)間后轉(zhuǎn)向另一個(gè)位。這種動(dòng)態(tài)逐個(gè)掃描多位LED顯示器的方式會(huì)造成顯示位“閃爍”,但是,適當(dāng)?shù)卣{(diào)整掃描速度,利用人的視覺(jué)暫留,使人的眼睛看起來(lái)“不閃爍”。動(dòng)態(tài)掃描LED顯示器方式比靜態(tài)顯示控制方式的電路更簡(jiǎn)單,將多位LED顯示器的段引腳對(duì)應(yīng)連接成“段”總線,僅需要一個(gè)8位鎖存器和多個(gè)位選通控制線就可以達(dá)到控制多位LED顯示器的目的。動(dòng)態(tài)掃描LED顯示器的亮度與各段的導(dǎo)通電流有關(guān),另外,亮度還與掃描頻率(一個(gè)位亮的時(shí)間和滅的時(shí)間稱為一個(gè)掃描周期)有關(guān)。圖7-8和圖7-9是利用擴(kuò)展的I/O通道分別實(shí)現(xiàn)靜態(tài)LED顯示器和動(dòng)態(tài)LED顯示器的電路。在圖7-8中為實(shí)現(xiàn)3位LED顯示器需要擴(kuò)展3個(gè)8位的D型鎖存器74HC273,每個(gè)鎖存器的輸出端經(jīng)過(guò)限流電阻后與各位LED顯示器的a~dp段對(duì)應(yīng)連接。擴(kuò)展的3個(gè)鎖存器的地址分別為0DFFFH、0BFFFH和7FFFH,8051單片機(jī)將各位需要顯示的字符對(duì)應(yīng)的段控制碼鎖存在各鎖存器中,即可實(shí)現(xiàn)顯示器的控制。一旦段控制碼鎖存后,顯示器一直保持顯示的字符,直到8051單片機(jī)重新寫(xiě)新的段控制碼到鎖存器中。圖7-83位LED顯示器的靜態(tài)控制接口電路在圖7-9中,擴(kuò)展了兩個(gè)8位D型鎖存器74HC273,U2作為段控制碼鎖存器使用,U3作為顯示器位選通碼使用,4位LED顯示器的段引腳a~dp對(duì)應(yīng)連接構(gòu)成“段”總線與U2的輸入連接。每一個(gè)位選通控制線都經(jīng)過(guò)一個(gè)達(dá)林頓結(jié)構(gòu)的驅(qū)動(dòng)器(75452),當(dāng)8051單片機(jī)通過(guò)寫(xiě)操作將段控制碼鎖存在段碼鎖存器中,然后控制位選通信號(hào)中的某一個(gè)位有效,此時(shí)該顯示位顯示段碼鎖存器中對(duì)應(yīng)的字符。一個(gè)顯示位亮一定時(shí)間后,8051單片機(jī)將所有的位選通信號(hào)都置為無(wú)效,然后重新將下一個(gè)顯示位的字符的段控制碼鎖存在段碼鎖存器中,再將這個(gè)位選通信號(hào)置為有效,這樣重復(fù)掃描4個(gè)LED顯示器。圖7-94位LED顯示器的動(dòng)態(tài)控制接口電路比較上面兩個(gè)電路,如果需要顯示器的位數(shù)相同,那么靜態(tài)控制方式的電路需要擴(kuò)展更多的鎖存器。相比較而言,動(dòng)態(tài)控制方式的電路就比較簡(jiǎn)單。下面是兩種不同顯示控制方式的控制程序。靜態(tài)顯示控制方式的程序:#include<io51.h>#define

StaticDisplayLED0Adr*(unsignedchar*)(0x01DFFF)

//BIT0地址#define

StaticDisplayLED1Adr*(unsignedchar*)(0x01BFFF)

//BIT1地址#define

StaticDisplayLED2Adr*(unsignedchar*)(0x017FFF)

//BIT2地址codeunsignedcharLEDSegmentCode[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71}unsignedcharidataDisplayBuffer[3];

//顯示緩沖區(qū)…voidStaticLEDDisplayUpdate(void)

//刷新靜態(tài)LED顯示器的子程序{

unsignedcharct;

ct=DisplayBuffer[0]&0x0F;

//僅顯示“0”~“F”

StaticDisplayLED0Adr=LEDSegmentCode[ct];

//將段碼鎖存在BIT0地址

ct=DisplayBuffer[1]&0x0F;

//僅顯示“0”~“F”

StaticDisplayLED1Adr=LEDSegmentCode[ct];

//將段碼鎖存在BIT1地址

ct=DisplayBuffer[2]&0x0F;

//僅顯示“0”~“F”

StaticDisplayLED2Adr=LEDSegmentCode[ct];

//將段碼鎖存在BIT2地址}在下面的動(dòng)態(tài)顯示方式控制程序中,利用Timer0定時(shí)20ms,作為L(zhǎng)ED顯示器的掃描周期。源程序如下:#include<io51.h>#define

DynamicDispSegCodeAdr*(unsignedchar*)(0x01BFFF)

//段碼鎖存器地址#define

DynamicDispBitSelectAdr*(unsignedchar*)(0x017FFF)

//位選通碼鎖存器地址codeunsignedcharLEDSegmentCode[]={0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F,0x77,0x7C,0x39,0x5E,0x79,0x71};codeunsignedcharLEDBitSelectCode[]={0x01,0x02,0x04,0x08};unsignedcharidataDisplayBuffer[3];

//顯示緩沖區(qū)unsignedcharidataOver20ms=0;

//20ms定時(shí)溢出標(biāo)志unsignedcharidataCurrentLEDBitPt=0;//定時(shí)掃描LED的位指針interrupt[0x0B]voidTimer0_ISR(void){

TL0=0xDF;

//fosc=12MHz,要求定時(shí)20ms

TH0=0xB1;

//重新裝入T0定時(shí)器初始值

Over20ms=1;

//20ms定時(shí)時(shí)間到,向主程序發(fā)送標(biāo)志}voidmain(void)

//主程序{

unsignedncharcct;

//初始化程序

while(1)

//主程序無(wú)限循環(huán)開(kāi)始

{

if(Over20ms) //從Timer0中斷服務(wù)程序接收到消息

{

Over20ms=0;

//清除標(biāo)志

DynamicDispBitSelectAdr=0x00;

//讓所有的位選通線都無(wú)效

cct=DisplayBuffer[CurrentLEDBitPt]&0x0F;

//從顯示緩沖區(qū)取顯示數(shù)據(jù)

DynamicDispSegCodeAdr=LEDSegmentCode[cct];

//鎖存段碼

DynamicDispSegCodeAdr=LEDBitSelectCode [CurrentLEDBitPt];

//置指針指向的位的位選通碼有效

CurrentLEDBitPt++;

//顯示器位指針加1

if(CurrentLEDBitPt>4) //判斷顯示器位指針是否已經(jīng)大于4

CurrentLEDBitPt=0;

//當(dāng)大于4時(shí),重新開(kāi)始下一輪顯示掃描

}

//執(zhí)行系統(tǒng)的其他任務(wù)

}}動(dòng)態(tài)掃描LED顯示器時(shí),為了防止“串亮”,在每次修改段碼鎖存器中的段控制碼之前,必須首先讓所有的位選通線都無(wú)效。比較上面兩種控制程序可以看出,采用靜態(tài)顯示控制方式的LED顯示器刷新程序比較簡(jiǎn)單,當(dāng)主程序需要刷新顯示的字符時(shí)才將新的段控制碼鎖存一次,平時(shí)不需要更改顯示的字符時(shí),靜態(tài)控制方式的LED顯示器能夠自動(dòng)保持顯示的字符。而對(duì)動(dòng)態(tài)顯示控制方式的LED顯示器來(lái)講,無(wú)論主程序是否要更改顯示的字符,程序必須周期性地掃描LED顯示器,需要周期性占用CPU的時(shí)間去逐位刷新,否則動(dòng)態(tài)控制方式的LED顯示器將不能正常工作。

MCS-51系列單片機(jī)與LED顯示器的接口方法還有很多種,如利用Intel公司的鍵盤(pán)和顯示器專用接口芯片8279(參考前一節(jié)的有關(guān)內(nèi)容)控制LED顯示器,這是一種傳統(tǒng)的擴(kuò)展方法。在MCS-51單片機(jī)系統(tǒng)中擴(kuò)展8279作為鍵盤(pán)和LED顯示器接口電路,可以構(gòu)成32個(gè)鍵的行列式鍵盤(pán)和8位LED顯示器。7.2.2字符型LCD顯示器的接口與LED顯示器相比,LCD顯示器是一種功耗極低的顯示器件。液晶(LiquidCrystal)的特點(diǎn)是在一定的溫度范圍內(nèi)既有液體的流動(dòng)性和連續(xù)性,又有晶體的各向異性,它們的分子呈現(xiàn)長(zhǎng)棒形狀,長(zhǎng)和寬的比例較大,分子不能彎曲,是一種剛性體。它們的中心一般有橋鏈,兩頭有極性。

LCD顯示器件的內(nèi)部結(jié)構(gòu)原理如圖7-10所示。由于液晶的“四壁效應(yīng)”,在定向膜的作用下,液晶材料的分子在正、背玻璃板電極上呈水平排列,但排列方向互為正交,而玻璃電極之間的分子呈連續(xù)扭轉(zhuǎn)過(guò)渡,這樣的構(gòu)造能使液晶對(duì)光產(chǎn)生旋光作用,使光的偏振方向旋轉(zhuǎn)90°。所以說(shuō),LCD顯示器屬于非主動(dòng)發(fā)光的光源,為了能夠看到LCD顯示器中的字符或圖形,必須在光線充足的地方,或?yàn)長(zhǎng)CD顯示器提供外界主動(dòng)發(fā)光的光源。為了在夜間能夠使用LCD顯示器,目前絕大多數(shù)LCD顯示器都帶有背光板,LCD顯示器背光板必須能夠?yàn)長(zhǎng)CD顯示器提供充足的背景光線。LCD顯示器的背光板光源可以選擇各種不同的顏色,可以得到不同的顯示效果。圖7-10LCD的基本構(gòu)造示意圖圖7-11是LCD顯示器的工作原理示意圖。當(dāng)外界主動(dòng)發(fā)光源的光線通過(guò)上偏振片后形成偏振光,偏振方向呈垂直方向。然后,此偏振光通過(guò)液晶材料之后被旋轉(zhuǎn)90°,此時(shí)光線的偏振方向呈水平,此方向與下偏振片的方向一致,因此此光線能夠穿過(guò)下偏振片而到達(dá)反射板。最后,該光線的反射光線沿原路返回,從而使LCD顯示器呈現(xiàn)透明狀。當(dāng)在液晶盒的上、下電極間加上一定電壓后,電極部分的液晶分子轉(zhuǎn)為垂直排列,從而失去旋光性。因此,從上偏振片入射的偏振光不被旋轉(zhuǎn),當(dāng)此偏振光到達(dá)下偏振片時(shí),被下偏振片吸收,無(wú)法到達(dá)反射板形成反射光,所以呈現(xiàn)黑色。這樣控制電路可以根據(jù)顯示的字符、圖形的需要控制液晶盒上、下電極之間的電壓,使得部分LCD顯示器中的部分點(diǎn)呈透明狀,而另一些點(diǎn)呈黑色,就可以在LCD顯示器上顯示各種字符或圖形。圖7-11LCD顯示器工作原理示意圖段式LCD顯示器是將液晶盒各段的其中一個(gè)電極連在一起,另一個(gè)電極作為獨(dú)立引腳,相應(yīng)的控制電路直接控制液晶盒上、下電極之間的電壓,使各段處于亮或滅的狀態(tài),從而組合出不同的字符。段式LCD液晶盒上、下電極之間的電壓必須采用一定頻率的交流信號(hào),否則容易損壞LCD顯示器。段式LCD顯示器的驅(qū)動(dòng)電路可以采用專用的段式LCD驅(qū)動(dòng)芯片。當(dāng)段式LCD顯示位比較多時(shí),其驅(qū)動(dòng)電路也相應(yīng)比較復(fù)雜,面積也會(huì)增加。字符型LCD顯示器是一種通用的顯示器件,常見(jiàn)的字符型LCD的型號(hào)大多數(shù)以其每行能夠顯示的字符個(gè)數(shù)和顯示字符的行數(shù)來(lái)命名。如0802(2行,每行8個(gè)字符)、1601(1行,每行16個(gè)字符)、1602(2行,每行16個(gè)字符)、2004(4行,每行20個(gè)字符)等。所有字符型LCD顯示器的接口都相同。圖7-12是2行×16個(gè)字符(1602)的字符型LCD顯示器的外型圖和引腳排列。該顯示器由32個(gè)字符點(diǎn)陣塊組成,每個(gè)字符點(diǎn)陣塊由5×7或5×10個(gè)點(diǎn)陣組成,可以顯示ASCII碼表中的所有可視的字符。其內(nèi)部ROM中存儲(chǔ)有ASCII碼字符表,器件內(nèi)部有若干個(gè)用戶自編程字符存儲(chǔ)區(qū),允許用戶編寫(xiě)ASCII碼字符表之外的特殊字符或圖形。器件內(nèi)部還具有數(shù)據(jù)RAM存儲(chǔ)器,用于保存顯示數(shù)據(jù)。大多數(shù)字符型LCD顯示器都以模塊(Module)形狀使用,LCD顯示器模塊(LCM)中有LCD驅(qū)動(dòng)電路(點(diǎn)陣的行和列掃描電路)和接口控制器電路,有些字符型LCD顯示器模塊還帶有背光板(BackLightingBoard)組件。LCM的接口控制器是連接主控制器的通道,目前常用的LCM接口控制器有Hitachi公司的HD44780和Samsung公司的SED1278等,它們的時(shí)序、接口電路互相兼容。圖7-12字符型LCD顯示器外型和引腳排列、名稱標(biāo)準(zhǔn)的字符型LCD顯示器模塊的接口引腳名稱和引腳功能如表7-3所示。字符型LCD顯示器模塊是一種智能器件,它的內(nèi)部有兩種寄存器:指令寄存器和數(shù)據(jù)寄存器。單片機(jī)等主控制系統(tǒng)對(duì)LCM的指令寄存器寫(xiě)操作,可以將“清屏”等控制指令發(fā)送給LCM;對(duì)指令寄存器讀操作,得到的數(shù)據(jù)的最高位是LCM的狀態(tài)(空閑狀態(tài)或忙狀態(tài))標(biāo)志位,低7位是地址計(jì)數(shù)器信息。對(duì)LCM的數(shù)據(jù)存儲(chǔ)器寫(xiě)操作,可以修改當(dāng)前地址中的顯示字符;讀操作可以得到當(dāng)前顯示地址中的顯示數(shù)據(jù)。字符型LCD顯示器模塊的詳細(xì)指令如表7-4所示。

LCM的顯示數(shù)據(jù)存儲(chǔ)器DDRAM與顯示屏上的字符顯示位置是一一對(duì)應(yīng)的,表7-5給出了LCM2004(4行,每行20個(gè)字符)的DDRAM地址與字符顯示位置的對(duì)應(yīng)關(guān)系。當(dāng)單片機(jī)等主控制器系統(tǒng)需要把字符顯示在屏幕的某一位置時(shí),首先將對(duì)應(yīng)位置的DDRAM的地址寫(xiě)到地址計(jì)數(shù)器(指令寄存器)中,然后再將該字符的ASCII碼寫(xiě)入DDRAM中,這樣就可以完成一個(gè)字符的顯示。字符型LCD顯示器模塊的接口讀/寫(xiě)操作時(shí)序如圖7-13和圖7-14所示,其時(shí)序參數(shù)見(jiàn)表7-6。值得注意的是,LCM的讀/寫(xiě)時(shí)序不兼容IntelBus時(shí)序,而MCS-51系列單片機(jī)的“三總線”時(shí)序兼容IntelBus時(shí)序,所以后面介紹的MCS-51單片機(jī)與LCM接口電路和接口控制程序都是按照?qǐng)D7-13和圖7-14所示的讀/寫(xiě)操作時(shí)序進(jìn)行設(shè)計(jì)的。圖7-13LCM接口讀操作時(shí)序圖7-14LCM接口寫(xiě)操作時(shí)序

MCS-51單片機(jī)與LCM接口的典型電路如圖7-15所示。圖中利用P2.7(AB15)和WR、RD邏輯組合后作為L(zhǎng)CM1602的使能控制;P1.0和P1.1分別作為L(zhǎng)CM的RS和R/W的控制信號(hào)。當(dāng)MCS-51單片機(jī)對(duì)外部地址7FFFH單元進(jìn)行讀或?qū)懖僮鲿r(shí),LCM1602的工作使能端有效,驅(qū)動(dòng)程序通過(guò)設(shè)置P1.0和P1.1的電平狀態(tài)以選擇LCM1602的命令或數(shù)據(jù)寄存器及LCM1602的讀或?qū)懖僮?。該電路的地址和I/O端口狀態(tài)與LCM寄存器的對(duì)應(yīng)關(guān)系見(jiàn)表7-7。圖7-15MCS-51單片機(jī)與LCM1602的接口電路按照?qǐng)D7-15所示的接口電路,相應(yīng)的接口控制程序如下:#include<io51.h>#include<string.h>#define

LCDRS

P1.0

//LCD的RS控制線#define

LCDRW

P1.1

//LCD的R/W控制線#define

ReadLCMCmdReg LCDRS=0;\

LCDRW=1

//設(shè)置LCM進(jìn)入“讀命令”操作#define

WriteLCMCmdReg

LCDRS=0;\

LCDRW=0

//設(shè)置LCM進(jìn)入“寫(xiě)命令”操作#define

ReadLCMDataReg

LCDRS=1;\

LCDRW=1

//設(shè)置LCM進(jìn)入“讀數(shù)據(jù)”操作#define

WriteLCMDataReg

LCDRS=1;\

LCDRW=0

//設(shè)置LCM進(jìn)入“寫(xiě)數(shù)據(jù)”操作#define

LCMPORTAdr*(unsignedchar*)(0x017FFF)

//LCM的地址codeTestScreen[][]={{“LCMInterface”},{“ZJUT2001/10”}};

//測(cè)試字符串unsignedcharReadBusyandACFromLCM(void)

//讀忙標(biāo)志和地址計(jì)數(shù)器{

unsignedcharresult;

ReadLCMCmdReg;

//置LCD-RS=0,LCD-RW=1

result=LCMPORTAdr;

//讀LCM的忙標(biāo)志和地址計(jì)數(shù)器

return(result);

//返回忙標(biāo)志(MSB=Bsy)和地址計(jì)數(shù)器}voidWriteDataToLCM(unsignedchar_data)

//寫(xiě)數(shù)據(jù)操作{

WriteLCMDataReg;

//置LCD-RS=1,LCD-RW=0

LCMPORTAdr=_data; //寫(xiě)數(shù)據(jù)到LCM的數(shù)據(jù)寄存器

do{

_data=ReadBusyandACFromLCM();

}while((_data&0x80)==0x80); //等待LCM操作完畢}voidInit_LCM1602(void)

//初始化LCM操作{

Delay(100);

WriteCommandToLCM(0x38);

//連續(xù)執(zhí)行3次,等待LCM上電自復(fù)位結(jié)束

Delay(80);

WriteCommandToLCM(0x38);

Delay(80);

WriteCommandToLCM(0x38);

//設(shè)置接口DB寬度(8位)和LCM顯示行數(shù)(2行)

Delay(80);

WriteCommandToLCM(0x01); //執(zhí)行清屏操作

Delay(50);

WriteCommandToLCM(0x06); //設(shè)置光標(biāo)為加1模式

Delay(50);

WriteCommandToLCM(0x0C); //設(shè)置光標(biāo)為移位模式

Delay(50);}voidGotoXYofLCMScreen(unsignedcharx,unsignedchary){

x&=0x01;

//顯示行數(shù)僅可以為0或1,即第1或2行

y&=0x0F;

//顯示的列位置僅可以為0~F

y|=(x==0)?0x40:0xC0;

//判斷是第1或2行

WriteCommandToLCM(y);

//寫(xiě)到LCM的地址計(jì)數(shù)器

do{

y=ReadBusyandACFromLCM();

while((y&0x80)==0x80);

//等待LCM操作完畢}voidPutCharonLCMScreen(unsignedcharx,unsignedchary,

unsignedchar_char);

//顯示一個(gè)字符在屏幕中指定的位置(x,y){

GotoXYofLCMScreen(x,y); //當(dāng)前顯示器地址轉(zhuǎn)向(x,y)

WriteDataToLCM(_char); //將字符(_char)寫(xiě)到當(dāng)前顯示地址}voidPutStrToLCMScreen(unsignedcharx,unsignedchary,

unsignedchar*str,unsignedcharlen){ //從屏幕中指定的位置(x,y)開(kāi)始顯示字符串str

unsignedchari;

for(i=0;i<len;i++)

{

PutCharonLCMScreen(x,y++,str[i]);

//將一個(gè)字符寫(xiě)到當(dāng)前顯示地址

if(y>0x0F)

//顯示自動(dòng)換行調(diào)整操作

{

y=0;

//下一行的第1列

x++;

//下一行

}

}}voidmain(void) //主程序調(diào)用上面的子程序,顯示兩個(gè)字符串{

//8051初始化程序

Init_LCM1602();

//初始化LCM(2行,8位并行接口)

PutStrToLCMScreen(0,0,TestScreen[0][0],16);

//從(0,0)開(kāi)始顯示顯示"_LCM_Interface__"

PutStrToLCMScreen(0,0,TestScreen[1][0],16);

//從(1,0)開(kāi)始顯示顯示"__ZJUT_2002/10__"

...

//繼續(xù)執(zhí)行其他任務(wù)}7.2.3圖形點(diǎn)陣LCD顯示器的接口目前常用的圖形點(diǎn)陣LCD顯示器一般都采用模塊結(jié)構(gòu)(稱為圖形LCM)。MCS-51單片機(jī)與圖形點(diǎn)陣LCD顯示器接口電路取決于顯示模塊的接口控制器。目前常用的圖形LCM的接口控制器有:Toshiba公司的T6963C、Hitachi公司的HD61830、Samsung公司的“KS0107+KS0108”(分別為行和列驅(qū)動(dòng))等。接口控制器不同,它們與單片機(jī)的接口電路、時(shí)序和接口控制軟件也不完全相同。圖7-16是G12864圖形LCM的內(nèi)部結(jié)構(gòu)框圖,它采用Samsung公司的圖形LCD驅(qū)動(dòng)控制器,其屏幕由64(行)×128(列)點(diǎn)陣組成,可以顯示16點(diǎn)陣的4行×8列(32個(gè))漢字或128×64全屏幕點(diǎn)陣圖形。該模塊的控制板上帶有圖形LCM必需的對(duì)比度調(diào)節(jié)負(fù)電壓產(chǎn)生電路,設(shè)計(jì)接口電路時(shí)可以直接利用該LCM輸出的負(fù)電壓(VEE)。而且LCM的控制板中還具有背光板高壓驅(qū)動(dòng)電路,用戶接口電路對(duì)背光板的控制采用兼容TTL邏輯電平。它采用單DC+5V供電,功耗極低,當(dāng)背光板關(guān)閉時(shí),消耗電流3mA;當(dāng)背光板亮?xí)r,消耗電流小于50mA。它與MCS-51單片機(jī)等主控制系統(tǒng)采用8位并行接口及20引腳連接器,各引腳名稱和功能如表7-8所示。圖7-16G12864圖形LCM的內(nèi)部結(jié)構(gòu)

G12864圖形LCD顯示器使用7種指令與單片機(jī)等主控制器之間通信,7種指令的詳細(xì)格式和參數(shù)見(jiàn)表7-9。在表7-9中所謂的頁(yè)地址就是DDRAM的行地址,8行為一頁(yè),LCMG12864共64行,即8頁(yè),A2~A0用于選擇第0~7頁(yè)。讀/寫(xiě)數(shù)據(jù)對(duì)頁(yè)地址沒(méi)有影響,頁(yè)地址為當(dāng)前指令指定的位置或復(fù)位后位于第0頁(yè)地址。頁(yè)地址與DDRAM的對(duì)應(yīng)關(guān)系如表7-10所示。

MCS-51單片機(jī)在執(zhí)行指令“設(shè)y地址”時(shí),將新的6位y地址寫(xiě)到y(tǒng)地址計(jì)數(shù)器中。當(dāng)單片機(jī)對(duì)DDRAM中的數(shù)據(jù)進(jìn)行讀或?qū)懖僮?讀/寫(xiě)數(shù)據(jù))時(shí),y地址計(jì)數(shù)器會(huì)加1,指向下一個(gè)地址。圖7-17是G12864顯示模塊與主控制系統(tǒng)的接口讀/寫(xiě)操作時(shí)序,其時(shí)間參數(shù)見(jiàn)表7-11。圖7-17G12864讀/寫(xiě)操作時(shí)序(a)讀操作時(shí)序;(b)寫(xiě)操作時(shí)序根據(jù)圖7-17所示的操作時(shí)序,設(shè)計(jì)如圖7-18所示的G12864與MCS-51單片機(jī)的接口電路。由于G12864接口時(shí)序的特殊性,采用MCS-51單片機(jī)的擴(kuò)展I/O端口作為G12864的控制信號(hào),擴(kuò)展的I/O端口Bit.0和Bits.1分別作為兩片列驅(qū)動(dòng)器(KS0108A-1和KS0108A-2)的片選控制,這兩個(gè)信號(hào)任何時(shí)刻僅允許一個(gè)輸出高有效電平。選通其中的一片列驅(qū)動(dòng)器,當(dāng)Bit.0=1且Bit.1=0時(shí),第1片列驅(qū)動(dòng)器被選中;Bit.0=0且Bit.1=1時(shí),第2片列驅(qū)動(dòng)器被選中。Bit.2作為L(zhǎng)CM的指令和數(shù)據(jù)寄存器選擇控制信號(hào),Bit.3作為L(zhǎng)CM讀/寫(xiě)選擇控制信號(hào)。Bit.6控制LCM的復(fù)位和運(yùn)行狀態(tài),Bit.6=0,復(fù)位LCM;正常運(yùn)行狀態(tài)時(shí)Bit.6=1。Bit.7作為G12864的背光板打開(kāi)或關(guān)閉控制信號(hào),Bit.7=1,背光板被打開(kāi);Bit.7=0,背光板被關(guān)閉。G12864的使能控制信號(hào)受P2.7(AB15)控制,當(dāng)AB15=0時(shí),8051執(zhí)行讀操作即讀LCM的數(shù)據(jù)寄存器或指令寄存器;當(dāng)AB15=1時(shí),8051執(zhí)行寫(xiě)操作即寫(xiě)LCM的指令寄存器或數(shù)據(jù)寄存器。擴(kuò)展的8位鎖存器的寫(xiě)鎖存信號(hào)受P2.6(AB14)控制,當(dāng)AB14=0時(shí),8051可以將控制G12864狀態(tài)字鎖存到擴(kuò)展的I/O輸出端口處。圖7-18MCS-51單片機(jī)與LCM12864的接口電路圖形點(diǎn)陣LCD顯示器可以直接顯示漢字和圖形、曲線,其原理是控制LCD點(diǎn)陣中的點(diǎn)的亮或暗,亮和暗的點(diǎn)陣按一定規(guī)律可以組成漢字,組成一幅、若干幅圖形和曲線。而所有的LCM都帶有顯示緩存,單片機(jī)等主控制器只需要將點(diǎn)陣的亮和暗控制信息寫(xiě)到LCM的顯示緩存中,LCM的行、列驅(qū)動(dòng)器會(huì)自動(dòng)掃描LCD點(diǎn)陣,保持用戶期望的顯示效果。所有的LCM顯示緩存都采用字節(jié)方式讀/寫(xiě),對(duì)用戶來(lái)講,LCM屏幕上的點(diǎn)陣是按字節(jié)方式8個(gè)點(diǎn)一組來(lái)控制的。一個(gè)16點(diǎn)陣的漢字在LCM的屏幕上是采用16×16個(gè)點(diǎn)來(lái)表達(dá)的,即一個(gè)16點(diǎn)陣的漢字需要32個(gè)字節(jié)的編碼數(shù)據(jù),這些編碼數(shù)據(jù)包含16×16點(diǎn)陣中亮和暗的控制信息。

G12864是一種全屏幕點(diǎn)陣圖形顯示器,可以在G12864的屏幕上僅顯示一幅128×64點(diǎn)陣的圖形或曲線。當(dāng)用它來(lái)顯示漢字或字符時(shí),可以按照漢字或字符點(diǎn)陣的大小任意分割成多個(gè)小點(diǎn)陣塊。如果用來(lái)顯示16×16點(diǎn)陣的漢字,可以分割成32個(gè)16×16點(diǎn)陣塊,能夠顯示32個(gè)漢字;如果用來(lái)顯示32×32點(diǎn)陣漢字,能夠顯示8個(gè)32×32點(diǎn)陣漢字。下面就是在G12864顯示器上顯示16×16點(diǎn)陣漢字的程序:#include<io51.h>#include<string.h>#define

LCMCWAdr*(unsignedchar*)(0x01BFFF)

//LCM控制字鎖存器端口地址#defineLCMPORTAdr*(unsignedchar*)(0x017FFF) //LCM讀/寫(xiě)使能端口地址#define

_CS1

0x01

//指定各控制信號(hào)在鎖存器中的位置(硬件有關(guān))#define

_CS2 0x02#define

_DI

0x04#define

_RW

0x08#define

_RST

0x40#define

_ELON

0x80unsignedcharidataELState=0;

//是否允許背光板亮的狀態(tài)寄存器codeunsignedcharTestHZDotCode[][]={

//將“機(jī)電一體化”5個(gè)漢字的編碼保存在Code區(qū){

0x00,0x0C,0x07,0x7F,0x61,0x03,0x42,0x30,

0x0F,0x00,0x00,0x00,0x7F,0x40,0x60,0x00,

0x00,0x30,0x10,0xFE,0x16,0x90,0x10,0x00,

0xFC,0x04,0x04,0x04,0xFC,0x00,0x00,0x00},

//漢字“機(jī)”的編碼{

0x00,0x00,0x00,0x1F,0x04,0x04,0x04,0x7F,

0x44,0x44,0x44,0x44,0x47,0x60,0x20,0x00,

0x00,0x00,0x00,0xF0,0x90,0x90,0x90,0xFE,

0x90,0x90,0x90,0x90,0xF0,0x00,0x00,0x00},

//漢字“電”的編碼{

0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,

0x01,0x

溫馨提示

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

最新文檔

評(píng)論

0/150

提交評(píng)論