51單片機實現SMG12864液晶顯示器操作

来源:http://www.cnblogs.com/hughdong/archive/2017/05/23/6895631.html
-Advertisement-
Play Games

———————————————————————————————————————————— SMG12864液晶顯示器 128*64個點位,可以顯示圖形或8*4個漢字 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ...


————————————————————————————————————————————

SMG12864液晶顯示器

  • 128*64個點位,可以顯示圖形或8*4個漢字

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

引腳功能:

基本結構:

  • 行驅動器:IC3
  • 列驅動器:IC1IC2
  • 128*64全點陣液晶顯示器

內部結構:IC1IC2IC3含有的主要功能器件

  • 指令寄存器 IR:寫指令時將指令存入IR
  • 數據寄存器 DR:寫數據時將數據存入DR
  • 忙標誌 BFBF=1表示模塊在內部操作,此時不接收外部指令和數據。BF=0時為準備狀態,可以接收指令和數據
  • 顯示控制觸發器 DDF:屏幕顯示開和關的控制,DFF=1開,DFF=0
  • 顯示數據記憶體 DDRAM:存儲圖形顯示數據
  • XY地址計數器:9位計數器(高3位為X,低6位為Y)作為DDRAM指針,X只能通過指令設置,Y地址計數器具有指令迴圈功能,讀寫數據完成後Y地址自動+1
  • Z地址計數器:6位計數器,用於顯示行掃描同步,完成一行掃描後Z地址自動+1,向下一行掃描。RST複位後,Z地址歸零。顯示屏幕的起始行由此指令控制。此模塊的DDRAM64行,屏幕可以迴圈滾動顯示64行。

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

操作時序:

讀操作時序圖:

寫操作時序圖:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

操作指令:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

DDRAM與地址、顯示位置的關係 p.s.CS2對應左屏,CS1對應右屏

  • DDRAM與頁地址的對應關係

    在圖中可以看到每個CS由8頁(64行)*64列組成

  • DDRAM與地址顯示位置的對應關係

  • DDRAM與起始行對應關係

DDRAM

62

63

0

1

...

29

屏幕顯示行

1

2

3

4

...

32

————————————————————————————————————————————

SMG12864液晶顯示器使用實例

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

設計要求:一行顯示八個字,滾動顯示

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

實現思路:

  • 動態顯示:利用餘暉效應迴圈顯示八個漢字
  • 滾動顯示:每次顯示完畢後在下一次迴圈中顯示在下一行(建立新的初始行,每次迴圈將初始行+1)

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

主體模塊:

  • 初始化LCD,清屏
  • 動態顯示
    • 滾動控制
      • 開始行建立
      • 開始行+1
    • 漢字顯示
      • 第一個字
      • 第二個字
      • ...
      • 第八個字
      • 全屏顯示

子模塊:

  • 初始化
    • 清屏
  • 漢字顯示
    • 選擇左右屏(前四個字在左屏,後四個字在右屏)
    • 顯示字的上半部分
      • 建立行(頁)
      • 建立列
      • 遍歷寫入字型檔對應位置
    • 顯示字的下半部分
      • 同上半部分

LCD基本操作:

  • 讀狀態
    • rs=0;rw=1;
    • do迴圈(BUSY1忙碌時)
      • P0置空
      • 打開使能
      • 讀入P0
      • 關閉使能
      • 檢測BF標誌位狀態(引腳DB7
  • 寫指令:
    • 讀狀態
    • rs=0;rw=0;
    • 寫入指令
    • E負跳變沿
  • 寫數據
    • 讀狀態
    • rs=0;rw=1;
    • 寫入數據
    • E負跳變沿
  • 選擇屏幕
    • 全屏顯示:CS1/2=0;
    • 右屏顯示(CS1控制):CS2高電平,CS1低電平
    • 左屏顯示(CS2控制):CS1高電平,CS2低電平
  • 清屏:
    • 選擇全屏
    • 迴圈遍歷8
      • 建立該頁
      • 建立第0
      • 遍歷該頁的所有列寫入內容
  • 開始行建立:指令碼 11xxxxxx
  • 行(頁)建立:指令碼 10111xxx
  • 列建立:指令碼 01xxxxxx
  • 顯示開閉:指令碼 0011111x

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

清屏過程:

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

字顯示過程:

  • 1個字(對應字型檔1~2行)
    • 上半部分,第0頁(字型檔第1行)
      • 逐列顯示 0,1,2,3,4,5,6,7(字型檔第0,1,2,3,4,5,6,7位)
    • 下半部分,第1頁(字型檔第2行)
      • 逐列顯示 0,1,2,3,4,5,6,7(字型檔第8,9,10,11,12,13,14,15位)
  • 2個字(對應字型檔前3~4行)
    • 0頁(字型檔第3行)
      • 逐列顯示 17,18,19,20,21,22,23,24
    • 1頁(字型檔第4行)
      • 逐列顯示 25,26,27,28,29,30,31,32
  • ...
  • i個字(對應字型檔 i*2-1~i*2)
    • 0(字型檔第 i*2-1)
      • 字型檔第 (i-1)*32,(i-1)*32+1,(i-1)*32+2,(i-1)*32+3...,(i-1)*32+7
    • 1(字型檔第 i*2)
      • 字型檔第 (i-1)*32+16,(i-1)*32+17,(i-1)*32+18,(i-1)*32+19...,(i-1)*32+31

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

實現代碼:

 

  1 #include <reg52.h>
  2 #include <intrins.h>
  3 #define DATA P0
  4 typedef unsigned char uchar;
  5 sbit rs = P2 ^ 2;
  6 sbit rw = P2 ^ 1;
  7 sbit en = P2 ^ 0;
  8 sbit cs1 = P2 ^ 4;
  9 sbit cs2 = P2 ^ 3;
 10 uchar code zhCN[] =
 11 {
 12     //每個位置占據1列8行
 13     //第1個字
 14     //上半部分:第1列,第2列,第3列...第8列
 15     0x00, 0x04, 0x04, 0xC4, 0xB4, 0x8C, 0x87, 0x84, 0xF4, 0x84, 0x84, 0x84, 0x84, 0x04, 0x00, 0x00,
 16     //下半部分
 17     0x00, 0x00, 0x20, 0x18, 0x0E, 0x04, 0x20, 0x40, 0xFF, 0x00, 0x02, 0x04, 0x18, 0x30, 0x00, 0x00,
 18     //第2個字
 19     0x20, 0x20, 0x2A, 0x2A, 0xAA, 0x6A, 0x3E, 0x2B, 0xAA, 0xAA, 0xEA, 0xAA, 0x2A, 0x22, 0x20, 0x00,
 20     0x82, 0x82, 0x45, 0x45, 0x25, 0x15, 0x0D, 0xFF, 0x04, 0x0C, 0x14, 0x24, 0x65, 0xC2, 0x42, 0x00,
 21     //第3個字
 22     0x00, 0x00, 0xF8, 0x48, 0x48, 0x48, 0x48, 0xFF, 0x48, 0x48, 0x48, 0x48, 0xF8, 0x00, 0x00, 0x00,
 23     0x00, 0x00, 0x0F, 0x04, 0x04, 0x04, 0x04, 0x3F, 0x44, 0x44, 0x44, 0x44, 0x4F, 0x00, 0x70, 0x00,
 24     //第4個字
 25     0x00, 0x00, 0x02, 0x02, 0x02, 0x02, 0x02, 0xE2, 0x12, 0x0A, 0x06, 0x02, 0x00, 0x80, 0x00, 0x00,
 26     0x01, 0x01, 0x01, 0x01, 0x01, 0x41, 0x81, 0x7F, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00,
 27     //第5個字
 28     0x40, 0x20, 0xD0, 0x4C, 0x43, 0x44, 0x48, 0xD8, 0x30, 0x10, 0x00, 0xFC, 0x00, 0x00, 0xFF, 0x00,
 29     0x00, 0x00, 0x3F, 0x40, 0x40, 0x42, 0x44, 0x43, 0x78, 0x00, 0x00, 0x07, 0x20, 0x40, 0x3F, 0x00,
 30     //第6個字
 31     0x20, 0x24, 0x2C, 0x35, 0xE6, 0x34, 0x2C, 0x24, 0x00, 0xFC, 0x24, 0x24, 0xE2, 0x22, 0x22, 0x00,
 32     0x21, 0x11, 0x4D, 0x81, 0x7F, 0x05, 0x59, 0x21, 0x18, 0x07, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00,
 33     //第7個字
 34     0x00, 0x04, 0x04, 0x04, 0xFF, 0x54, 0x54, 0x54, 0x54, 0x54, 0xFF, 0x04, 0x04, 0x04, 0x00, 0x00,
 35     0x11, 0x51, 0x49, 0x4D, 0x4B, 0x49, 0x49, 0x7D, 0x49, 0x49, 0x4B, 0x45, 0x4D, 0x59, 0x09, 0x00,
 36     //第8個字
 37     0x10, 0x10, 0x10, 0xFE, 0x10, 0x50, 0x40, 0xFE, 0x20, 0x20, 0xFF, 0x10, 0x10, 0xF8, 0x10, 0x00,
 38     0x20, 0x20, 0x10, 0x1F, 0x08, 0x08, 0x00, 0x3F, 0x40, 0x40, 0x4F, 0x42, 0x44, 0x43, 0x70, 0x00
 39 };
 40 void Delay(uchar m)
 41 {
 42     uchar i;
 43     for (; m > 0; --m)
 44         for (i = 0; i < 110; ++i)
 45             ;
 46 }
 47 /* 檢查忙碌狀態 */
 48 void CheckState()
 49 {
 50     //通過讀取BF標誌位(引腳9,對應P0^7)狀態判斷模塊是否繁忙
 51     uchar dat;
 52     //讀狀態下RS=0,R/W=1,E=1
 53     rs = 0;
 54     rw = 1;
 55     do
 56     {
 57         DATA = 0x00; //RST=0正常,BUSY=0準備狀態,ON/OFF=0顯示關,
 58         en = 1;
 59         _nop_(); //打開使能後檢測模塊狀態
 60         dat = DATA; //狀態讀入dat
 61         en = 0;
 62         dat = 0x80 & dat; // 1000 0000 & dat 通過與操作隔離後7位,僅判斷最高位
 63     }
 64     while(dat != 0x00); //P0^7為0時跳出迴圈,BUSY=0準備狀態
 65 }
 66 /* 選擇要顯示的屏幕 */
 67 void SelectScreen(uchar screen)
 68 {
 69     //CS為低電平時亮
 70     switch(screen)
 71     {
 72     case 0: //全屏顯示
 73         cs1 = 0; //IC1控制右半屏
 74         _nop_();
 75         _nop_();
 76         _nop_();
 77         cs2 = 0; //IC2控制左半屏
 78         _nop_();
 79         _nop_();
 80         _nop_();
 81         break;
 82     case 1: //右屏顯示
 83         cs1 = 0;
 84         _nop_();
 85         _nop_();
 86         _nop_();
 87         cs2 = 1;
 88         _nop_();
 89         _nop_();
 90         _nop_();
 91         break;
 92     case 2: //左屏顯示
 93         cs1 = 1;
 94         _nop_();
 95         _nop_();
 96         _nop_();
 97         cs2 = 0;
 98         _nop_();
 99         _nop_();
100         _nop_();
101         break;
102     }
103 }
104 /* 寫命令操作 */
105 void SendCommandToLCD(uchar com)
106 {
107     //p.s.在CS1或CS2低電平情況下才能寫入命令
108     CheckState();
109     rs = 0;
110     rw = 0;
111     DATA = com;
112     en = 1;
113     _nop_();
114     _nop_();
115     en = 0;
116 }
117 /* 顯示開閉 */
118 void SetOnOff(uchar onoff)
119 {
120     //傳入0,關顯示,00111110|00000000 = 00111110
121     //傳入1,開顯示,00111110|00000001 = 00111111
122     onoff = 0x3E | onoff;
123     SendCommandToLCD(onoff); //寫指令onoff
124 }
125 /* 行(頁)建立 */
126 void SetLine(uchar page)
127 {
128     //10111000|00000000 = 10111000
129     //10111000|00000001 = 10111001
130     //10111000|00000010 = 10111010
131     //...
132     //10111000|00000111 = 10111111
133     //共8頁,設置頁地址
134     page = 0xb8 | page;
135     SendCommandToLCD(page);
136 }
137 /* 列建立 */
138 void SetColumn(uchar column)
139 {
140     //01xxxxxx 後六位為列地址
141     //先通過與操作屏蔽前2位,將地址範圍限制在0-63之間
142     //再通過或操作將列操作指令前兩位代入
143     column = column & 0x3F; //00000000 & 00111111 = 00000000
144     column = 0x40 | column; //01000000 | 00000000 = 01000000
145     SendCommandToLCD(column);
146 }
147 /* 寫入數據 */
148 void WriteByte(uchar dat)
149 {
150     CheckState();
151     rs = 1;
152     rw = 0;
153     DATA = dat;
154     en = 1;
155     _nop_();
156     _nop_();
157     en = 0;
158 }
159 /* 清屏 */
160 void ClearScreen(uchar screen)
161 {
162     uchar i, j;
163     SelectScreen(screen);
164     for (i = 0; i < 8; ++i) //書上源碼建立16頁,此處建立8頁正常運行
165     {
166         SetLine(i); //建立行
167         SetColumn(0); //建立列
168         for (j = 0; j < 64; ++j) //通過遍歷該行的64列寫入內容,列地址自動+1
169             WriteByte(0x00);
170     }
171 }
172 /* 設置開始行 */
173 void SetStartLine(uchar startline)
174 {
175     //設置開始行時前兩位為11
176     startline = 0xC0 | startline;
177     SendCommandToLCD(startline);
178 }
179 /* 初始化 */
180 void InitLCD()
181 {
182     CheckState(); //檢查LCD狀態,是否繁忙,每次操作前都要進行檢查
183     SelectScreen(0); //全屏顯示,將要顯示的屏幕部分置為低電平
184     SetOnOff(0); //關顯示,1為開顯示,0位關顯示
185     SelectScreen(0);
186     SetOnOff(1); //開顯示
187     SelectScreen(0);
188     ClearScreen(0); //0清全屏,1清左屏,2清右屏
189     SetStartLine(0); //從第0行開始
190 }
191 /* 顯示漢字 */
192 void Display(uchar screen, uchar page, uchar column, uchar num)
193 {
194     uchar i;
195     SelectScreen(screen); //選擇對應要亮的屏
196     /* 顯示字的上半部分 */
197     SetLine(page); //建立行(頁)
198     column = column & 0x3F; // column & 00111111 屏蔽前兩位
199     SetColumn(column); //建立列
200     //寫入字型檔第32*num~32*num+16位的數據
201     //第1個字:0~15,對應字型檔第1行
202     //第2個字:32~47,對應字型檔第3行
203     //第3個字:64~79,對應字型檔第5行
204     //...
205     for (i = 0; i < 16; ++i)
206         WriteByte(zhCN[i + 32 * num]);
207     /* 顯示字的下半部分 */
208     SetLine(page + 1);
209     SetColumn(column);
210     //寫入字型檔第32*num+16~32*num+32位的數據
211     //第1個字:16~31,對應字型檔第2行
212     //第2個字:48~63,對應字型檔第4行
213     //第3個字:80~95,對應字型檔第6行
214     //...
215     for (i = 0; i < 16; ++i)
216         WriteByte(zhCN[i + 32 * num + 16]);
217 }
218 /* 主函數 */
219 int main()
220 {
221     uchar i;
222     /* 初始化LCD,書上進行了一系列初始化操作,僅清屏的話不影響運行結果 */
223     // InitLCD();
224     ClearScreen(0); //清屏
225     /* 動態顯示 */
226     while(1) //餘暉效應
227     {
228         for (i = 0; i < 64; ++i) //如果此處改成10,則在向上移動10行後重新出現在第0行,此處使用64的倍數來實現無限迴圈(無間斷),書上源碼迴圈128次,64次也無影響
229         {
230             /* 滾動控制 */
231             SetStartLine(i); //迴圈建立開始行,每一次迴圈都上移1行
232             /* 漢字顯示 */
233             Display(2, 
              
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 存儲引擎:也叫表類型,相當於 table 的存儲機制、索引方案等配套相關功能。 不同的存儲引擎,由於處理方式不同,帶來的功能or優化不一樣。 要根據實際需求,選擇合理的引擎。 · 存儲類型: Myisam , InnoDB , BDB , Memory , Archive 。 · 預設的 table ...
  • 運維redis很久了,一直是口頭給rd說各種要求,嘗試把這些規範總結成文檔 摘選一些可能比較通用的規則如下: ...
  • 1. 是否允許為空(Null/not Null) 規定一個欄位的值是否可以是null。預設是可以為空。 此時,插入值a = 10 , b 為空,發現可以正確插入: 若試圖插入值b = 11,而a 不做處理,發現不能正確插入,提示 a 沒有預設值。 即當對某個欄位未輸入信息時,列屬性趨向於先查找有無默 ...
  • " 1、批量數據操作 " "1.1、批量生成數據" "1.2、批量插入數據" " 2、批量生成腳本 " " 3、生成數據字典 " " 4、常見系統包 " "4.1、DBMS_OUTPUT" "4.2、DBMS_RANDOM" "4.3、其它系統包及常用方法" " 5、總結 " 1、批量數據操作 1. ...
  • 記錄下mysql-connector-java與mysql版本的對應關係,已方便以後參考,這是最新版本對應, 時間:2017年5月23日 官網文檔地址: https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-versions.html (C ...
  • 1、索引相關查詢 2、觸發器相關查詢 查看當前庫中所有的觸發器: 1 SELECT * FROM Sysobjects WHERE xtype = 'TR' 查看當前庫中所有的觸發器和與之相對應的表: ...
  • mysql多實例監控實錄 系統環境: cat /etc/redhat-release CentOS Linux release 7.3.1611 (Core) 內核版本: uname -r 3.10.0-514.el7.x86_64 docker版本: docker -v Docker versio ...
  • 1. tr 按列替換 刪除輸入中的 "{" 和 "}" 將文件testfile中的小寫字母全部轉換成大寫字母 2. cut : cut [ b] [file] 列切分 cut 命令從文件的每一行剪切位元組、字元和欄位並將這些位元組、字元和欄位寫至標準輸出。 如果不指定 File 參數,cut 命令將讀取 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...