日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

LCD1602的学习与理解

發布時間:2023/12/14 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 LCD1602的学习与理解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

LCD1602的學習與理解

文章目錄

  • LCD1602的學習與理解
  • 一、LCD1602知識體系的結構
  • 二、初始化程序


# 前言

看過很多博主的文章,很多都講得不是很清楚,很可能的原因就是,這些博主在寫文章的時候,認為你有一定的基礎認知了,才來看的。其實,大部分來找資料的不是小白就是沒怎么學明白,腦袋一團漿糊才來找資料的人,結果,看了一些博主的文章,不但沒看明白,反而腦袋里又多了一段漿糊。


下面我就自己的學習,整理了一下,該怎么去學習和理解LCD1602。

一、LCD1602知識體系的結構

先看一張我畫的整個LCD1602知識體系的結構圖


從這個圖中,我就來一點一點的講解吧,把這個圖的每一部分了解清楚,這個模塊也就理解清楚了。

  • LCD1602,由兩部分組成,分別是液晶顯示屏,和HD44780芯片。液晶顯示屏有2行,每行顯示16個字符。HD44780芯片里面的東西就多了,上面圖上的右半部分都是HD44780芯片的東西。

  • 顯示數據隨機存儲器 (Display Data RAM,簡稱DDRAM)

    DDRAM就是顯示數據RAM,用來寄存待顯示的字符代碼。共80個字節,其地址和屏幕的對應關系如下表:

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

    那么,每行40個字節,顯示卻只用了前面的16個,剩下的干嘛去了呢?剩下的那些是為了方便滾屏使用,具體操作也是可以通過指令來設置的。

  • 字符生成只讀存儲器(Character Generator ROM,簡稱CGROM)

    我們知道文本文件中每一個字符都是用一個字節的代碼記錄的。一個漢字是用兩個字節的代碼記錄。在 PC 上我們只要打開文本文件就能在屏幕上看到對應的字符是因為在操作系統里和 BIOS 里都固化有字符字模。什么是字模?就代表了是在點陣屏幕上點亮和熄滅的信息數據,例如“A”。CGROM中就存儲著HD44780已經定義好的字符字模。

    上面這個就是HD44780里面的字符字模表,每個格子都有一個地址,比如“A”的地址是0100 0001,也就是41H,可以理解成41H這個地址里存放的是‘“A”的字模(也可以理解成字符編碼,因為左邊的這些字母數字基本上都是ASCII編碼)。

  • 字符生成隨機存儲器(Character Generator RAM,簡稱CGRAM)
    CGRAM用于編寫CGROM中沒有的字符,它的存儲空間大小為64字節,在上面CGROM中可以看到,最左邊有一列00H-0FH地址編碼是供CGRAM使用的區域,標著有16個房間,實際上只有8個房間的地址編號可以使用(第8-16個房間地址與0-7房間地址等效)。如果自定義的是58的字符,那么一個字符需要8個字節來定義,最多就只能定義8個自定義字符,如果是定義510的字符,一個字符需要16字節,最多只能定義4個字符。注意,自定義的字符是存儲在CGROM中,上表就有CGRAM自定義的字符的地址編碼(可以理解成CGRAM是CGROM的一部分),CGRAM的64字節空間是用于存儲自定義字符的,并不是地址編碼,地址編碼在CGROM中,這一點要搞清楚。

  • 地址計數器(Address Counter,簡稱 AC)
    存儲DDRAM的地址信息,也可以存儲CGRAM的地址信息,在顯示時,通過指令設置AC,讓光標指向相應位置。

  • 11個指令操作





    通過這11個指令可以看出,有些位是固定的,在寫初始化程序的時候,只需要去找相應的控制指令,然后設置對應的位填入就行了。

  • 二、初始化程序

    先附上硬件電路圖

    通過LCD1602的的結構圖,可以看出,指令的讀寫通過引腳E RW RS三個引腳控制,數據傳輸通過D0-D7。
    E:使能控制,讀寫指令數據必須打開這個開關
    RS:指令或數據,低電平是指令,高電平是數據
    RW:讀寫控制,高電平是讀,低電平是寫

    這兩個引腳自由組合有四種可能

  • 讀指令:RS=0,RW=1;
  • 讀數據:RS=1,RW=1;
  • 寫指令:RS=0,RW=0;
  • 寫數據:RS=1,RW=0;
  • 還有一點比較重要的就是,時序圖!!!
    無論是讀寫數據或是指令,都跟時序圖有關,要看懂這個時序圖,才能真正理解程序是怎樣讀寫數據指令的。


    下面以一個寫命令的初始化函數為例

    void Lcd_WriteCom(uchar com) //1602寫命令函數 { P0=com; //把命令字送入P2en=0; rs=0; //選擇指令寄存器rw=0; //選擇寫_nop_();//一個機械周期 en=1; //使能線電平變化,命令送入1602的8位數據口 delay(1);en=0; }

    看著時序圖的寫部分,再結合代碼,來分析一下:
    時序圖,只用看中間的部分
    E控制著整個寫的過程,只有E拉高之后,指令才會寫進去。

  • 圖中可以看到RS RW D0-D7的電平變化都在E的變化之前,所以,在寫程序的時候,可以首先把數據懟上去,然后最后一個時序D0-D7就不用管了,只需要等待E電平拉高就行了。
  • 接下來是設置RS RW E變成相應的電平,寫指令的話,RS=0,RW=0,E先變為低電平,然后從時序圖中可以看到,操作了RW,RS之后,要等待一個時間tsp1之后才能拉高使能端E的電平,從表中可以查到tsp1最小時間是30ns,這個時間很小,對于51單片機來說,不需要延時,因為51單片機的晶振差不多都是12MHz左右的,一條指令的時間在1us左右,遠大于30ns,但對于運行速度較快的單片機,必須延時!!!
  • 然后拉高E的電平,持續tpw的時間,對于51單片機來說,還是不用延時,但是為了代碼規范,我還是加了延時的(E的高電平持續時間要比表格中的時間長就ok),然后拉低E的電平,表示這條指令寫進了HD44780芯片當中了。
  • 如果作為小白的你,不太明白著幾句話,我建議你結合我給的示例代碼和時序圖,反復理解一下。

    寫數據的操作也這個是一樣的,我會在文末給出初始化的代碼。

    下面在說一下忙檢函數,主要是用于檢測1602當前是否正在進行指令操作

    void Busy(void) {uchar temp=0;do{rw=1;rs=0;en=0;_nop_();en=1;delay(1);en=0;temp=P0;}while(temp&0x80); }

    忙檢函數,實際上就是讀操作,像我剛才敘述的寫操作一樣,代碼寫的順序也是根據時序圖來的,只是和寫操作不一樣的是,數據D0-D7是在E電平拉高后產生變化的,所以在初始化程序中,就不用管數據的變化,直接設置RW RS E 就行了,最后,說明一點,當E由高電平變為低電平后,數據就已經讀取到P0口了,然后再把數據賦值給temp,檢測最高位BF(忙標志位)的狀態。
    補充一下,BF這個位是由硬件決定的,只能讀,不能通過軟件寫。

    最后是,LCD1602的初始化函數

    void lcd_init() //1602初始化函數 { delay(1);Lcd_WriteCom(0x38); //8位數據,雙列,5*7字形 Busy();Lcd_WriteCom(0x0c); //開啟顯示屏,關光標,光標不閃爍 Busy();Lcd_WriteCom(0x06); //顯示地址遞增,即寫一個數據后,顯示位置右移一位 Busy();Lcd_WriteCom(0x01); //清屏 Busy();Lcd_WriteCom(0x80); //設置數據指針起點 }

    關于里面的數據,0x38,0x0c啥的,這時候就要去看前面的11個指令設置了,對應去找,這些數據怎么來的,相信你也一下子就理解了。

    把我寫的這些都讀懂了,那么我相信你對1602的使用已經有了一個大致的了解了,如果還有什么不懂的,還是看1602的數據手冊吧,這篇文章看完,你也應該能看懂數據手冊了,細節方面,還是去數據手冊里面在找找吧。

    最后,附上一個簡單的初始化代碼
    LCD1602.h

    #ifndef __LCD1602_H__ #define __LCD1602_H__ #include<reg52.h> //包含頭文件 #include"intrins.h" #define uint unsigned int //預定義 #define uchar unsigned char void delay(uint n); void Busy(void); void Lcd_WriteCom(uchar com); void Lcd_WriteData(uchar dat); void lcd_init(); #endif

    LCD1602.c

    #include"lcd1602.h"sbit rs=P2^6; //1602的數據/指令選擇控制線 sbit rw=P2^5; //1602的讀寫控制線 sbit en=P2^7; //1602的使能控制線void delay(uint n) //延時函數 { uint x,y; for(x=n;x>0;x--) for(y=110;y>0;y--); } void Busy(void) {uchar temp=0;do{rw=1;rs=0;en=0;_nop_();en=1;delay(1);en=0;temp=P0;}while(temp&0x80); }void Lcd_WriteCom(uchar com) //1602寫命令函數 { P0=com; //把命令字送入P2en=0; rs=0; //選擇指令寄存器rw=0; //選擇寫_nop_();//一個機械周期 en=1; //使能線電平變化,命令送入1602的8位數據口 delay(1);en=0; } void Lcd_WriteData(uchar dat) //1602寫數據函數 { P0=dat; //把要顯示的數據送入P0en=0; rs=1; //選擇數據寄存器 rw=0; //選擇寫 _nop_();//一個機械周期 en=1; //使能線電平變化,數據送入1602的8位數據口 delay(1);en=0; } void lcd_init() //1602初始化函數 { delay(1);Lcd_WriteCom(0x38); //8位數據,雙列,5*7字形 Busy();Lcd_WriteCom(0x0c); //開啟顯示屏,關光標,光標不閃爍 Busy();Lcd_WriteCom(0x06); //顯示地址遞增,即寫一個數據后,顯示位置右移一位 Busy();Lcd_WriteCom(0x01); //清屏 Busy();Lcd_WriteCom(0x80); //設置數據指針起點 }

    main.c

    #include"lcd1602.h"/*P0口接1602的D0~D7*/ uchar code table[]="ni hao"; //要顯示的內容放入數組tablevoid main() //主函數 { uchar m=0; lcd_init(); //液晶初始化 Lcd_WriteCom(0x80); //顯示地址設為80H(即00H,)上排第一位 for(m=0;m<6;m++) //將table[]中的數據依次寫入1602顯示 { Lcd_WriteData(table[m]); delay(200); } while(1); //動態停機 }

    下次再寫自定義字符,和動態顯示的相關文章吧。

    總結

    以上是生活随笔為你收集整理的LCD1602的学习与理解的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。