|
寫在開始:(借此灌下水^_^ ) 之前,發(fā)了一個帖子,大意是看見殺手和水劍寫的帖子,心里也癢癢了,想寫一寫以前學(xué)習(xí)單片機過程中的一些經(jīng)歷,希望能給大家一點參考。無奈最近時間很是緊張,因此,一直都沒能著手整理。本打算星期六寫的,但是接到一個朋友的電話,說想買CPLD的開發(fā)板。于是,計劃被迫打亂,只好先陪他去電子市場買板子。回來之后,雖然頭很暈(坐車的原因),但是不能再拖了,否則留給大家一個只說不做的印象就不好了。雖然頭暈,但是下面的寫出來的東西可不暈。OK,LET’S GO !
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)用于市面上大部分的字符型液晶。
0.png (327.95 KB, 下載次數(shù): 129)
下載附件
2017-10-31 01:31 上傳
下面我們來驅(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)停機
- }
復(fù)制代碼
程序?qū)懞煤鬅龑戇M單片機,現(xiàn)在讓我們看看效果吧
0.png (172.3 KB, 下載次數(shù): 128)
下載附件
2017-10-31 01:32 上傳
這就是顯示的效果,你做成功了嗎?
下面讓我們來看看如何顯示一個自定義的字符吧
我們從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地址的指令大家還記得嗎?趕快再找出來看看。
0.png (32.64 KB, 下載次數(shù): 92)
下載附件
2017-10-31 01:32 上傳
從這個指令可以看出指令數(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);
- }
復(fù)制代碼 讓我們一起來看看顯示的效果吧~~
在綠底黑字液晶模塊和藍(lán)底白字液晶模塊上分別顯示的效果。
0.png (172.67 KB, 下載次數(shù): 126)
下載附件
2017-10-31 01:33 上傳
下面再為大家展示幾種可能出現(xiàn)的問題
1:通電之后,程序也燒寫進去了,但是1602就是不顯示,只顯示一排黑塊(一般都是在上排8個小黑塊,記得剛開始用1602液晶的時候,被這個整怕了~~),怎么樣,你郁悶了吧,其實出現(xiàn)這種問題的原因無非以下幾種:硬件連線上的錯誤,這種錯誤一般用萬用表仔細(xì)檢查后很容易找出來。第二種情況就是硬件連接上是正確的,那么此時出問題最大的就是程序上了,如果你用的是忙檢測,看一下忙檢測函數(shù)寫對了沒,如果用的是延時函數(shù),那么看看延時的時間是否夠長。再就是看看時序圖,這點很重要的哦。如果硬件和軟件都沒有錯,那么就要考慮1602是否壞了,但是出現(xiàn)這種情況的幾率很小,如果遇到這種情況,你可以考慮去買彩票了~~
下面這種情況你遇到過嗎?我遇到過了的,搞得我很是郁悶~~
0.png (173.92 KB, 下載次數(shù): 85)
下載附件
2017-10-31 01:33 上傳
我做的實驗是要液晶顯示ABC這三個字母,并且開光標(biāo),光標(biāo)閃爍。大家可以在第一排的最后幾位看到ABC和光標(biāo)都已經(jīng)顯示出來了。但是為什么其它位會顯示這么多8呢?嘿嘿~~郁悶吧。出現(xiàn)這種情況的原因就是在初始化液晶的時候,要把清屏指令放在最后面,否則就會出現(xiàn)上圖這種情況。怎么樣,第一次聽說吧~不過,我不知道其它的液晶是否也有這個問題出現(xiàn),至少我用的這塊就有這種情況,但是我的另一個液晶則沒有這種情況出現(xiàn),不管是在一開始就清屏還是最后清屏。大家注意下就可以了,萬一出現(xiàn)了這種情況,就會處理了~~
0.png (133.62 KB, 下載次數(shù): 108)
下載附件
2017-10-31 01:34 上傳
上面這張圖是用1602作為顯示的溫度電子鐘~~上面的年月日三個字就是用自定義字符的方法顯示的。呵呵,怎么樣~~到此1602的驅(qū)動基本上結(jié)束了,剩下的就靠大家自己去發(fā)揮了。
完整的Word格式文檔51黑下載地址(共68頁):
51單片機好學(xué)1602全過程C語言編程顯示很全的哦.doc
(1.64 MB, 下載次數(shù): 219)
2017-10-30 19:19 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|
|