日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

晨輝教你輕松學(xué)51--------液晶篇(1602)

 ylw527 2011-01-26
晨輝教你輕松學(xué)51--------液晶篇(1602)
 
        1602字符液晶在實際的產(chǎn)品中運用的也比較多了,前幾天留意了一下,發(fā)現(xiàn)宿舍門前的自動售水機就是采用的1602液晶進行顯示的。而且對于單片機的學(xué)習(xí)而言,掌握1602的用法是每一個學(xué)習(xí)者必然要經(jīng)歷的過程。在此,我將使用1602過程中遇到的問題以及感受記錄下來,希望能夠給初學(xué)者帶來一點指導(dǎo),少走一點彎路。
        所謂1602是指顯示的內(nèi)容為16*2,即可以顯示兩行,每行16個字符。目前市面上字符液晶絕大多數(shù)是基于HD44780液晶芯片的,控制原理是完全相同的,因此基于HD44780寫的控制程序可以很方便地應(yīng)用于市面上大部分的字符型液晶。

1602液晶的正面(綠色背光,黑色字體)


1602液晶背面(綠色背光,黑色字體)


另一種1602液晶模塊,顯示屏是藍色背光白色字體

        字符型LCD1602通常有14條引腳線或16條引腳線的LCD,多出來的2條線是背光電源線VCC(15腳)和地線GND(16腳),其控制原理與14腳的LCD完全一樣,引腳定義如下表所示:



        HD44780內(nèi)置了DDRAM、CGROM和CGRAM。 
        DDRAM就是顯示數(shù)據(jù)RAM,用來寄存待顯示的字符代碼。共80個字節(jié),其地址和屏幕的對應(yīng)關(guān)系如下表:

click here to enlarge

        也就是說想要在LCD1602屏幕的第一行第一列顯示一個"A"字,就要向DDRAM的00H地址寫入“A”字的代碼就行了。但具體的寫入是要按LCD模塊的指令格式來進行的,后面我會說到的。那么一行可有40個地址呀?是的,在1602中我們就用前16個就行了。第二行也一樣用前16個地址。對應(yīng)如下:
               DDRAM地址與顯示位置的對應(yīng)關(guān)系
  
 

        (事實上我們往DDRAM里的00H地址處送一個數(shù)據(jù),譬如0x31(數(shù)字1的代碼)并不能顯示1出來。這是一個令初學(xué)者很容易出錯的地方,原因就是如果你要想在DDRAM的00H地址處顯示數(shù)據(jù),則必須將00H加上80H,即80H,若要在DDRAM的01H處顯示數(shù)據(jù),則必須將01H加上80H即81H。依次類推。大家看一下控制指令的的8條:DDRAM地址的設(shè)定,即可以明白是怎么樣的一回事了) 
        1602液晶模塊內(nèi)部的字符發(fā)生存儲器(CGROM)已經(jīng)存儲了160個不同的點陣字符圖形,如下表所示,這些字符有:阿拉伯?dāng)?shù)字、英文字母的大小寫、常用的符號、和日文假名等,每一個字符都有一個固定的代碼,比如大寫的英文字母“A”的代碼是01000001B(41H),顯示時模塊把地址41H中的點陣字符圖形顯示出來,我們就能看到字母“A”

click here to enlarge 

        上表中的字符代碼與我們PC中的字符代碼是基本一致的。因此我們在向DDRAM寫C51字符代碼程序時甚至可以直接用P1='A'這樣的方法。PC在編譯時就把“A”先轉(zhuǎn)為41H代碼了。 
        字符代碼0x00~0x0F為用戶自定義的字符圖形RAM(對于5X8點陣的字符,可以存放8組,5X10點陣的字符,存放4組),就是CGRAM了。后面我會詳細(xì)說的。 
        0x20~0x7F為標(biāo)準(zhǔn)的ASCII碼,0xA0~0xFF為日文字符和希臘文字符,其余字符碼(0x10~0x1F及0x80~0x9F)沒有定義。 
        那么如何對DDRAM的內(nèi)容和地址進行具體操作呢,下面先說說HD44780的指令集及其設(shè)置說明,請瀏覽該指令集,并找出對DDRAM的內(nèi)容和地址進行操作的指令。共11條指令:

1.清屏指令


功能:<1> 清除液晶顯示器,即將DDRAM的內(nèi)容全部填入"空白"的ASCII碼20H;
            <2> 光標(biāo)歸位,即將光標(biāo)撤回液晶顯示屏的左上方;
            <3> 將地址計數(shù)器(AC)的值設(shè)為0。

2.光標(biāo)歸位指令


功能:<1> 把光標(biāo)撤回到顯示器的左上方;
            <2> 把地址計數(shù)器(AC)的值設(shè)置為0;
            <3> 保持DDRAM的內(nèi)容不變

3.進入模式設(shè)置指令


功能:設(shè)定每次定入1位數(shù)據(jù)后光標(biāo)的移位方向,并且設(shè)定每次寫入的一個字符是否移動。參數(shù)設(shè)定的情況如下所示:
              
    位名              設(shè)置
    I/D               0=寫入新數(shù)據(jù)后光標(biāo)左移                            
                        1=寫入新數(shù)據(jù)后光標(biāo)右移
     S                0=寫入新數(shù)據(jù)后顯示屏不移動
                        1=寫入新數(shù)據(jù)后顯示屏整體右移1個字

4.顯示開關(guān)控制指令

click here to enlarge
功能:控制顯示器開/關(guān)、光標(biāo)顯示/關(guān)閉以及光標(biāo)是否閃爍。參數(shù)設(shè)定的情況如下:
                位名              設(shè)置
                 D                0=顯示功能關(guān)           1=顯示功能開
                 C                0=無光標(biāo)                   1=有光標(biāo)
                 B                0=光標(biāo)閃爍               1=光標(biāo)不閃爍

5.設(shè)定顯示屏或光標(biāo)移動方向指令

click here to enlarge 功能:使光標(biāo)移位或使整個顯示屏幕移位。參數(shù)設(shè)定的情況如下:
S/C               R/L                設(shè)定情況
0                 0          光標(biāo)左移1格,且AC值減1
  0                 1          光標(biāo)右移1格,且AC值加1
  1                 0          顯示器上字符全部左移一格,但光標(biāo)不動
1                 1          顯示器上字符全部右移一格,但光標(biāo)不動

6.功能設(shè)定指令

click here to enlarge 功能:設(shè)定數(shù)據(jù)總線位數(shù)、顯示的行數(shù)及字型。參數(shù)設(shè)定的情況如下:
  位名              設(shè)置
   DL                             0=數(shù)據(jù)總線為4位
                    1=數(shù)據(jù)總線為8位
   N                               0=顯示1行
                    1=顯示2行
   F                                0=5×7點陣/每字符                                
                    1=5×10點陣/每字符

7.設(shè)定CGRAM地址指令

click here to enlarge 功能:設(shè)定下一個要存入數(shù)據(jù)的CGRAM的地址。

8.設(shè)定DDRAM地址指令

click here to enlarge 功能:設(shè)定下一個要存入數(shù)據(jù)的CGRAM的地址。
(注意這里我們送地址的時候應(yīng)該是0x80+Address,這也是前面說到寫地址命令的時候要加上0x80的原因)

9.讀取忙信號或AC地址指令
  
click here to enlarge 功能:<1> 讀取忙碌信號BF的內(nèi)容,BF=1表示液晶顯示器忙,暫時無法接收單片機送來的數(shù)據(jù)或指令;
                     當(dāng)BF=0時,液晶顯示器可以接收單片機送來的數(shù)據(jù)或指令;
            <2> 讀取地址計數(shù)器(AC)的內(nèi)容。

10.數(shù)據(jù)寫入DDRAM或CGRAM指令一覽

click here to enlarge 功能:<1> 將字符碼寫入DDRAM,以使液晶顯示屏顯示出相對應(yīng)的字符;
            <2> 將使用者自己設(shè)計的圖形存入CGRAM。

11.從CGRAM或DDRAM讀出數(shù)據(jù)的指令一覽

click here to enlarge 功能:讀取DDRAM或CGRAM中的內(nèi)容。
基本操作時序:
讀狀態(tài)           輸入:RS=L,RW=H,E=H                    
                                  輸出:DB0~DB7=狀態(tài)字
寫指令           輸入:RS=L,RW=L,E=下降沿脈沖,DB0~DB7=指令碼
                 輸出:無
讀數(shù)據(jù)           輸入:RS=H,RW=H,E=H                                
                                  輸出:DB0~DB7=數(shù)據(jù)
寫數(shù)據(jù)           輸入:RS=H,RW=L,E=下降沿脈沖,DB0~DB7=數(shù)據(jù)
                 輸出:無


        呵呵,看到這么多的控制指令希望你沒有頭暈。其實這么多的指令剛開始的時候沒有必要全部掌握,隨著學(xué)習(xí)的深入可以再嘗試去用更復(fù)雜的控制指令。下面讓我們一起驅(qū)動1602的液晶吧。下面是我的液晶的連接圖,用的是那種藍底白字的液晶,其實藍底白字和那種綠底黑字的液晶唯一的區(qū)別就是顏色的問題,至于用哪種液晶,就看各位自己的喜好咯。 
        這就是我做測試用的最小系統(tǒng),單片機是STC89C516,晶振為12M。液晶為藍底白字的那種1602。


 
        當(dāng)我們硬件連接錯誤,或者程序錯誤時就會出現(xiàn)下圖這種情況,就是上排顯示16的白色的塊(藍底黑字的液晶則顯示的是16個黑塊)。
  
 

        下面我們來驅(qū)動1602吧在1602的上排顯示“LCD1602 check ok”下排顯示“study up”程序中沒有用到忙檢測,而是用的是延時函數(shù)來替代忙檢測
#include<reg52.h>    //包含頭文件,這個嘛,就不用多說了~~
#define uint unsigned int  //預(yù)定義一下
#define uchar unsigned char
sbit rs=P3^5;    //1602的數(shù)據(jù)/指令選擇控制線
sbit rw=P3^6;        //1602的讀寫控制線
sbit en=P3^7;        //1602的使能控制線
/*P2口接1602的D0~D7,注意不要接錯了順序,我以前可在這上面吃過虧~*/
uchar code table[]="LCD1602 check ok"; //要顯示的內(nèi)容1放入數(shù)組tablel
uchar code table1[]="study up";             //要顯示的內(nèi)容2放入數(shù)組table1
void delay(uint n)       //延時函數(shù)                      
{
    uint x,y;
    for(x=n;x>0;x--)
        for(y=110;y>0;y--);
}
void lcd_wcom(uchar com)  //1602寫命令函數(shù)                
{
    rs=0;            //選擇指令寄存器
    rw=0;            //選擇寫
    P2=com;            //把命令字送入P2
    delay(5);            //延時一小會兒,讓1602準(zhǔn)備接收數(shù)據(jù)
    en=1;           //使能線電平變化,命令送入1602的8位數(shù)據(jù)口
    en=0;
}
void lcd_wdat(uchar dat)        //1602寫數(shù)據(jù)函數(shù)      
{
    rs=1;        //選擇數(shù)據(jù)寄存器
    rw=0;        //選擇寫
    P2=dat;        //把要顯示的數(shù)據(jù)送入P2
    delay(5);        //延時一小會兒,讓1602準(zhǔn)備接收數(shù)據(jù)
    en=1;        //使能線電平變化,數(shù)據(jù)送入1602的8位數(shù)據(jù)口
    en=0;
}
void lcd_init()              //1602初始化函數(shù)      
{
    lcd_wcom(0x38);       //8位數(shù)據(jù),雙列,5*7字形      
    lcd_wcom(0x0c);      //開啟顯示屏,關(guān)光標(biāo),光標(biāo)不閃爍
    lcd_wcom(0x06);    //顯示地址遞增,即寫一個數(shù)據(jù)后,顯示位置右移一位
    lcd_wcom(0x01);    //清屏
}
void main()            //主函數(shù)
{    
    uchar n,m=0;
    lcd_init();                 //液晶初始化
    lcd_wcom(0x80);   //顯示地址設(shè)為80H(即00H,)上排第一位      
    for(m=0;m<16;m++)     //將table[]中的數(shù)據(jù)依次寫入1602顯示
    {
            lcd_wdat(table[m]);          
            delay(200);
    }
    lcd_wcom(0x80+0x44); //重新設(shè)定顯示地址為0xc4,即下排第5位
    for(n=0;n<8;n++)   //將table1[]中的數(shù)據(jù)依次寫入1602顯示
    {    
            lcd_wdat(table1[n]);
           delay(200);
    }
    while(1);        //動態(tài)停機
}

        程序?qū)懞煤鬅龑戇M單片機,現(xiàn)在讓我們看看效果吧


 
        這就是顯示的效果,你做成功了嗎?

        下面讓我們來看看如何顯示一個自定義的字符吧 
        我們從CGROM表上可以看到,在表的最左邊是一列可以允許用戶自定義的CGRAM,從上往下看著是16個,實際只有8個字節(jié)可用。它的字符碼是00000000-00000111這8個地址,表的下面還有8個字節(jié),但因為這個CGRAM的字符碼規(guī)定0-2位為地址,3位無效,4-7全為零。因此CGRAM的字符碼只有最后三位能用也就是8個字節(jié)了。等效為0000X111,X為無效位,最后三位為000-111共8個。 
        如果我們要想顯示這8個用戶自定義的字符,操作方法和顯示CGROM的一樣,先設(shè)置DDRAM位置,再向DDRAM寫入字符碼,例如“A”就是41H。現(xiàn)在我們要顯示CGRAM的第一個自定義字符,就向DDRAM寫入00000000B(00H),如果要顯示第8個就寫入00000111(08H),簡單吧! 
        好!現(xiàn)在我們來看怎么向這八個自定義字符寫入字模。有個設(shè)置CGRAM地址的指令大家還記得嗎?趕快再找出來看看。

click here to enlarge 
        從這個指令可以看出指令數(shù)據(jù)的高2位已固定是01,只有后面的6位是地址數(shù)據(jù),而這6位中的高3位就表示這八個自定義字符,最后的3位就是字模數(shù)據(jù)的八個地址了。例如第一個自定義字符的字模地址為01000000-01000111八個地址。我們向這8個字節(jié)寫入字模數(shù)據(jù),讓它能顯示出“℃”
地址:01000000  數(shù)據(jù):00010000       圖示:○○○■○○○○
   01000001     00000110               ○○○○○■■○
   01000010     00001001               ○○○○■○○■
   01000011     00001000               ○○○○■○○○
   01000100     00001000               ○○○○■○○○
   01000101     00001001               ○○○○■○○■
   01000110     00000110               ○○○○○■■○
   01000111     00000000               ○○○○○○○○ 

        下面我們寫一段程序讓這8個自定義字符顯示出一個心的圖案: (由于上面那個顯示程序已經(jīng)有很詳細(xì)的注釋了,因此這個程序只對與上個程序不同的地方寫注釋)
#include<reg52.h>
#define uint unsigned int
#define uchar unsigned char
sbit rs=P3^5;
sbit rw=P3^6;
sbit en=P3^7;
uchar code table[]={0x03,0x07,0x0f,0x1f,0x1f,0x1f,0x1f,0x1f,
                    0x18,0x1E,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
                    0x07,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
                    0x10,0x18,0x1c,0x1E,0x1E,0x1E,0x1E,0x1E,
                    0x0f,0x07,0x03,0x01,0x00,0x00,0x00,0x00,
                    0x1f,0x1f,0x1f,0x1f,0x1f,0x0f,0x07,0x01,
                    0x1f,0x1f,0x1f,0x1f,0x1f,0x1c,0x18,0x00,
                    0x1c,0x18,0x10,0x00,0x00,0x00,0x00,0x00};//心圖案
/*uchar  code table1[]={0x10,0x06,0x09,0x08,0x08,0x09,0x06,0x00};//字符℃ */
void delay(uint n)                              
{
    uint x,y;
    for(x=n;x>0;x--)
            for(y=110;y>0;y--);
}
void lcd_wcom(uchar com)                  
{
    rs=0;
    rw=0;
    P2=com;
    delay(5);
    en=1;
    en=0;
}
void lcd_wdat(uchar dat)              
{
    rs=1;
    rw=0;
    P2=dat;
    delay(5);
    en=1;
    en=0;
}
void lcd_init()                    
{
         lcd_wcom(0x38);            
         lcd_wcom(0x0c);          
         lcd_wcom(0x06);            
         lcd_wcom(0x01);            
}
void main()
{    
                    char m=0;
    lcd_init();
    lcd_wcom(0x40);             //設(shè)定CGRAM地址
    for(m=0;m<64;m++)    //將心型代碼寫入CGRAM中
    {
            lcd_wdat(table[m]);          
    }
    lcd_wcom(0x85);        //設(shè)定上排的顯示位置
    for(m=0;m<4;m++)        //顯示心型圖案的上半部分
    {
            lcd_wdat(m);
    }
    lcd_wcom(0xc5);        //將顯示坐標(biāo)轉(zhuǎn)移到下排和上排相對應(yīng)的地方
    for(m=4;m<8;m++)        //顯示心型圖案的下半部分
    {
            lcd_wdat(m);
    }
    while(1);
}

讓我們一起來看看顯示的效果吧~~
在綠底黑字液晶模塊和藍底白字液晶模塊上分別顯示的效果。





下面再為大家展示幾種可能出現(xiàn)的問題 
        1:通電之后,程序也燒寫進去了,但是1602就是不顯示,只顯示一排黑塊(一般都是在上排8個小黑塊,記得剛開始用1602液晶的時候,被這個整怕了~~),怎么樣,你郁悶了吧,其實出現(xiàn)這種問題的原因無非以下幾種:硬件連線上的錯誤,這種錯誤一般用萬用表仔細(xì)檢查后很容易找出來。第二種情況就是硬件連接上是正確的,那么此時出問題最大的就是程序上了,如果你用的是忙檢測,看一下忙檢測函數(shù)寫對了沒,如果用的是延時函數(shù),那么看看延時的時間是否夠長。再就是看看時序圖,這點很重要的哦。如果硬件和軟件都沒有錯,那么就要考慮1602是否壞了,但是出現(xiàn)這種情況的幾率很小,如果遇到這種情況,你可以考慮去買彩票了~~ 
        下面這種情況你遇到過嗎?我遇到過了的,搞得我很是郁悶~~

 
        我做的實驗是要液晶顯示ABC這三個字母,并且開光標(biāo),光標(biāo)閃爍。大家可以在第一排的最后幾位看到ABC和光標(biāo)都已經(jīng)顯示出來了。但是為什么其它位會顯示這么多8呢?嘿嘿~~郁悶吧。出現(xiàn)這種情況的原因就是在初始化液晶的時候,要把清屏指令放在最后面,否則就會出現(xiàn)上圖這種情況。怎么樣,第一次聽說吧~不過,我不知道其它的液晶是否也有這個問題出現(xiàn),至少我用的這塊就有這種情況,但是我的另一個液晶則沒有這種情況出現(xiàn),不管是在一開始就清屏還是最后清屏。大家注意下就可以了,萬一出現(xiàn)了這種情況,就會處理了~~

 
        上面這張圖是用1602作為顯示的溫度電子鐘~~上面的年月日三個字就是用自定義字符的方法顯示的。呵呵,怎么樣~~到此1602的驅(qū)動基本上結(jié)束了,剩下的就靠大家自己去發(fā)揮了。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多