LCD1602的学习与理解
LCD1602的學(xué)習(xí)與理解
文章目錄
- LCD1602的學(xué)習(xí)與理解
- 一、LCD1602知識體系的結(jié)構(gòu)
- 二、初始化程序
# 前言
看過很多博主的文章,很多都講得不是很清楚,很可能的原因就是,這些博主在寫文章的時(shí)候,認(rèn)為你有一定的基礎(chǔ)認(rèn)知了,才來看的。其實(shí),大部分來找資料的不是小白就是沒怎么學(xué)明白,腦袋一團(tuán)漿糊才來找資料的人,結(jié)果,看了一些博主的文章,不但沒看明白,反而腦袋里又多了一段漿糊。
下面我就自己的學(xué)習(xí),整理了一下,該怎么去學(xué)習(xí)和理解LCD1602。
一、LCD1602知識體系的結(jié)構(gòu)
先看一張我畫的整個(gè)LCD1602知識體系的結(jié)構(gòu)圖
從這個(gè)圖中,我就來一點(diǎn)一點(diǎn)的講解吧,把這個(gè)圖的每一部分了解清楚,這個(gè)模塊也就理解清楚了。
LCD1602,由兩部分組成,分別是液晶顯示屏,和HD44780芯片。液晶顯示屏有2行,每行顯示16個(gè)字符。HD44780芯片里面的東西就多了,上面圖上的右半部分都是HD44780芯片的東西。
顯示數(shù)據(jù)隨機(jī)存儲器 (Display Data RAM,簡稱DDRAM)
DDRAM就是顯示數(shù)據(jù)RAM,用來寄存待顯示的字符代碼。共80個(gè)字節(jié),其地址和屏幕的對應(yīng)關(guān)系如下表:
也就是說想要在LCD1602屏幕的第一行第一列顯示一個(gè)"A"字,就要向DDRAM的00H地址寫入“A”字的代碼就行了。但具體的寫入是要按LCD模塊的指令格式來進(jìn)行的,后面我會說到的。那么一行可有40個(gè)地址呀?是的,在1602中我們就用前16個(gè)就行了。第二行也一樣用前16個(gè)地址。對應(yīng)如下:
DDRAM 地址與顯示位置的對應(yīng)關(guān)系
那么,每行40個(gè)字節(jié),顯示卻只用了前面的16個(gè),剩下的干嘛去了呢?剩下的那些是為了方便滾屏使用,具體操作也是可以通過指令來設(shè)置的。
字符生成只讀存儲器(Character Generator ROM,簡稱CGROM)
我們知道文本文件中每一個(gè)字符都是用一個(gè)字節(jié)的代碼記錄的。一個(gè)漢字是用兩個(gè)字節(jié)的代碼記錄。在 PC 上我們只要打開文本文件就能在屏幕上看到對應(yīng)的字符是因?yàn)樵诓僮飨到y(tǒng)里和 BIOS 里都固化有字符字模。什么是字模?就代表了是在點(diǎn)陣屏幕上點(diǎn)亮和熄滅的信息數(shù)據(jù),例如“A”。CGROM中就存儲著HD44780已經(jīng)定義好的字符字模。
上面這個(gè)就是HD44780里面的字符字模表,每個(gè)格子都有一個(gè)地址,比如“A”的地址是0100 0001,也就是41H,可以理解成41H這個(gè)地址里存放的是‘“A”的字模(也可以理解成字符編碼,因?yàn)樽筮叺倪@些字母數(shù)字基本上都是ASCII編碼)。
字符生成隨機(jī)存儲器(Character Generator RAM,簡稱CGRAM)
CGRAM用于編寫CGROM中沒有的字符,它的存儲空間大小為64字節(jié),在上面CGROM中可以看到,最左邊有一列00H-0FH地址編碼是供CGRAM使用的區(qū)域,標(biāo)著有16個(gè)房間,實(shí)際上只有8個(gè)房間的地址編號可以使用(第8-16個(gè)房間地址與0-7房間地址等效)。如果自定義的是58的字符,那么一個(gè)字符需要8個(gè)字節(jié)來定義,最多就只能定義8個(gè)自定義字符,如果是定義510的字符,一個(gè)字符需要16字節(jié),最多只能定義4個(gè)字符。注意,自定義的字符是存儲在CGROM中,上表就有CGRAM自定義的字符的地址編碼(可以理解成CGRAM是CGROM的一部分),CGRAM的64字節(jié)空間是用于存儲自定義字符的,并不是地址編碼,地址編碼在CGROM中,這一點(diǎn)要搞清楚。
地址計(jì)數(shù)器(Address Counter,簡稱 AC)
存儲DDRAM的地址信息,也可以存儲CGRAM的地址信息,在顯示時(shí),通過指令設(shè)置AC,讓光標(biāo)指向相應(yīng)位置。
11個(gè)指令操作
通過這11個(gè)指令可以看出,有些位是固定的,在寫初始化程序的時(shí)候,只需要去找相應(yīng)的控制指令,然后設(shè)置對應(yīng)的位填入就行了。
二、初始化程序
先附上硬件電路圖
通過LCD1602的的結(jié)構(gòu)圖,可以看出,指令的讀寫通過引腳E RW RS三個(gè)引腳控制,數(shù)據(jù)傳輸通過D0-D7。
E:使能控制,讀寫指令數(shù)據(jù)必須打開這個(gè)開關(guān)
RS:指令或數(shù)據(jù),低電平是指令,高電平是數(shù)據(jù)
RW:讀寫控制,高電平是讀,低電平是寫
這兩個(gè)引腳自由組合有四種可能
還有一點(diǎn)比較重要的就是,時(shí)序圖!!!
無論是讀寫數(shù)據(jù)或是指令,都跟時(shí)序圖有關(guān),要看懂這個(gè)時(shí)序圖,才能真正理解程序是怎樣讀寫數(shù)據(jù)指令的。
下面以一個(gè)寫命令的初始化函數(shù)為例
看著時(shí)序圖的寫部分,再結(jié)合代碼,來分析一下:
時(shí)序圖,只用看中間的部分
E控制著整個(gè)寫的過程,只有E拉高之后,指令才會寫進(jìn)去。
如果作為小白的你,不太明白著幾句話,我建議你結(jié)合我給的示例代碼和時(shí)序圖,反復(fù)理解一下。
寫數(shù)據(jù)的操作也這個(gè)是一樣的,我會在文末給出初始化的代碼。
下面在說一下忙檢函數(shù),主要是用于檢測1602當(dāng)前是否正在進(jìn)行指令操作
忙檢函數(shù),實(shí)際上就是讀操作,像我剛才敘述的寫操作一樣,代碼寫的順序也是根據(jù)時(shí)序圖來的,只是和寫操作不一樣的是,數(shù)據(jù)D0-D7是在E電平拉高后產(chǎn)生變化的,所以在初始化程序中,就不用管數(shù)據(jù)的變化,直接設(shè)置RW RS E 就行了,最后,說明一點(diǎn),當(dāng)E由高電平變?yōu)榈碗娖胶?#xff0c;數(shù)據(jù)就已經(jīng)讀取到P0口了,然后再把數(shù)據(jù)賦值給temp,檢測最高位BF(忙標(biāo)志位)的狀態(tài)。
補(bǔ)充一下,BF這個(gè)位是由硬件決定的,只能讀,不能通過軟件寫。
最后是,LCD1602的初始化函數(shù)
void lcd_init() //1602初始化函數(shù) { delay(1);Lcd_WriteCom(0x38); //8位數(shù)據(jù),雙列,5*7字形 Busy();Lcd_WriteCom(0x0c); //開啟顯示屏,關(guān)光標(biāo),光標(biāo)不閃爍 Busy();Lcd_WriteCom(0x06); //顯示地址遞增,即寫一個(gè)數(shù)據(jù)后,顯示位置右移一位 Busy();Lcd_WriteCom(0x01); //清屏 Busy();Lcd_WriteCom(0x80); //設(shè)置數(shù)據(jù)指針起點(diǎn) }關(guān)于里面的數(shù)據(jù),0x38,0x0c啥的,這時(shí)候就要去看前面的11個(gè)指令設(shè)置了,對應(yīng)去找,這些數(shù)據(jù)怎么來的,相信你也一下子就理解了。
把我寫的這些都讀懂了,那么我相信你對1602的使用已經(jīng)有了一個(gè)大致的了解了,如果還有什么不懂的,還是看1602的數(shù)據(jù)手冊吧,這篇文章看完,你也應(yīng)該能看懂?dāng)?shù)據(jù)手冊了,細(xì)節(jié)方面,還是去數(shù)據(jù)手冊里面在找找吧。
最后,附上一個(gè)簡單的初始化代碼
LCD1602.h
LCD1602.c
#include"lcd1602.h"sbit rs=P2^6; //1602的數(shù)據(jù)/指令選擇控制線 sbit rw=P2^5; //1602的讀寫控制線 sbit en=P2^7; //1602的使能控制線void delay(uint n) //延時(shí)函數(shù) { 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寫命令函數(shù) { P0=com; //把命令字送入P2en=0; rs=0; //選擇指令寄存器rw=0; //選擇寫_nop_();//一個(gè)機(jī)械周期 en=1; //使能線電平變化,命令送入1602的8位數(shù)據(jù)口 delay(1);en=0; } void Lcd_WriteData(uchar dat) //1602寫數(shù)據(jù)函數(shù) { P0=dat; //把要顯示的數(shù)據(jù)送入P0en=0; rs=1; //選擇數(shù)據(jù)寄存器 rw=0; //選擇寫 _nop_();//一個(gè)機(jī)械周期 en=1; //使能線電平變化,數(shù)據(jù)送入1602的8位數(shù)據(jù)口 delay(1);en=0; } void lcd_init() //1602初始化函數(shù) { delay(1);Lcd_WriteCom(0x38); //8位數(shù)據(jù),雙列,5*7字形 Busy();Lcd_WriteCom(0x0c); //開啟顯示屏,關(guān)光標(biāo),光標(biāo)不閃爍 Busy();Lcd_WriteCom(0x06); //顯示地址遞增,即寫一個(gè)數(shù)據(jù)后,顯示位置右移一位 Busy();Lcd_WriteCom(0x01); //清屏 Busy();Lcd_WriteCom(0x80); //設(shè)置數(shù)據(jù)指針起點(diǎn) }main.c
#include"lcd1602.h"/*P0口接1602的D0~D7*/ uchar code table[]="ni hao"; //要顯示的內(nèi)容放入數(shù)組tablevoid main() //主函數(shù) { uchar m=0; lcd_init(); //液晶初始化 Lcd_WriteCom(0x80); //顯示地址設(shè)為80H(即00H,)上排第一位 for(m=0;m<6;m++) //將table[]中的數(shù)據(jù)依次寫入1602顯示 { Lcd_WriteData(table[m]); delay(200); } while(1); //動態(tài)停機(jī) }下次再寫自定義字符,和動態(tài)顯示的相關(guān)文章吧。
總結(jié)
以上是生活随笔為你收集整理的LCD1602的学习与理解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Ubuntu上下载百度网盘资料
- 下一篇: linux电路图软件有哪些,新手福利,推