新聞中心

        EEPW首頁 > 嵌入式系統 > 設計應用 > 初步認識51單片機-2.2單片機控制LCD1602液晶顯示模塊

        初步認識51單片機-2.2單片機控制LCD1602液晶顯示模塊

        作者: 時間:2016-11-21 來源:網絡 收藏
        上面學的兩招,控制IO和延時,在這里要舉的第一個例子就是LCD1602。LCD1602什么意思,表示一行可以顯示16個字符,一共有兩行。先來個LCD1602的簡單介紹,1602LCD主要技術參數:

        顯示容量:16×2個字符

        本文引用地址:http://www.104case.com/article/201611/319543.htm

        芯片工作電壓:4.5—5.5V

        工作電流:2.0mA(5.0V)

        模塊最佳工作電壓:5.0V

        字符尺寸:2.95×4.35(W×H)mm

        引腳功能說明

        1602LCD采用標準的14腳(無背光)或16腳(帶背光)接口,各引腳接口說明如表1所示:

        第1腳:VSS為地電源

        第2腳:VDD接5V正電源。

        第3腳:VL為液晶顯示器對比度調整端,接正電源時對比度最弱,接地時對比度最高,對比度過高時會產生“鬼影”,使用時可以通過一個10K的電位器調整對比度。

        第4腳:RS為寄存器選擇,高電平時選擇數據寄存器、低電平時選擇指令寄存器。

        第5腳:R/W為讀寫信號線,高電平時進行讀操作,低電平時進行寫操作。當RS和R/W共同為低電平時可以寫入指令或者顯示地址,當RS為低電平R/W為高電平時可以讀忙信號,當RS為高電平R/W為低電平時可以寫入數據。

        第6腳:E端為使能端,當E端由高電平跳變成低電平時,液晶模塊執行命令。

        第7~14腳:D0~D7為8位雙向數據線。

        第15腳:背光源正極。

        第16腳:背光源負極。

        我們來看看如何使用這兩招控制LCD1602液晶模塊。既然是用單片機控制LCD1602,那么根據前面的分析思想,首先要搞清楚誰是控制對象,誰是被控制對象。很顯然,LCD1602是被控制對象,那么我們就先從LCD1602開始分析。所謂控制也可以理解為溝通,那么如何與LCD1602溝通呢?可以想一想,平時人與人是如何溝通的?溝通之前先要打個招呼吧,比如“你好”之類的,電話里面要先講個“喂?”,之后才進入溝通正題了。其實單片機與LCD1602的溝通方式也一樣,“喂?”在這個例子里面就叫初始化。后面也會經常碰到這個“初始化”的概念。其實器件也是人設計的,所以他的工作方式從某種程度上講,也是人的溝通方式。打完招呼后,就開始進入真正主題了。什么主題呢?LCD1602是顯示模塊,主要作用當然是顯示了。那么顯示什么呢?很明顯,顯示內容當然來自于單片機了,單片機讓它顯示什么它就顯示什么。這個‘顯示什么’就是傳送的數據。那么怎么往1602傳送數據呢?1602什么意思,表示2行16個字符,也就是有不同的顯示地點,那么如何確定顯示地點呢?因此前面的分析可以總結為三個問題,如何初始化,如何傳送顯示的內容(顯示什么),在哪里顯示。這三個問題如何解答呢?當然要去看芯片手冊了。

        為了解決這三個問題,我們先來看看人與人之間是如何溝通的,如果當面溝通,你的信號(聲音)能夠直接傳到對方,而且能讓對方聽懂。如果相距比較遠,那么就使用電話等通信工具。前者信號傳遞載體是空氣,后者是電話線。那么我們來看看MCU與LCD1602的信號傳遞載體是什么樣的。查看原理圖。因為是MCU與1602之間的溝通,當然這里我們只查看與單片機相連接的部分。

        從圖中我們看到,單片機通過P2.7,P2.6分別與RS,EN連接,P0端口與D0到D7連接,一共10根線。那么也就是說,單片機的所有指令,數據等都是通過這10根線來完成的。怎么樣去控制LCD呢,當然是閱讀LCD的說明手冊。這里來個比喻,房間內一個人規定,敲三下門,屋內的人才把門打開。如果你要進入屋內,就必須敲三下,如果你不知道這個規則,敲了四下,或者大喊大叫,門也開不了。這個規定可以是多樣化,比如一共敲兩下,第一下要敲重一點,第二下要敲輕一點。或者重敲三下,輕敲一下,等等。而且這里你不需要問為什么,照著做就行了。其實LCD1602包括后面會講到的其他模塊同樣如此,你要與它溝通,當然必須按照它的規則來。下面我們就來解讀它的規則,來解決前面提到的三個問題,

        LCD1602初始化;在哪里顯示;顯示什么。

        (1)LCD1602初始化

        關于這一點,說明手冊上已經告訴我們了,這里全盤復制過來。

        延時15ms

        寫指令38H

        延時5ms

        寫指令38H

        寫指令08H

        寫指令01H

        寫指令06H

        寫指令0CH

        以上為初始化過程,延時部分好解決,前面講過了。這里就看如何寫指令了。寫指令這個過程肯定是通過上圖中10根線來完成的。D0-D7一共八根線應該是用來存放指令的內容。問題來了,1602怎么知道單片機給我的是命令還是數據。(命令是什么,在哪里顯示,屏幕清零;數據是什么,顯示什么內容,顯示A還是B)。LCD1602看到RS為高時,就明白了,哦,你要通過P0端口給我數據了,于是LCD1602就把這些數據拿過來了。看到RS為低時,就知道你要給我指令了。通過這種方式,單片機能準確的傳遞指令或者數據信息,實現與LCD1602的溝通。是不是這樣就能讓LCD1602正常執行了。不是的。回到我們前面講的那個例子,這里加個條件,屋內人聽到敲門三下后,判斷暗號正確了,但是沒有直接開門,而是通知了他的上級,得到上級的授權后,才開門。也就是兩個條件,暗號正確和上級授權。LCD1602也一樣,收到指令沒有立即執行,還要等另外一個信號,就是EN使能信號。此時EN給個一定寬度的脈沖,LCD1602開始執行。

        時序圖如上圖所示,這里少了R/W信號,用于控制從LCD1602讀取還是寫入的,為了簡化過程,在硬件上把R/W接地了,也就是只能寫不能讀。同時,讀忙信號也不能操作,這里采用延時的方法替代。根據前面的分析很容易的寫出寫指令的代碼:

        ?void write_com(unsigned char mycmd)

        {

        delayMs(5);//注意這里需要延時5ms比較保險 代替判斷忙信號

        P0=mycmd; //準備好指令

        RS=0; //告訴LCD1602,P0中放的是指令不是數據

        EN=1;

        delayUs(5); //根據時序圖,脈沖要有一定寬度

        EN=0; //使指令有效,開始執行

        }

        同樣的道理,以上代碼中,只需改一下RS信號為1,就是寫數據的代碼了

        void write_com(unsigned char mydata)

        {

        delayMs(5);//注意這里需要延時5ms比較保險 代替判斷忙信號

        P0=mycmd; //準備好指令

        RS=1; //告訴LCD1602,P0中放的是數據不是指令

        EN=1;

        delayUs(5); //根據時序圖,脈沖要有一定寬度

        EN=0; //使指令有效,開始執行

        }

        講到這里,LCD1602初始化代碼應該能寫出了。同時我們也已經寫出了傳遞指令的代碼,那么現在我們只要知道指令內容就可以了。

        1602LCD的指令說明及時序

        1602液晶模塊內部的控制器共有11條控制指令,如表2所示:

        1602液晶模塊的讀寫操作、屏幕和光標的操作都是通過指令編程來實現的。(說明:1為高電平、0為低電平)

        指令1:清顯示,指令碼01H,光標復位到地址00H位置。

        指令2:光標復位,光標返回到地址00H。

        指令3:光標和顯示模式設置 I/D:光標移動方向,高電平右移,低電平左移 S:屏幕上所有文字是否左移或者右移。高電平表示有效,低電平則無效。

        指令4:顯示開關控制。 D:控制整體顯示的開與關,高電平表示開顯示,低電平表示關顯示 C:控制光標的開與關,高電平表示有光標,低電平表示無光標 B:控制光標是否閃爍,高電平閃爍,低電平不閃爍。

        指令5:光標或顯示移位 S/C:高電平時移動顯示的文字,低電平時移動光標。

        指令6:功能設置命令 DL:高電平時為4位總線,低電平時為8位總線 N:低電平時為單行顯示,高電平時雙行顯示 F: 低電平時顯示5x7的點陣字符,高電平時顯示5x10的點陣字符。

        指令7:字符發生器RAM地址設置。

        指令8:DDRAM地址設置。

        指令9:讀忙信號和光標地址 BF:為忙標志位,高電平表示忙,此時模塊不能接收命令或者數據,如果為低電平表示不忙。

        指令10:寫數據。

        指令11:讀數據。

        你需要給LCD1602什么指令,只需要傳遞給void write_com(unsignedchar mycmd)函數中的mycmd參數就行了。

        (2)在哪里顯示

        知道了這個,現在我們就能解決前面提到的第二個問題,在哪里顯示,

        例如第二行第一個字符的地址是40H,那么是不是它的地址就是40H了。注意表2中第8條數據存儲地址,D7已經被寫死了。最終的顯示地址是40H+10000000B,因此我們只要把這個值傳給mycom,LCD1602就知道在第二行第一個位置顯示了。

        (3)顯示什么

        前面講了,如果傳送數據就是要顯示的內容。比如我要顯示字母A,怎么操作呢。

        以上圖中可以知道,如果你要顯示A,那么數據的高位為0100,低位為0001,因此為01000001。把這個數據傳送給LCD1602,它就知道要顯示A了。

        現在回過頭來看看,我們在使用單片機控制LCD1602這個過程中用到了單片機的哪些知識。回去看看圖1,10根連接線,P2.6和P2.7引腳,再加上P0端口,主要是通過P2.6和P2.7高低變化來發出指令或數據,P0的變化反映指令或數據的內容。可見,這個過程中我們只用到了IO口控制和延時。其他很長的部分我們用在理解1602的使用規則了。注意這里是使用規則,談不上原理。比如你給LCD1602發送清屏指令時,你明白LCD1602收到這個指令是如何操作清屏的嗎?不知道,也沒有必要知道。液晶模塊說明書也不告訴你。好比你使用手機時,你點擊一下某個應用程序就打開了,然后按照它的規則去使用就行了,比如聽歌,上網等等,你不用關心它們是怎么實現的。其實手機也是個模塊,我們只要學會操作就行了,不管它里面發生了什么事情。

        附參考代碼如下:

        #include

        void LCD_init(void);

        void delayUs(unsigned char t);

        void delayMs(unsigned char t);

        void write_com(unsigned char mycmd);

        void write_data(unsigned char mydata);

        sbit RS=P2^7;

        sbit EN=P2^6;

        void main (void)

        {

        LCD_init();

        write_com(0x0f);

        write_data(0x41);

        while(1);

        }

        void LCD_init(void)

        {

        delayMs(15);

        write_com(0x38);

        delayMs(5);

        write_com(0x38);

        write_com(0x08);

        write_com(0x01);

        write_com(0x06);

        write_com(0x0c);

        }

        void delayUs(unsigned char t)

        {

        while(--t);

        }

        void delayMs(unsigned char t)

        {

        while(--t)

        {

        delayUs(245);

        delayUs(245);

        }

        }

        void write_com(unsigned char mycmd)

        {

        delayMs(5);//注意這里需要延時5ms比較保險代替判斷忙信號

        P0=mycmd; //準備好指令

        RS=0; //告訴LCD1602,P0中放的是指令不是數據

        EN=1;

        delayUs(5); //根據時序圖,脈沖要有一定寬度

        EN=0; //使指令有效,開始執行

        }

        void write_data(unsigned char mydata)

        {

        delayMs(5);//注意這里需要延時5ms比較保險

        P0=mydata;

        RS=1;

        EN=1;

        delayUs(5);

        EN=0;

        }



        評論


        技術專區

        關閉
        主站蜘蛛池模板: 新源县| 连州市| 镇坪县| 磐石市| 体育| 巫山县| 莫力| 来安县| 虞城县| 岚皋县| 临漳县| 睢宁县| 双城市| 五河县| 襄樊市| 海兴县| 木里| 荃湾区| 什邡市| 会泽县| 平邑县| 玉山县| 宜丰县| 尚义县| 鸡泽县| 饶阳县| 镇巴县| 金寨县| 洛南县| 乐清市| 改则县| 运城市| 醴陵市| 奇台县| 辽中县| 龙南县| 双峰县| 江安县| 南溪县| 思南县| 商南县|