|
/*單片機(jī)I/O口使單片機(jī)資源的重要組成部分,也是用來擴(kuò)展外圍設(shè)備的必選資源,盡可能以更少的I/O口實(shí)現(xiàn)更多的功能是單片機(jī)工程師追求的目標(biāo),現(xiàn)在的一些串行器件也為這一目標(biāo)的實(shí)現(xiàn)添加了更多的可能性,比如I2C總線,MAXIM力推的1-WIRE等等,都可以以很少的I/O口實(shí)現(xiàn)更多的功能,當(dāng)然這是以降低一定的速度為代價(jià)的。 廢話少說,進(jìn)入正題。 顯示器件多見的是LED數(shù)碼管,LCD液晶屏等。一般的數(shù)碼管成本低廉,在顯示內(nèi)容要求不多的時(shí)候適用;LCD液晶屏以更多的顯示空間得到了許多人的愛好,不過成本上要高的多(市場(chǎng)價(jià)在20元左右),本文以LCD1602為例說明如何驅(qū)動(dòng)液晶屏。 LCD1602外接的控制接口有RS,R/W,E;數(shù)據(jù)接口為DB7--DB0?偣灿11跟線與單片機(jī)的I/O口連接,若使用標(biāo)準(zhǔn)的51單片機(jī),至少占用了一個(gè)端口再加上另一個(gè)端口的部分I/O口。這再很多應(yīng)用場(chǎng)合是不大可取的。所以很有必要減少連接數(shù)。從其數(shù)據(jù)手冊(cè)上介紹的4線連接方式可以達(dá)到只使用7個(gè)I/O口即可滿足要求,其中為3個(gè)控制口RS,R/W,E和數(shù)據(jù)口的DB7--DB4;寫入數(shù)據(jù)或指令的順序是先寫高半個(gè)字節(jié),再寫低半個(gè)字節(jié)。 其中P0口的高四位接到LCD1602的DB7-DB4,P3.0-P3.1分別接RS,R/W,E; 下面給出驅(qū)動(dòng)源程序*/ #i nclude <reg52.h> #i nclude "intrins.h"
#define uint unsigned int #define uchar unsigned char #define TRUE 1 #define FALSE 0 #define nop _nop_() #define PtData P0 //定義連接口線, #define PtContr P3 sbit RS="PtContr"^0; sbit RW="PtContr"^1; sbit E="PtContr"^2;
void InitialLcd(); void WriteLcdInstr(uchar); void WriteLcdData(uchar); void CheckLcdBusy(); uchar HexToDdram(uchar); void Delay(unsigned int); main() {Delay(1000); InitialLcd(); WriteLcdInstr(0x80); WriteLcdData('e'); WriteLcdData('l'); WriteLcdData('k'); WriteLcdData('e'); WriteLcdData('l'); WriteLcdData('i'); WriteLcdData('k'); WriteLcdData('e'); WriteLcdInstr(0xc0); WriteLcdData('L'); WriteLcdData('C'); WriteLcdData('D'); WriteLcdData('1'); WriteLcdData('6'); WriteLcdData('0'); WriteLcdData('2'); while(1) { WriteLcdInstr(0x0f); Delay(30000); WriteLcdInstr(0x08); Delay(40000); } }
//----------------LCD1602函數(shù)---------------------// //---初始化 void InitialLcd() {Delay(600);//延時(shí)應(yīng)大于15ms,不同的晶振使需要修改,本程序再6M下調(diào)試通過 RS=0; RW=0;nop; E=0;nop; E=1;nop; PtData=0x20;// nop; E=0; Delay(200);//延時(shí)應(yīng)大于4.1ms E=1;nop; PtData=0x20;// nop; E=0; Delay(5);//延時(shí)應(yīng)大于100us E=1;nop; PtData=0x20;// nop; E=0;//設(shè)置4位操作; WriteLcdInstr(0x01);//清屏 WriteLcdInstr(0x28);//設(shè)置4位操作,1行顯示,5x8 WriteLcdInstr(0x02);//光標(biāo)歸位 WriteLcdInstr(0x06);//AC自動(dòng)加1,畫面不動(dòng) WriteLcdInstr(0x0f);//0x0f:光標(biāo)閃爍開; } //---寫指令 void WriteLcdInstr(uchar Temp) {CheckLcdBusy(); RS=0; RW=0; E=0;nop; E=1;nop; PtData=Temp; nop; E=0;nop; E=1;nop; PtData=(Temp<<4); nop; E=0;nop; } //---寫數(shù)據(jù) void WriteLcdData(uchar Temp) { CheckLcdBusy(); RS=1; RW=0; E=0;nop; E=1;nop; PtData=Temp; nop; E=0;nop; E=1;nop; PtData=(Temp<<4); nop; E=0;nop; }
//---查忙 void CheckLcdBusy() {uchar Temp,t; PtData=0xff;
RW=1; RS=0;nop; E=0;nop; do {nop; E=1;nop; Temp=PtData; nop;nop;nop; E=0;nop;nop; E=1;nop; t=PtData; nop;nop;nop; E=0;nop;nop; Temp&=0x80; }while(Temp==0x80); } //---delay void Delay(unsigned int N) {unsigned int i; for(i=0;i<N;i++){i=i;} } |