鬼谷左原 发表于 2016-3-8 01:24:42

LCD1602驱动设计及VHDL实现

3.4.1LCD1602简介
1602LCD分为带背光和不带背光两种,基控制器大部分为HD44780,带背光的比不带背光的厚,是否带背光在应用中并无差别。
1602LCD一般带有字库,也就是主机往指定的地方写ASCII码就可以显示想要的字符,无需复杂的取模。
1602液晶模块内部的控制器共有11条控制指令,如下表所示:
序号
指令
RS
R/W
D7
D6
D5
D4
D3
D2
D1
D0
1
清显示
0
0
0
0
0
0
0
0
0
1
2
光标返回
0
0
0
0
0
0
0
0
1
*
3
置输入模式
0
0
0
0
0
0
0
1
I/D
S
4
显示开/关控制
0
0
0
0
0
0
1
D
C
B
5
光标或字符移位
0
0
0
0
0
1
S/C
R/L
*
*
6
置功能
0
0
0
0
1
DL
N
F
*
*
7
置字符发生存贮器地址
0
0
0
1
字符发生存贮器地址
8
置数据存贮器地址
0
0
1
显示数据存贮器地址
9
读忙标志或地址
0
1
BF
计数器地址
10
写数到CGRAM或DDRAM)
1
0
要写的数据内容
11
从CGRAM或DDRAM读数
1
1
读出的数据内容
3.4.2LCD1602读写时序及代码实现
对于LCD1602写之前一般要确认是否正在忙,否则会导致写入失败,对于本设计而言,这里不做检测,直接写命令和数据,简化设计
写命令和写数据的时序和代码实现一致。以写命令为例:file:///C:/Users/yao/AppData/Local/Temp/msohtmlclip1/01/clip_image002.jpg
代码实现:
这里同样使用把时序整合带状态机的概念,把R/W,RS,E 拉低,输出数据到并行管脚计数一段时间后,拉高E管脚,在计数一段时间后拉低E管脚一段时间,这样完成了写命令的过程,握手信号的设计与IIC模块的一致。
case stateis
whenx"0"=>--写时序产生
         done_flag<= '0';
         --en
         if cnt_div = 10#0# then LCD_EN<='0';
         elsif cnt_div = Period_Pos thenLCD_EN<='1'; LCD_Data<= wr_data;
         elsif cnt_div = Period_Neg thenLCD_EN<='0';
         end if;
         
         if cnt_div =10#0# thenLCD_RS<='0';--写命令
--       elsif cnt_div = Period thenLCD_RS<='1';
         end if;
         
         if cnt_div = Period then state <=x"1"; cnt_div<=(others =>'0');
         else cnt_div<=cnt_div+1;
         end if;
whenx"1" =>--产生一个时钟的高电平
         done_flag<='1';
         state <=x"2";
whenx"2" =>--产生一个时钟的高电平
         done_flag<='0';
         state <=x"0";
whenothers =>state <=x"0";
end case;
         3.4.3LCD1602驱动设计总结
      使用上述的写命令和写数据模块,通过握手通信进行同步,完成以下初始化过程(1)-(4),循环在(5),(6)状态就可以使LCD显示想要的字符
(1)      发送命令31h(设置8位数据线模式,单行,5*7)(这里使用单行显示的原因是LCD1602 3.3V供电后显示双行时亮度不够,故加了个数码管电路来显示温度)
(2)      发送命令01h(清屏)
(3)      发送命令06h(设置每写入一个数据光标右移,地址加1)
(4)      发送命令0fh(显示开及光标有并闪烁)
(5)      发送地址
(6)      发送数据(ASCII码)
页: [1]
查看完整版本: LCD1602驱动设计及VHDL实现