當前進展:
一、我的構想:如何為編程愛好者設計一款好玩的智能硬件(一)——即插即用、積木化、功能重組的智能硬件模塊構想
二、別人家的孩子:如何為編程愛好者設計一款好玩的智能硬件(二)——別人是如何設計硬件積木的!
三、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 持續更新中~