如何為編程愛好者設計一款好玩的智能硬件(七)——LCD1602點陣字符型液晶顯示模塊驅動封裝(上)


 

當前進展:

一、我的構想:如何為編程愛好者設計一款好玩的智能硬件(一)——即插即用、積木化、功能重組的智能硬件模塊構想

二、別人家的孩子:如何為編程愛好者設計一款好玩的智能硬件(二)——別人是如何設計硬件積木的!

三、MCU選型:如何為編程愛好者設計一款好玩的智能硬件(三)——該選什么樣的MCU呢?

四、溫濕度傳感器DHT11驅動封裝(上):如何為編程愛好者設計一款好玩的智能硬件(四)——初嘗試·把溫濕度給收集了(上)!

五、溫濕度傳感器DHT11驅動封裝(中):如何為編程愛好者設計一款好玩的智能硬件(五)——初嘗試·把溫濕度給收集了(中)!

六、溫濕度傳感器DHT11驅動封裝(下):如何為編程愛好者設計一款好玩的智能硬件(六)——初嘗試·把溫濕度給收集了(下)!

 

七、點陣字符型液晶顯示模塊LCD1602驅動封裝(上)

  

  前幾節我們封裝好了一個可以采集數據的傳感器驅動,接下來兩節將介紹一個非常簡單的LCD液晶屏,即顯示模塊的驅動封裝。——有采集有顯示,才好!考慮剛開始,所以本節介紹一種最常用的液晶屏:LCD1602

 

 

· 模塊簡介

  該模塊總共有16個引腳,顯示字符為16X2行。1602液晶模塊內部的字符發生存儲器(CGROM)已經存儲了160個不同的點陣字符圖形,這些字符有:阿拉伯數字、英文字母的大小寫、常用符號和日文假名等,每一個字符都有一個固定的代碼,比如大寫的英文字母'A'的代碼是41H,顯示時模塊把地址41H中的點陣字符圖形顯示出來,我們就能看到字母'A'了。因為1602識別的是ASCII碼,可以直接用ASCII碼直接賦值。

 

引腳及功能

  456為控制線,DB0~7為8位數據線,3為為調節對比度的(過小會導致文本不清晰,過大會導致背景掩蓋文本)

       

 

驅動器接口說明(HD44780)

  無論是TFT\LCD\OLCD等都會有一個驅動器,簡單理解就是屏幕和控制CPU直接的一個橋梁,該橋梁規定發送什么格式的命令能達到某種效果~此外,一般這種驅動對於類似的顯示器時相似的!這里用的是HD44780驅動芯片。

1、基本操作時序:

1.1 讀狀態:輸入:RS=L,RW=H,E=H            輸出:D0~D7=狀態字
1.2 寫狀態:輸入:RS=L,RW=L,D0~D7=指令碼,E=高脈沖  輸出:無
1.3 讀數據:輸入:RS=H,RW=H,E=H            輸出:D0~D7=數據
1.4 寫數據:輸入:RS=H,RW=L,D0~D7=數據,E=高脈沖   輸出:無

2、狀態字說明:

   注:對控制器每次進行讀寫操作之前,都必須進行讀寫檢測,確保STA7為0

3、RAM地址映射圖

  控制器內部帶80X8位(80字節)的RAM緩沖區,對應下圖關系為:(因為這個是16X2行的,所以只用了其中一部分)

 4、指令說明

  顯示模式設置:    00111000  設置16X2顯示,5X7點陣,8位數據接口

  顯示開關光標設置:  00001DCB  D=1 開顯示;D=0 關顯示

                     C=1 顯示光標;C=0 不顯示光標

                     B=1 光標閃爍;B=0 光標不閃

             000001NS  N=1 當讀或者寫一個字符后地址指針加一,且光標加一

                     N=0 當讀或者寫一個字符后地址指針減一,且光標減一

                     S=1 當寫一個字符,整屏顯示左移(N=1)或右移(N=0),以得到光標不移動而整個屏幕移動的效果

                     S=0 當寫一個字符,整個屏幕不移動

  數據控制:      控制器內部設有一個數據地址指針,用戶可通過它們來訪問內部全部80字節RAM

  數據指針設置:    80H+地址碼(0-27H,40H-67H) 

  其他設置:      01H      顯示清屏

             02H      顯示回車

  初始化過程(復位過程):      ① 延時15ms

                    ② 寫指令38H(不檢測忙信號)

                    ③ 延時5ms

                    ④ 寫指令38H(不檢測忙信號)                  

                        ⑤ 延時5ms

                          ⑥ 寫指令38H(不檢測忙信號)

                        ⑦ (以后每次寫指令、讀/寫數據操作之前均需要忙檢測信號)

                        ⑧ 寫指令38H:顯示模式設置

                        ⑨ 寫指令08H:顯示關閉

                        © 寫指令01H:顯示清屏

                        ® 寫指令06H:顯示光標移動設置

                        〇 寫指令0CH:顯示開及光標設置

 

 

常用鏈接方式

 

 

時序圖

讀操作時序圖

  

寫操作時序圖

 

時序參數表

 

 

· 基於51平台的DEMO

下面是基於51平台LCD1602顯示靜態文本的例子,其連線按照“引腳與功能”左圖的方式進行連接,效果如下:

注:看下面代碼,注意重點看我加粗的地方~不同顏色表示不同功能塊的部分~

  1 /**********************BST-V51實驗開發板例程************************
  2 *  平台:BST-V51 + Keil U3 + STC89C52
  3 *  名稱:1602基本驅動的代碼
  4 *  公司:深圳市亞博軟件開發有限公司
  5 *  淘寶:bstmcu.taobao.com
  6 *  日期:2012-8-12
  7 *  晶振:11.0592MHZ
  8 *  說明:免費開源,不提供源代碼分析.
  9 ******************************************************************/
 10 
 11 //實驗目的:
 12 /*-----------------------------------------------
 13   名稱:LCD1602
 14   內容:通過標准程序靜態顯示字符
 15   引腳定義如下:1-VSS 2-VDD 3-V0 4-RS 5-R/W 6-E 7-14 DB0-DB7 15-BLA 16-BLK
 16 ------------------------------------------------*/
 17 
 18 
 19 #include<reg52.h> //包含頭文件,一般情況不需要改動,頭文件包含特殊功能寄存器的定義
 20 #include<intrins.h>
 21 
 22 sbit RS = P1 ^ 0; //定義端口
 23 sbit RW = P1 ^ 1;
 24 sbit EN = P2 ^ 5;
 25 
 26 
 27 #define RS_CLR RS=0
 28 #define RS_SET RS=1
 29 
 30 #define RW_CLR RW=0
 31 #define RW_SET RW=1
 32 
 33 #define EN_CLR EN=0
 34 #define EN_SET EN=1
 35 
 36 #define DataPort P0
 37 
 38 /*------------------------------------------------
 39  uS延時函數,含有輸入參數 unsigned char t,無返回值
 40  unsigned char 是定義無符號字符變量,其值的范圍是
 41  0~255 這里使用晶振12M,精確延時請使用匯編,大致延時
 42  長度如下 T=tx2+5 uS
 43 ------------------------------------------------*/
 44 void DelayUs2x(unsigned char t)
 45 {
 46     while(--t);
 47 }
 48 /*------------------------------------------------
 49  mS延時函數,含有輸入參數 unsigned char t,無返回值
 50  unsigned char 是定義無符號字符變量,其值的范圍是
 51  0~255 這里使用晶振12M,精確延時請使用匯編
 52 ------------------------------------------------*/
 53 void DelayMs(unsigned char t)
 54 {
 55 
 56     while(t--)
 57     {
 58         //大致延時1mS
 59         DelayUs2x(245);
 60         DelayUs2x(245);
 61     }
 62 }
 63 /*------------------------------------------------
 64               判忙函數
 65 ------------------------------------------------*/
 66 bit LCD_Check_Busy(void)//藍色的幾個忙檢測、寫數據和寫命令是根據上面《驅動器接口說明》中的第一條和讀寫時序圖寫成的  67 {
 68     DataPort = 0xFF;
 69     RS_CLR;
 70     RW_SET;
 71     EN_CLR;
 72     _nop_();
 73     EN_SET;
 74     return (bit)(DataPort & 0x80);
 75 }
 76 /*------------------------------------------------
 77               寫入命令函數
 78 ------------------------------------------------*/
 79 void LCD_Write_Com(unsigned char com)  80 {
 81     while(LCD_Check_Busy()); //忙則等待
 82     RS_CLR;
 83     RW_CLR;
 84     EN_SET;
 85     DataPort = com;
 86     _nop_();
 87     EN_CLR;
 88 }
 89 /*------------------------------------------------
 90               寫入數據函數
 91 ------------------------------------------------*/
 92 void LCD_Write_Data(unsigned char Data)  93 {
 94     while(LCD_Check_Busy()); //忙則等待
 95     RS_SET;
 96     RW_CLR;
 97     EN_SET;
 98     DataPort = Data;
 99     _nop_();
100     EN_CLR;
101 }
102 
103 /*------------------------------------------------
104                 清屏函數
105 ------------------------------------------------*/
106 void LCD_Clear(void)
107 {
108     LCD_Write_Com(0x01);
109     DelayMs(5);
110 }
111 /*------------------------------------------------
112               寫入字符串函數
113 ------------------------------------------------*/
114 void LCD_Write_String(unsigned char x, unsigned char y, unsigned char *s)
115 {
116     if (y == 0)
117     {
118         LCD_Write_Com(0x80 + x);     //表示第一行
119     }
120     else
121     {
122         LCD_Write_Com(0xC0 + x);      //表示第二行
123     }
124     while (*s)
125     {
126         LCD_Write_Data( *s);
127         s ++;
128     }
129 }
130 /*------------------------------------------------
131               寫入字符函數
132 ------------------------------------------------*/
133 void LCD_Write_Char(unsigned char x, unsigned char y, unsigned char Data)
134 {
135 if (y == 0)//根據Y的值確定顯示在哪一行,不同行RAM地址不一樣 136     {
137         LCD_Write_Com(0x80 + x);
138     }
139     else
140     {
141         LCD_Write_Com(0xC0 + x);
142     }
143     LCD_Write_Data( Data);
144 }
145 /*------------------------------------------------和《4、指令說明》的啟動階段描述一樣 146 初始化函數 147 ------------------------------------------------*/ 148 void LCD_Init(void) 149 { 150 LCD_Write_Com(0x38); /*顯示模式設置*/ 151 DelayMs(5); 152 LCD_Write_Com(0x38); 153 DelayMs(5); 154 LCD_Write_Com(0x38); 155 DelayMs(5); 156 LCD_Write_Com(0x38); 157 LCD_Write_Com(0x08); /*顯示關閉*/ 158 LCD_Write_Com(0x01); /*顯示清屏*/ 159 LCD_Write_Com(0x06); /*顯示光標移動設置*/ 160 DelayMs(5); 161 LCD_Write_Com(0x0C); /*顯示開及光標設置*/ 162 } 163 
164 /*------------------------------------------------
165                     主函數
166 ------------------------------------------------*/
167 void main(void)
168 {
169     LCD_Init();
170     LCD_Clear();//清屏
171     while (1)
172     {
173         LCD_Write_Char(7, 0, 'o');
174         LCD_Write_Char(8, 0, 'k');
175         LCD_Write_String(1, 1, "Hard Work");
176         while(1);
177     }
178 }

 

小結&接下來計划:

  下一節將把LCD1602的驅動改寫成便於移植的版本,同時討論一些稍微炫一點的效果——滾動、光標等待等。兩周內計划是:再研究一個按鍵的驅動、一個通信的驅動之后就着手寫我們的“X-積木”OS了。

 

 

 

@beautifulzzzz

  2015-9-20 持續更新中~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM