久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 32661|回復: 18
打印 上一主題 下一主題
收起左側

LCD1602的單片機驅動超詳細的學習教程

  [復制鏈接]
跳轉到指定樓層
樓主
寫在開始:(借此灌下水^_^ ) 之前,發了一個帖子,大意是看見殺手和水劍寫的帖子,心里也癢癢了,想寫一寫以前學習單片機過程中的一些經歷,希望能給大家一點參考。無奈最近時間很是緊張,因此,一直都沒能著手整理。本打算星期六寫的,但是接到一個朋友的電話,說想買CPLD的開發板。于是,計劃被迫打亂,只好先陪他去電子市場買板子。回來之后,雖然頭很暈(坐車的原因),但是不能再拖了,否則留給大家一個只說不做的印象就不好了。雖然頭暈,但是下面的寫出來的東西可不暈。OK,LET’S GO !

       1602字符液晶在實際的產品中運用的也比較多了,前幾天留意了一下,發現宿舍門前的自動售水機就是采用的1602液晶進行顯示的。而且對于單片機的學習而言,掌握1602的用法是每一個學習者必然要經歷的過程。在此,我將使用1602過程中遇到的問題以及感受記錄下來,希望能夠給初學者帶來一點指導,少走一點彎路。
        所謂1602是指顯示的內容為16*2,即可以顯示兩行,每行16個字符。目前市面上字符液晶絕大多數是基于HD44780液晶芯片的,控制原理是完全相同的,因此基于HD44780寫的控制程序可以很方便地應用于市面上大部分的字符型液晶。

     下面我們來驅動1602吧在1602的上排顯示“LCD1602 check ok”下排顯示“study up”程序中沒有用到忙檢測,而是用的是延時函數來替代忙檢測
  1. #include<reg52.h>    //包含頭文件,這個嘛,就不用多說了~~
  2. #define uint unsigned int  //預定義一下
  3. #define uchar unsigned char
  4. sbit rs=P3^5;    //1602的數據/指令選擇控制線
  5. sbit rw=P3^6;        //1602的讀寫控制線
  6. sbit en=P3^7;        //1602的使能控制線
  7. /*P2口接1602的D0~D7,注意不要接錯了順序,我以前可在這上面吃過虧~*/
  8. uchar code table[]="LCD1602 check ok"; //要顯示的內容1放入數組tablel
  9. uchar code table1[]="study up";             //要顯示的內容2放入數組table1
  10. void delay(uint n)       //延時函數                       
  11. {
  12.     uint x,y;  
  13.     for(x=n;x>0;x--)
  14.         for(y=110;y>0;y--);
  15. }
  16. void lcd_wcom(uchar com)  //1602寫命令函數                 
  17. {
  18.     rs=0;            //選擇指令寄存器
  19.     rw=0;            //選擇寫
  20.     P2=com;            //把命令字送入P2
  21.     delay(5);            //延時一小會兒,讓1602準備接收數據
  22.     en=1;           //使能線電平變化,命令送入1602的8位數據口
  23.     en=0;
  24. }
  25. void lcd_wdat(uchar dat)        //1602寫數據函數      
  26. {
  27.     rs=1;        //選擇數據寄存器
  28.     rw=0;        //選擇寫
  29.     P2=dat;        //把要顯示的數據送入P2
  30.     delay(5);        //延時一小會兒,讓1602準備接收數據
  31.     en=1;        //使能線電平變化,數據送入1602的8位數據口
  32.     en=0;
  33. }
  34. void lcd_init()              //1602初始化函數      
  35. {
  36.     lcd_wcom(0x38);       //8位數據,雙列,5*7字形      
  37.     lcd_wcom(0x0c);      //開啟顯示屏,關光標,光標不閃爍
  38.     lcd_wcom(0x06);    //顯示地址遞增,即寫一個數據后,顯示位置右移一位
  39.     lcd_wcom(0x01);    //清屏
  40. }
  41. void main()            //主函數
  42. {     
  43.     uchar n,m=0;
  44.     lcd_init();                 //液晶初始化
  45.     lcd_wcom(0x80);   //顯示地址設為80H(即00H,)上排第一位      
  46.     for(m=0;m<16;m++)     //將table[]中的數據依次寫入1602顯示
  47.     {
  48.             lcd_wdat(table[m]);           
  49.             delay(200);
  50.     }
  51.     lcd_wcom(0x80+0x44); //重新設定顯示地址為0xc4,即下排第5位
  52.     for(n=0;n<8;n++)   //將table1[]中的數據依次寫入1602顯示
  53.     {     
  54.             lcd_wdat(table1[n]);
  55.            delay(200);
  56.     }
  57.     while(1);        //動態停機
  58. }
復制代碼

程序寫好后燒寫進單片機,現在讓我們看看效果吧

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

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

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

        下面我們寫一段程序讓這8個自定義字符顯示出一個心的圖案: (由于上面那個顯示程序已經有很詳細的注釋了,因此這個程序只對與上個程序不同的地方寫注釋)
  1. #include<reg52.h>
  2. #define uint unsigned int
  3. #define uchar unsigned char
  4. sbit rs=P3^5;
  5. sbit rw=P3^6;
  6. sbit en=P3^7;
  7. uchar code table[]={0x03,0x07,0x0f,0x1f,0x1f,0x1f,0x1f,0x1f,
  8.                     0x18,0x1E,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
  9.                     0x07,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,
  10.                     0x10,0x18,0x1c,0x1E,0x1E,0x1E,0x1E,0x1E,
  11.                     0x0f,0x07,0x03,0x01,0x00,0x00,0x00,0x00,
  12.                     0x1f,0x1f,0x1f,0x1f,0x1f,0x0f,0x07,0x01,
  13.                     0x1f,0x1f,0x1f,0x1f,0x1f,0x1c,0x18,0x00,
  14.                     0x1c,0x18,0x10,0x00,0x00,0x00,0x00,0x00};//心圖案
  15. /*uchar  code table1[]={0x10,0x06,0x09,0x08,0x08,0x09,0x06,0x00};//字符℃ */
  16. void delay(uint n)                              
  17. {
  18.     uint x,y;
  19.     for(x=n;x>0;x--)
  20.             for(y=110;y>0;y--);
  21. }
  22. void lcd_wcom(uchar com)                  
  23. {
  24.     rs=0;
  25.     rw=0;
  26.     P2=com;
  27.     delay(5);
  28.     en=1;
  29.     en=0;
  30. }
  31. void lcd_wdat(uchar dat)               
  32. {
  33.     rs=1;
  34.     rw=0;
  35.     P2=dat;
  36.     delay(5);
  37.     en=1;
  38.     en=0;
  39. }
  40. void lcd_init()                     
  41. {
  42.          lcd_wcom(0x38);            
  43.          lcd_wcom(0x0c);           
  44.          lcd_wcom(0x06);            
  45.          lcd_wcom(0x01);            
  46. }
  47. void main()
  48. {     
  49.                     char m=0;
  50.     lcd_init();
  51.     lcd_wcom(0x40);             //設定CGRAM地址
  52.     for(m=0;m<64;m++)    //將心型代碼寫入CGRAM中
  53.     {
  54.             lcd_wdat(table[m]);           
  55.     }
  56.     lcd_wcom(0x85);        //設定上排的顯示位置
  57.     for(m=0;m<4;m++)        //顯示心型圖案的上半部分
  58.     {
  59.             lcd_wdat(m);
  60.     }
  61.     lcd_wcom(0xc5);        //將顯示坐標轉移到下排和上排相對應的地方
  62.     for(m=4;m<8;m++)        //顯示心型圖案的下半部分
  63.     {
  64.             lcd_wdat(m);
  65.     }
  66.     while(1);
  67. }
復制代碼
讓我們一起來看看顯示的效果吧~~
在綠底黑字液晶模塊和藍底白字液晶模塊上分別顯示的效果。

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

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

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

完整的Word格式文檔51黑下載地址(共68頁):

51單片機好學1602全過程C語言編程顯示很全的哦.doc (1.64 MB, 下載次數: 219)


分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏14 分享淘帖 頂1 踩
回復

使用道具 舉報

沙發
ID:295302 發表于 2018-4-18 09:37 來自觸屏版 | 只看該作者
感謝lz的資料。
回復

使用道具 舉報

板凳
ID:302931 發表于 2018-4-23 12:28 | 只看該作者
程序燒錄完成之后LCD1602沒有任何顯示是怎么回事
回復

使用道具 舉報

地板
ID:314579 發表于 2018-4-23 18:11 | 只看該作者
程序燒進去之后,一直顯示的都是第一行亮著16個塊,很難受,怎么都調不出來
回復

使用道具 舉報

5#
ID:321464 發表于 2018-5-3 18:18 | 只看該作者
孫124 發表于 2018-4-23 12:28
程序燒錄完成之后LCD1602沒有任何顯示是怎么回事

同問
回復

使用道具 舉報

6#
ID:321861 發表于 2018-5-4 11:04 | 只看該作者
czj_ 發表于 2018-4-23 18:11
程序燒進去之后,一直顯示的都是第一行亮著16個塊,很難受,怎么都調不出來

端口改一下!單片機是以P0為數據口的把P2改為P0就好了!
回復

使用道具 舉報

7#
ID:342161 發表于 2018-5-31 14:26 | 只看該作者
想把adc0809模數轉換之后的數據顯示出來也是這么操作嗎
回復

使用道具 舉報

8#
ID:97554 發表于 2018-6-10 22:31 來自觸屏版 | 只看該作者
孫124 發表于 2018-4-23 12:28
程序燒錄完成之后LCD1602沒有任何顯示是怎么回事

有個V0腳,接定位器那個,電位器調一下,電壓合適了才會顯示,如果引腳接線對應程序沒有問題,除了這個調對比度的電位器,再就是屏壞了。
回復

使用道具 舉報

9#
ID:97554 發表于 2018-6-10 22:33 來自觸屏版 | 只看該作者
czj_ 發表于 2018-4-23 18:11
程序燒進去之后,一直顯示的都是第一行亮著16個塊,很難受,怎么都調不出來

重點檢查RS  EN什么的那幾個引腳的線接好沒有,或者與程序對應了沒有
回復

使用道具 舉報

10#
ID:281113 發表于 2018-10-15 14:17 | 只看該作者
學習了
回復

使用道具 舉報

11#
ID:282215 發表于 2018-12-9 21:10 | 只看該作者
謝謝樓主
回復

使用道具 舉報

12#
ID:468709 發表于 2019-1-15 18:20 | 只看該作者
好貼,謝謝樓主

回復

使用道具 舉報

13#
ID:229361 發表于 2019-1-28 11:47 | 只看該作者
學習了,謝謝樓主
回復

使用道具 舉報

14#
ID:491548 發表于 2019-3-15 16:28 | 只看該作者
#include "intrins.h"
unsigned char lcd_busy()               //查忙 這部很重要 否則有的顯示容易出現亂碼                                             
{                                                                          
    unsigned char result;                                                            
    rs = 0;
        delay(5);                                                         
    rw = 1;   
        delay(5);                                                         
    en = 1;   
        delay(5);                                                                                                                 
    result = (P0&0x80);
        delay(5);                                             
    en= 0;   
        delay(5);                                                   
    return result;             //返回值                                            
}  

void lcd_wcom(uchar com)  //1602寫命令函數                 
{
                while(lcd_busy());
    rs=0;            //選擇指令寄存器
    rw=0;            //選擇寫
    P0=com;            //把命令字送入P0
    delay(5);            //延時一小會兒,讓1602準備接收數據
    en=1;           //使能線電平變化,命令送入1602的8位數據口
                _nop_();
                _nop_();
                _nop_();
    en=0;
}

......................................................

回復

使用道具 舉報

15#
ID:491548 發表于 2019-3-15 16:29 | 只看該作者
  1. #include "intrins.h"

  2. unsigned char lcd_busy()               //查忙 這部很重要 否則有的顯示容易出現亂碼                                             

  3. {                                                                          

  4.     unsigned char result;                                                            

  5.     rs = 0;

  6.         delay(5);                                                         

  7.     rw = 1;   

  8.         delay(5);                                                         

  9.     en = 1;   

  10.         delay(5);                                                                                                                 

  11.     result = (P0&0x80);

  12.         delay(5);                                             

  13.     en= 0;   

  14.         delay(5);                                                   

  15.     return result;             //返回值                                            

  16. }  


  17. void lcd_wcom(uchar com)  //1602寫命令函數                 
  18. {
  19.                 while(lcd_busy());
  20.     rs=0;            //選擇指令寄存器
  21.     rw=0;            //選擇寫
  22.     P0=com;            //把命令字送入P0
  23.     delay(5);            //延時一小會兒,讓1602準備接收數據
  24.     en=1;           //使能線電平變化,命令送入1602的8位數據口
  25.                 _nop_();
  26.                 _nop_();
  27.                 _nop_();
  28.     en=0;
  29. }
  30. ......................................................
復制代碼


回復

使用道具 舉報

16#
ID:305511 發表于 2019-4-6 21:16 | 只看該作者
對于我等初學者真的是太好了!謝謝!
回復

使用道具 舉報

17#
ID:198286 發表于 2019-4-7 09:21 | 只看該作者
要是有IIC 就好了
回復

使用道具 舉報

18#
ID:71883 發表于 2019-7-12 16:25 | 只看該作者
謝謝樓主正在用
回復

使用道具 舉報

19#
ID:305511 發表于 2020-4-9 08:50 | 只看該作者
很實用哦,謝謝!
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 一区二区手机在线 | 欧美在线视频网站 | 91在线观看免费视频 | 日韩欧美三级 | 欧美综合一区二区三区 | 91精品中文字幕一区二区三区 | 一级免费毛片 | 精品视频久久久 | 91精品久久久久久久久 | 夜夜爽99久久国产综合精品女不卡 | 欧美九九 | 极品销魂美女一区二区 | 国产黄色一级片 | 中文字幕欧美一区 | 日本中文字幕在线视频 | 中文字幕不卡 | 日日夜夜天天 | 久久综合一区二区 | 国产视频中文字幕 | 久久久国产精品视频 | av天空| 亚洲精品一区二区三区蜜桃久 | 成人精品一区二区三区中文字幕 | 精品自拍视频 | 欧美日韩理论 | 欧美一级免费看 | 成人av网站在线观看 | 日韩视频免费看 | 日韩欧美一区二区三区免费看 | 91精品国产综合久久婷婷香蕉 | 日本精品一区二区三区视频 | 亚洲一二三区在线观看 | 91色站 | 国产伦一区二区三区四区 | 日韩欧美国产精品 | 一本色道久久综合亚洲精品高清 | 日韩亚洲一区二区 | 亚洲天天干 | 欧美久久久久 | 在线午夜 | 91国内精品久久 |