久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 4964|回復: 0
打印 上一主題 下一主題
收起左側

基于FPGA的LCD1602原理綜述

[復制鏈接]
跳轉到指定樓層
樓主
ID:323700 發表于 2018-5-6 19:53 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
LCD1602的簡單使用原理——跟大家分享我學習1602的總結與體會
我的總結主要分為這幾部分:
①LCD1602的硬件特性及引腳功能
②LCD1602的時序特性
③LCD1602的使用原理(包括帶字庫和不帶字庫的簡要使用方法,控制顯示指令)
④基于FPGA的LCD1602使用案例

Part 1.  LCD1602的硬件特性及引腳功能
   LCD1602顧名思義是一種02*16,即為兩行十六列的液晶顯示屏,液晶兩行,每行可以顯示16個字符,但是CGRAM及CGROM里面一共有160個字符,包括阿拉伯數字,英文字母大小寫,常用符號及日文。每個字符對應于一個ASCII碼值,在液晶顯示屏上顯示對應的字符時候,只需要將對應的ASCII碼寫到DDRAM中就好,詳細的步驟會在下面細說。液晶板上排列著5*8的字符點陣,8行,每行5個點位,高電平1就是該點顯示,低電平0就是該點不顯示。
  • 引腳功能:
RS,R/W,E控制數據端口DB0~DB7,數據的命令的讀寫由控制端口控制,并通過數據端口傳輸。端口其他特性這里不再贅述,詳細見1602液晶手冊。O(∩_∩)O
二、硬件特性:
①CGRAM 和CGROM
CGRAM:character generator ram   CGROM:character generator rom
CGRAM的地址空間:
CGRAM的地址是0x40~0x7F, 64個地址空間,每個地址雙字節,一共128字節,一個字符  是8個字節,所以一共能顯示8個自定義字符(每個雙字節地址只有一個字節是被自定義字符數據寫入的,另外個字節無效,因為CGARM的字符代碼的規定,詳細原因見下面)
字符對應的區位碼如下圖所示:
CGRAM: 字符產生ram,用來存放用戶自定義的字符,如上圖的兩條(1)~(8),區位碼為0x00~0x0F.0x00~0x07對應于(1)~(8);0x08~0x0F對應于下一條(1)~(8),雖然看起來有16個地址,但是其實只要8個地址可用,CGRAM的“字符碼”規定0~2為地址,3位無效,4~7位全為0,因此CGRAM的字符碼等效為0000X111,X為無效位,最后三位的地址只要八個,所以實際能用的只有8個。
其他為CGROM中自帶的字符,區位碼從0x21~0x7F,以各自的ASCII碼作為區位碼表示的基本字符。
將自定義的字符字模數8*8據寫入,字符數據有八行,每行八位點陣。
②DDRAM
DDRAM:data display ram數據顯示存儲器
DDRAM的地址空間與屏幕的對應關系如下圖:

DDRAM的地址空間一共有80字節

在1602中,我們只要前面16行就行,其地址和屏幕的對應關系:

Part 2.  LCD1602的時序特性
讀狀態:RS=0 ,RW=1,E=1
讀數據:RS=1,RW=1,E=1


寫命令:RS=0,RW=0,E=下降沿脈沖;DB0~DB7指令字
寫數據:RS=1,RW=0,E=下降沿脈沖;DB0~DB7數據
在E=1的時候寫入數據,在數據寫完之后,E來一個下降沿,把數據送到LCD。

Part4.LCD1602的指令功能
  • Display Clear清屏指令設置
   
<1>cursor move to first digit
<2>地址計數器AC的值設置為0;
  • Return Home光標歸位
<1>把光標撤回到顯示器的左上方
<2>把地址計數器Ac設置為0;
<3>保持DDRAM的值不變
  • Entry Mode set輸入模式設置指令
Function:
I/D   set cursor move direction H:increase L:decrease
寫入數據之后的光標移動的方向H:右移L:左移
S    specifies shift of display H:display is shifted L:display is not shifted
寫入一個數據之后顯示屏移動或者不移動
  • Display On/off顯示開關控制指令
  
D:H:顯示開; L:顯示關
C:H:光標開   L:光標關
B:H: 光標閃爍 L:光標不閃爍
  • Shift 設置顯示屏或者光標移動的方向
S/C:顯示屏還是光標 H:顯示屏移動L:光標移動
R/L:向左移動還是向右移動H:右移L;左移(光標右移:AC值加1;光標左移:AC值減1)
  • Set Function
DL:data length                            L:數據總線為4位    H:數據總線為8位
N  :number line                            L:1行 顯示         H:2行顯示
F :                               L:5×7點陣/每字符    H:5×10點陣/每字符
7、Set CGRAM Address
設置CGRAM的地址,我們將我們自定義的字模數據存入對應的地址,從0x40~0x7F,128字節,8個字符的字模數據可存入。
  • Set  DDRAM Address,(表格中寫錯了,是DDRAM)
與CGRAM一樣,在往DDRAM里面寫入想要顯示的字符的字符區位碼的之前需要將存儲字符區位碼的地址首先寫入。DDRAM的地址空間以上已述。(加地址的時候我們要加上0x80,因為寫入地址的時候DB7必須為1)
  • Read Busy Flag and the Address讀取忙碌標志和地址計數器的值
BF:H:忙碌,表示無法結束單片機送來的數據;L:準備就緒,可以接受數據
當內部操作正在進行的時候,讀取BF的值
AC:讀取地址計數器的值
  • 數據寫入CGRAMDDRAM
  • CGRAMDDRAM讀取數據

Part5.LCD1602的簡要原理

顯示字庫中本來就有的字符和顯示自定義的字符
  • 顯示字庫中本來就有的字符

步驟一:系統初始化和LCD初始化
步驟二:LCD液晶屏上面每個字符對應于DDRAm的地址,你想要把字符寫進屏幕哪個位置,就往DDRAM寫入該位置所對應的地址。(對應的地址在上述已說)
步驟三:字庫中本來已經存在的字符各自有對應的字符區位碼,其實就是每個字符對應的ASCII碼(見字符表格)。你要顯示哪個字符,只要將該字符對應的ASCII碼寫入DDRAM就搞定了,這個是很簡單的。

  • 顯示自定義的字符
其實顯示自定義的字符和字庫字符差不多的,只需要將你自定義的字符用取模工具得到字模的數組數據之后。之后的步驟和顯示字庫字符是一樣一樣滴。
步驟一:系統初始化和LCD初始化
步驟二:搞清楚字符點陣的格式是5*8,通過取字模工具得出自定義字符的字模數據,再寫入相應的CGRAM地址,一個地址寫入一個一個字節數據(一個字節的8位,前3位為0,點陣的格式5*8)
步驟三:同顯示字庫中本來就有的字符一樣的做法
Part 6. 基于FPGALCD1602使用案例

以下的程序例子是基于FPGA的液晶1602時鐘,是利用自帶字庫的方式顯示實時時鐘,主要通過時鐘控制狀態機來實現1602的工作程序(尚未驗證嘿嘿)
  1. library ieee;
  2. use ieee.std_logic_1164.all;
  3. use ieee.std_logic_arith.all;
  4. use ieee.std_logic_unsigned.all;
  5. entity lcd is
  6. port(
  7. clk:in std_logic;
  8. rw:out std_logic;
  9. rs:out std_logic;
  10. lcd_rst:out std_logic;
  11. data:out std_logic_vector( 7 downto 0);
  12. en:out std_logic
  13. );
  14. end lcd;
  15. architecture lcd1602 of lcd is
  16. signal clk_1m:std_logic:='1';
  17. signal clk_1s:std_logic:='1';
  18. type state is(s0,s1,s2,s3,s4,s5,s6,s7,s8,s9,s10);--定義狀態類型case語句上有具體說明
  19. signal current_s:state:=s0;
  20. type data_buffer is array(0 to 9) of std_logic_vector(7 downto 0);---定義數組類型
  21. signal
  22. date_buf:data_buffer:=(x"30",x"31",x"3a",x"33",x"34",x"3a",x"36",x"37",x"2a",x"2a");
  23. signal shi,fen,miao:integer range 0 to 100:=0;
  24. signal shi1,fen1,miao1:integer range 0 to 100:=0;
  25. begin
  26. process(clk)---對CLK 50M進行分頻系數為50的分頻clk_1m
  27. variable cnt:integer range 0 to 10000;---得到1M的時鐘
  28. begin
  29. if clk'event and clk='1' then

  30. if cnt=24 then
  31. clk_1m <= not clk_1m;cnt:=0;
  32. else cnt:=cnt+1;
  33. end if;
  34. end if;
  35. end process;
  36. process(clk)
  37. variable cnt:integer range 0 to 10000;
  38. variable cnt1:integer range 0 to 5000;
  39. begin
  40. if clk'event and clk='1' then

  41. if cnt=24900000 then ---cnt:0~24900000counter
  42. clk_1s <= not clk_1s;cnt:=0;------fenpin  clk_1s
  43. elsif cnt1=2000 then cnt:=cnt+1;cnt1:=0;---cnt1: 0~2000 counter
  44. else cnt1:=cnt1+1;
  45. end if;
  46. end if;
  47. end process;
  48. process(clk_1s)
  49. begin
  50. if clk_1s'event and clk_1s='1' then
  51.    if miao =59 then            
  52.              miao<=0;
  53.              if fen=59 then
  54.                            fen<=0;
  55.                            if shi=23 then
  56.                            shi<=0;
  57.                            else shi<=shi+1;
  58.                            end if;            
  59.              else fen<=fen+1;
  60.              end if;
  61.     else miao<=miao+1;
  62.    end if;
  63. end if;
  64. date_buf(0)<=conv_std_logic_vector (shi /10 ,8)+x"30";--強制轉換邏輯矢量,8bit
  65. date_buf(1)<=conv_std_logic_vector (shi mod 10,8)+x"30";
  66. date_buf(3)<=conv_std_logic_vector (fen /10,8)+x"30";
  67. date_buf(4)<=conv_std_logic_vector (fen mod 10,8)+x"30";
  68. date_buf(6)<=conv_std_logic_vector (miao /10,8)+x"30";
  69. date_buf(7)<=conv_std_logic_vector (miao mod 10 ,8)+x"30";
  70. end process;

  71. process(clk_1m,current_s,date_buf)
  72. variable i:integer range 0 to 11:=0;
  73. variable cnt1:integer range 0 to 100;
  74. variable cnt2:integer range 0 to 100;
  75. variable cnt3:integer range 0 to 100;
  76. variable cnt4:integer range 0 to 100;
  77. variable cnt5:integer range 0 to 100;
  78. variable cnt6:integer range 0 to 100;
  79. variable cnt7:integer range 0 to 100;
  80. variable cnt8:integer range 0 to 60000;
  81. begin
  82. current_s<=s0;
  83. if (clk_1m'event and clk_1m='1') then
  84. current_s <= current_s ;
  85. case current_s is

  86. when s0=>
  87. if cnt1 <5000 then
  88. lcd_rst<='0';cnt1:=cnt1+1;
  89. elsif cnt1<10000 then
  90. lcd_rst<='1';cnt1:=cnt1+1;
  91. elsif cnt1=10000 then lcd_rst<='1';current_s<=s1;cnt1:=0;
  92. end if;

  93. when s1=> cnt2:=cnt2+1;----設置功能指令字:8位數據總線,兩行顯示,5*7點陣
  94. if cnt2<10 then rw<='0';rs<='0';----command 0
  95. elsif cnt2<20 then data<=x"38";00111000
  96. elsif cnt2<30 then en<='1';
  97. elsif cnt2<70 then en<='0';
  98. elsif cnt2=100 then cnt2:=0;current_s<=s2;
  99. end if;
  100. when s2=>               ----顯示開關控制指令:D顯示開,C光標開,B光標閃爍
  101. cnt3:=cnt3+1;
  102. if cnt3<10 then rw<='0';rs<='0';
  103. elsif cnt3<20 then data<=x"0f";----00001111
  104. elsif cnt3<30 then en<='1';
  105. elsif cnt3<70 then en<='0';
  106. elsif cnt3=100 then cnt3:=0;current_s<=s3;
  107. end if;
  108. when s3=>                       -----輸入模式設置指令,寫入一個字符后光標右移,顯示屏不                        
  109. cnt4:=cnt4+1;                    -----移動
  110. if cnt4<10 then rw<='0';rs<='0';
  111. elsif cnt4<20 then data<=x"06";---00000110
  112. elsif cnt4<30 then en<='1';
  113. elsif cnt4<70 then en<='0';
  114. elsif cnt4=100 then cnt4:=0;current_s<=s5;
  115. end if;

  116. when s4=>                       -----displayclear 顯示清屏
  117. cnt5:=cnt5+1;
  118. if cnt5<10 then rw<='0';rs<='0';
  119. elsif cnt5<20 then data<=x"01";---00000001
  120. elsif cnt5<30 then en<='1';
  121. elsif cnt5<70 then en<='0';
  122. elsif cnt5=100 then cnt5:=0;current_s<=s5;
  123. end if;

  124. when s5=>                    -----寫DDRAM地址0X00+0X80
  125. cnt6:=cnt6+1;
  126. if cnt6<10 then rw<='0';rs<='0';
  127. elsif cnt6<20 then data<=x"80";---10000000
  128. elsif cnt6<30 then en<='1';
  129. elsif cnt6<70 then en<='0';
  130. elsif cnt6=100 then cnt6:=0;current_s<=s6;
  131. end if;
  132. when s6=>
  133. cnt7:=cnt7+1;
  134. if cnt7<10 then rw<='0';rs<='1';----WRITE DATA
  135. elsif cnt7<20 then data<=date_buf(i);--date_buf(i);時分秒的數據的ASCII碼
  136. elsif cnt7<30 then en<='1';     ---執行時間為40us
  137. elsif cnt7<70 then en<='0';
  138. elsif cnt7=100 then
  139.      if i=9 then cnt7:=0;current_s<=s7;i:=0;
  140.       else i:=i+1;current_s<=s6;cnt7:=0;end if;
  141. end if;

  142. when s7=>if cnt8<8000 then cnt8:=cnt8+1;
  143. else cnt8:=0;current_s<=s5;----循環等待8000的計數器,回到S5,繼續寫入DDRAM地                      ------址,進而      
  144. end if;-------------------------寫入數據


  145. when others=>null;
  146. end case;
  147. end if;

  148. end process;

  149. end lcd1602;
復制代碼

基于FPGA的LCD1602原理綜述.doc

447.5 KB, 下載次數: 9, 下載積分: 黑幣 -5

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏1 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 色花av| 免费看国产片在线观看 | 国产二区视频 | 日本午夜免费福利视频 | 精品中文字幕一区 | 久久免费小视频 | 国产一区二区三区视频 | 久久精品美女 | 日本一道本视频 | 亚洲第一网站 | 色免费视频 | 国产伊人久久久 | 精品国产一区二区三区日日嗨 | 欧美日在线| 亚洲高清在线 | 久久精品伊人 | 免费a国产 | 欧美一区二区三区电影 | 中文字幕 欧美 日韩 | 日韩电影一区 | 国产精品久久久久国产a级 欧美日本韩国一区二区 | 日本精品视频在线观看 | 国内在线视频 | 九九久久国产精品 | 精久久久久| 国产精品国产成人国产三级 | 国产视频一区在线观看 | 久久精品一级 | av国产精品| 日日爱夜夜操 | 精品一二区 | 国产精品免费在线 | 手机在线一区二区三区 | 久久久久国产一区二区三区 | 国产羞羞视频在线观看 | 国产精品久久久久久一级毛片 | 欧美一区日韩一区 | 亚洲激情第一页 | 国产精品国产a级 | 亚洲啪啪一区 | 亚洲国产精品第一区二区 |