LCD12864 液晶顯示-漢字及自定義顯示(並口)


  LCD12864帶字庫,型號:CM12864-12.其相關數據手冊可以在百度中搜索“ST7920 系列中文圖形液晶模塊使用說明書”,里面有詳細的介紹。這里就不在多描述。

其原理簡圖:(我們只需關心接口部分)

接口定義:這里注意V0,我一開始就栽倒這,網上搜到的資料中,這PIN可以懸空或接個滑動電阻,程序檢查好多遍,沒有發現問題,就是不顯示,接到3.3V上也不行,后來把V0直接接到5V上,就可以正常顯示。在這提醒大家數據手冊僅供參考,具體還是以自己的實物為主。避免走沒必要的彎路。

管腳號

管腳名稱

電平

管腳功能描述

1

VSS

0V

電源地

2

VCC

5V

電源正

3

V0

-

對比度(亮度)調整.(直接接到5V上最靠譜)

4

RS(CS)

H/L

RS=“H”,表示DB7——DB0為顯示數據

RS=“L”,表示DB7——DB0為顯示指令數據

5

R/W(SID)

H/L

R/W=“H”,E=“H”,數據被讀到DB7——DB0

R/W=“L”,E=“H→L”, DB7——DB0的數據被寫到IR或DR

6

E(SCLK)

H/L

使能信號

7

DB0

H/L

三態數據線

8

DB1

H/L

三態數據線

9

DB2

H/L

三態數據線

10

DB3

H/L

三態數據線

11

DB4

H/L

三態數據線

12

DB5

H/L

三態數據線

13

DB6

H/L

三態數據線

14

DB7

H/L

三態數據線

15

PSB

H/L

H:8位或4位並口方式,L:串口方式

16

NC

-

空腳

17

/RESET

H/L

復位端,低電平有效(懸空或接到5V都可以)

18

VOUT

-

LCD驅動電壓輸出端(懸空)

19

A

VDD

背光源正端(+5V)

20

K

VSS

背光源負端(0V)

ST7920數據手冊中,提到每次在寫命令之前都要判斷LCD是否處於空閑狀態,是為0,否則為1,本次試驗全過程只寫不讀,為了避開LCD忙的狀態,可以采取隔斷時間寫一次命令或數據。在指令表中,可以看到每個命令執行的時間,這里注意,除清除顯示和地址歸位,網上有不同的說法,有的說是1.6ms,有的4.6ms外,其他命令執行時間都是72us,不管怎么樣,我們還是取最大值更為靠譜,4.6ms取個整數,好聽點的6ms吧。當然可以取比這個更大(LCD在顯示數據時,是一個接一個的顯示出來,就可以察覺到,取的越大,顯示速度就越慢),看自己的決定了。利用FPGA分頻,產生一個周期6ms的時鍾,給LCD的E管腳,進行控制寫數據或命令。在8為並口寫操作時序圖中,DB0~DB7是在E為高時,寫入數據。

知道了何時給LCD寫數據或命令,還得知道如何把自己想要顯示的東西顯示在LCD屏幕上,這點也不難:

第一得知道中文字行的編碼,可以查國標GB2312,來調用CGROM字庫,比如"文:CEC4、少:C9D9、清:C7E5“。或可以下載“漢字十六進制轉換工具”軟件直接生成。

第二得知道顯示文字的地址該如何設置,就是一個文字我可以擺在第一行的開頭或結尾或其他行。如下圖示。

第三若自帶的庫中沒有你想要的東西時,可以自己定義,比如代碼中的星星月亮組合圖標,庫中沒有,那么我們可以自己定義(組合圖標的編碼可以用字模軟件進行提取)。自定義字符具體操作,先設定CGRAM存儲地址,其次把該組合圖標的編碼數據放置到該地址中,在設置該圖標在LCD屏幕顯示的位置,最后連續寫兩次數據(注意寫的是數據不是命令,我也被這東東栽倒一次),先寫高8it,后寫低8bit,就可以了。此時知道寫這數據到底是啥數據。那么就得理解0x0000,0x0002,0x0004,0x0006這四種編碼.至於這四種編碼有什么區別,我也不是很明白,在程序中,0x0000和0x0006沒發現有區別,顯示正常;0x0002,在星星的左上角有個小點;0x0004顯示亂碼。

第四半寬字型,數據手冊中寫的是”半寬字型ROM(HCGROM),總共提供126 個西文字型(16×8 點陣)“,應該就是英文字符。程序中的"LCD12864"。

在寫代碼之前理清思路,程序的流程該如何跑,寫起代碼來也比較順手。如下圖。前面設置好頻率后,每步中的延時就不用在考慮了。

代碼:(使用並口,只有寫)

LCD12864.v

  1 module LCD12864(
  2                     //input 
  3                     sys_clk,
  4                     rst_n,
  5                     
  6                     //output 
  7                     lcd_rs,
  8                     lcd_rw,
  9                     lcd_en,
 10                     lcd_data,
 11                     lcd_psb
 12                 );
 13 input sys_clk;// 50MHZ
 14 input rst_n;
 15 
 16 output lcd_rs;//H:data    L:command
 17 output lcd_rw;//H:read module    L:write module
 18 output lcd_en;//H active
 19 output [7:0] lcd_data;
 20 output lcd_psb;//H:parallel    module    L:SPI module
 21 
 22 /***************************************************/
 23 parameter T3MS = 18'd149_999;
 24 parameter    IDLE           = 4'd0,
 25             INIT_FUN_SET1 = 4'd1,
 26             INIT_FUN_SET2 = 4'd2,
 27             INIT_DISPLAY  = 4'd3,
 28             INIT_CLEAR       = 4'd4,
 29             INIT_DOT_SET  = 4'd5,
 30             SET_DDRAM      = 4'd6,
 31             WRITE_DATA1      = 4'd7,
 32             INIT_FUN_SET3 = 4'd8,
 33             SET_CGRAM     = 4'd9,
 34             WRITE_DATA2   = 4'd10,
 35             SET_DDRAM2    = 4'd11,
 36             SET_CUSTOM_L  = 4'd12,
 37             SET_CUSTOM_H  = 4'd13,
 38             STOP          = 4'd14;
 39 /***************************************************/
 40 //產生周期為6MS的lcd_clk給LCD
 41 reg [17:0] cnt;
 42 reg lcd_clk;
 43 always @(posedge sys_clk or negedge rst_n)
 44 if(!rst_n) begin
 45     cnt <= 18'd0;
 46     lcd_clk <= 1'b0;
 47 end
 48 else if(cnt == T3MS)begin
 49     cnt <= 18'd0;
 50     lcd_clk <= ~lcd_clk;
 51 end
 52 else
 53     cnt <= cnt + 1'b1;
 54 /***************************************************/
 55 reg lcd_rs;
 56 always @(posedge lcd_clk or negedge rst_n)
 57 if(!rst_n)
 58     lcd_rs <= 1'b0;
 59 else if((state == WRITE_DATA1) || (state == WRITE_DATA2)|| (state == SET_CUSTOM_H) || (state == SET_CUSTOM_L))
 60     lcd_rs <= 1'b1;        //寫數據模式
 61 else
 62     lcd_rs <= 1'b0;        //寫命令模式
 63 /***************************************************/
 64 reg [3:0] state;
 65 reg [7:0] lcd_data;
 66 reg [6:0] num;
 67 reg en;
 68 always @(posedge lcd_clk or negedge rst_n)
 69 if(!rst_n) begin
 70     state <= IDLE;
 71     lcd_data <= 8'hzz;
 72     en <= 1'b1;
 73     num <= 6'd0;
 74 end    
 75 else
 76     case(state)
 77         IDLE: 
 78         begin
 79             state <= INIT_FUN_SET1;
 80             lcd_data <= 8'hzz;
 81             en <= 1'b1;
 82         end
 83         
 84         INIT_FUN_SET1: 
 85         begin
 86             lcd_data <= 8'h30;    //功能設定
 87             state <= INIT_FUN_SET2;
 88         end 
 89         
 90         INIT_FUN_SET2:
 91         begin
 92             lcd_data <= 8'h30;    //功能設定
 93             state <= INIT_DISPLAY;
 94         end
 95             
 96         INIT_DISPLAY:
 97         begin
 98             lcd_data <= 8'h0c;    //顯示設定
 99             state <= INIT_CLEAR;
100         end
101             
102         INIT_CLEAR:
103         begin
104             lcd_data <= 8'h01;    //清屏
105             state <= INIT_DOT_SET;
106         end
107         
108         INIT_DOT_SET:
109         begin
110             lcd_data <= 8'h06;    //進入點設定
111             state <= SET_DDRAM;
112         end
113         
114         SET_DDRAM:
115         begin
116             if(num == 7'd0)
117                 lcd_data <= 8'h81;//1 line
118             else if(num == 7'd12)
119                 lcd_data <= 8'h92;//2 line
120             else if(num == 7'd18)
121                 lcd_data <= 8'h8a;//3 line
122             else if(num == 7'd26)
123                 lcd_data <= 8'h99;//4 line
124                 
125             state <= WRITE_DATA1;
126         end
127         
128         WRITE_DATA1:
129         begin
130             if(num <= 7'd11) begin   
131                 num <= num + 1'b1;
132                 lcd_data <= dis_data;
133                 if(num == 7'd11)
134                     state <= SET_DDRAM;
135                 else
136                     state <= WRITE_DATA1;
137             end
138             else if( num > 7'd11 && num <= 7'd17) begin
139                 num <= num + 1'b1;
140                 lcd_data <= dis_data;
141                 if(num == 7'd17)
142                     state <= SET_DDRAM;
143                 else
144                     state <= WRITE_DATA1;
145             end
146             else if(num > 7'd17 && num <= 7'd25) begin
147                 num <= num + 1'b1;
148                 lcd_data <= dis_data;
149                 if(num == 7'd25)
150                     state <= SET_DDRAM;
151                 else
152                     state <= WRITE_DATA1;
153             end
154             else if(num > 7'd25 && num <= 7'd33) begin
155                 num <= num + 1'b1;
156                 lcd_data <= dis_data;
157                 if(num == 7'd33)
158                     state <= INIT_FUN_SET3;
159                 else
160                     state <= WRITE_DATA1;
161             end
162         end
163         
164         INIT_FUN_SET3:    
165         begin
166             lcd_data <= 8'h30;//功能設定
167             state <= SET_CGRAM;
168         end
169         
170         SET_CGRAM:
171         begin
172             lcd_data <= 8'h40;//設定CGRAM字符的位置
173             state <= WRITE_DATA2;
174         end
175         
176         WRITE_DATA2:
177         begin
178             if(num >= 7'd34 && num <= 7'd65) begin 
179                 num <= num + 1'b1;
180                 lcd_data <= dis_data;
181                 state <= WRITE_DATA2;
182             end
183             else begin
184                 num <= 7'd0;
185                 state <= SET_DDRAM2;
186             end
187         end
188         
189         SET_DDRAM2:
190         begin
191             lcd_data <= 8'h9e;    //4line
192             state <= SET_CUSTOM_H;//設置自定義顯示字符編碼
193         end
194         
195         SET_CUSTOM_H:
196         begin
197             lcd_data <= 8'h00;//高8bit
198             state <= SET_CUSTOM_L;
199         end
200         
201         SET_CUSTOM_L:
202         begin
203             lcd_data <= 8'h06;//低8bit 00:正常 02:星星左上角多了一小點 04:顯示的是亂碼 06:顯示也正常
204             state <= STOP;
205         end
206         
207         STOP: 
208         begin
209             en <= 1'b0;//顯示完了,lcd_e就一直拉為低
210             state <= STOP;
211         end
212         
213         default: state <= IDLE;
214     endcase
215 /***************************************************/
216 reg [7:0] dis_data;
217 always @(posedge sys_clk or negedge rst_n)
218 if(!rst_n)
219     dis_data <= 8'hzz;
220 else
221     case(num)
222     //1 Line 81位置顯示 歡迎訪問博客
223     7'd0   :    dis_data <= 8'hbb; 
224     7'd1   :    dis_data <= 8'hb6; 
225     7'd2   :    dis_data <= 8'hd3; 
226     7'd3   :    dis_data <= 8'had; 
227     7'd4   :    dis_data <= 8'hb7; 
228     7'd5   :    dis_data <= 8'hc3; 
229     7'd6   :    dis_data <= 8'hce; 
230     7'd7   :    dis_data <= 8'hca; 
231     7'd8   :    dis_data <= 8'hb2; 
232     7'd9   :    dis_data <= 8'ha9; 
233     7'd10  :    dis_data <= 8'hbf; 
234     7'd11  :    dis_data <= 8'hcd; 
235     //2Line    92位置顯示 文少清     
236     7'd12  :    dis_data <= 8'hce; 
237     7'd13  :    dis_data <= 8'hc4; 
238     7'd14  :    dis_data <= 8'hc9; 
239     7'd15  :    dis_data <= 8'hd9; 
240     7'd16  :    dis_data <= 8'hC7; 
241     7'd17  :    dis_data <= 8'he5; 
242     //3Line 8a位置顯示 LCD12864   
243     7'd18  :    dis_data <=  "L";  
244     7'd19  :    dis_data <=  "C";  
245     7'd20  :    dis_data <=  "D";  
246     7'd21  :    dis_data <=  "1";  
247     7'd22  :    dis_data <=  "2";  
248     7'd23  :    dis_data <=  "8";  
249     7'd24  :    dis_data <=  "6";  
250     7'd25  :    dis_data <=  "4";  
251     //4Line 99位置顯示 謝謝! 
252     7'd26  :    dis_data <= 8'hd0; 
253     7'd27  :    dis_data <= 8'hbb; 
254     7'd28  :    dis_data <= 8'hd0; 
255     7'd29  :    dis_data <= 8'hbb; 
256     7'd30  :    dis_data <= 8'ha3; 
257     7'd31  :    dis_data <= 8'ha1; 
258     7'd32  :    dis_data <= " ";   //這兩次空格可以不寫的
259     7'd33  :    dis_data <= " ";   
260     //4line 9e位置顯示星星月亮                            
261     7'd34  :    dis_data <= 8'h08;
262     7'd35  :    dis_data <= 8'h20;
263     7'd36  :    dis_data <= 8'h1c;
264     7'd37  :    dis_data <= 8'h10;
265     7'd38  :    dis_data <= 8'h1c;
266     7'd39  :    dis_data <= 8'h1c;
267     7'd40  :    dis_data <= 8'hff;
268     7'd41  :    dis_data <= 8'h9e;
269     7'd42  :    dis_data <= 8'h7f;
270     7'd43  :    dis_data <= 8'h1e;
271     7'd43  :    dis_data <= 8'h1c;
272     7'd45  :    dis_data <= 8'h1f;
273     7'd46  :    dis_data <= 8'h3e;
274     7'd47  :    dis_data <= 8'h1f;
275     7'd48  :    dis_data <= 8'h3e;
276     7'd49  :    dis_data <= 8'h1f;
277     7'd50  :    dis_data <= 8'h77;
278     7'd51  :    dis_data <= 8'h1f;
279     7'd52  :    dis_data <= 8'h41;
280     7'd53  :    dis_data <= 8'h3f;
281     7'd54  :    dis_data <= 8'h00;
282     7'd55  :    dis_data <= 8'h7e;
283     7'd56  :    dis_data <= 8'h00;
284     7'd57  :    dis_data <= 8'hfe;
285     7'd58  :    dis_data <= 8'h83;
286     7'd59  :    dis_data <= 8'hfc;
287     7'd60  :    dis_data <= 8'h7f;
288     7'd61  :    dis_data <= 8'hf8;
289     7'd62  :    dis_data <= 8'h3f;
290     7'd63  :    dis_data <= 8'hf0;
291     7'd64  :    dis_data <= 8'h0f;
292     7'd65  :    dis_data <= 8'hc0;
293     default:    dis_data <= 8'h00;
294     endcase 
295 /***************************************************/
296 assign lcd_rw = 1'b0;//只有寫模式
297 assign lcd_psb = 1'b1;//並口模式
298 assign lcd_en = en ?  lcd_clk : 1'b0;
299 /***************************************************/
300 endmodule
View Code

顯示效果:

圖片顯示待續。

 

 

 

 

 

 

 

  


免責聲明!

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



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