目录
注意!
本工程采用野火征途PRO开发板,外接LCD1602部件进行测试。
有偿提供代码!!!可以定制功能!!!有需要私信!!!
一、基础知识
1.1 引脚信息
1.2 指令
1.2.1 清屏
1.2.2 归位(返回)
1.2.3 输入方式设置
1.2.4 显示模式控制
1.2.5 光标、画面位移
1.2.6 功能设置
1.2.7 CG RAM地址设置
1.2.8 DD RAM地址设置
1.2.9 写数据
1.3 常用指令
1.4 内置字符与自定义字符显示原理
1.5 LCD1602初始化过程
二、部分代码
2.1 LCD1602循环滚动显示0-9-a-z-A-D
2.2 LCD1602显示自定义字符“仰以殊观”
三、实测
3.1 LCD1602循环滚动显示0-9-a-z-A-D
3.1.1 第一行显示0-9-a-z-A-D
3.1.2 第二行显示0-9-a-z-A-D
3.1.3 滚动显示
3.2 LCD1602显示自定义字符“仰以殊观”
注意!
本工程采用野火征途PRO开发板,外接LCD1602部件进行测试。
有偿提供代码!!!可以定制功能!!!有需要私信!!!
联系方式见底部
一、基础知识
1.1 引脚信息
VSS | 电源地 |
VDD | 电源正极 |
V0 | 偏压(可不接或接地或接电位器调整电压) |
RS | 寄存器选择(Register Select,选择数据或命令寄存器) |
RW | 读/写 |
E | 使能 |
D0-D7 | 8位数据 |
A | 背光正极 |
K | 背光负极 |
1.2 指令
1.2.1 清屏
运行时间(250Khz): 1.64 µs
功能:清DDRAM和AC值。
1.2.2 归位(返回)
运行时间(250Khz): 1.64 µs
功能:AC= 0, 光标、画面回HOME位。
1.2.3 输入方式设置
运行时间(250Khz): 40 µs
功能:设置光标、画面移动方式。
其中:I/D =1: 数据读、写操作后,AC自动增一;
I/D =0: 数据读、写操作后,AC自动减一;
S = 1:数据读、写操作,画面平移;
S = 0: 数据读、写操作,画面不动。
1.2.4 显示模式控制
运行时间(250Khz): 40 µs
功能:设置显示、光标及闪烁开关。
其中:D表示显示开关:D = 1为开,D = 0为关;
C表示光标开关:C = 1为开,C = 0为关;
B表示闪烁开关:B = 1为开,B = 0为关。
1.2.5 光标、画面位移
运行时间(250Khz): 40 µs
功能:光标、画面移动,不影响DDRAM。
其中:S/C = 1: 画面左移一个字符位;
S/C = 0: 画面右移一个字符位;
R/L = 1: 光标左移一个字符位;
R/L = 0:光标右移一个字符位。
1.2.6 功能设置
运行时间(250Khz): 40 µs
功能:工作方式设置(初始化指令)。
其中:DL = 1:8位数据接口;
DL = 0:4位数据接口;
N = 1:两行显示;
N = 0:一行显示;
F = 1:5 × 10点阵字符;
F = 0:5 × 7点阵字符。
1.2.7 CG RAM地址设置
运行时间(250Khz): 40 µs
功能:设置CG RAM地址。A5 ~ A0 = 0 ~ 3FH
1.2.8 DD RAM地址设置
运行时间(250Khz): 40 µs
功能:设置DD RAM地址;
N = 0:一行显示,A6 ~ A0 = 0 ~ 4FH
N = 1: 两行显示,首行A6 ~ A0 = 00H ~ 2FH ,次行A6 ~ A0 = 40H ~ 67H
1.2.9 写数据
运行时间(250Khz): 40 µs
功能:根据最近设置的地址性质,数据写入DD RAM或CG RAM内。
1.3 常用指令
'h38:功能设置(初始化指令,设置数据接口位数-1.3.6)
'h08:显示关闭(所有显示1.3.4)
'h01:显示清屏(清DDRAM和AC(AddressCount地址计数器)值-1.3.1)
'h06:显示光标及画面移动设置(控制读写后AC自动增减一,控制画面平移或不动-1.3.3)
'h0c:显示开及光标设置(控制显示开关,光标开关,闪烁开关-1.3.4)
'h18:画面左移(1.3.5)
1.4 内置字符与自定义字符显示原理
a) DDRAM就相当于显示映射,最多可以显示2行*40列=80个字符,但是屏幕上只支持显示2行*16列=32个字符,显示字符时直接把想要显示数字或字母的ASCII值赋给D0-D7即可。
b) CGROM中存储了00-ff个字符(其中00-07字符可以由CGRAM定义),用户将地址写入到DDRAM,相当于是把地址写入了CGROM中,然后CGROM将字符输出到DDRAM进行显示。
c) CGRAM可以存储自定义字符,下图为DDRAM数据,CGRAM地址与写入字模码之间关系
1、字符码(DDRAM数据)0 ~ 2位与CGRAM地址3 ~ 5位对应(要么是000,要么是001);
2、CGRAM地址0 ~ 2位生成字模数据行位置(一个字符8行,一次输入一行,注意第八行为游标位置)
3、字符码3位的赋值状态并不影响用户自定义
4、用户自定义字符码的范围为00H ~ 07H或者08H ~ 0FH,也就是说字符码00H与08H对应同一 组用户自定义字符字模;
d) 自定义字符输入完毕后,将自定义字符的地址赋值给DDRAM即可显示自定义字符
字符码 | CGRAM地址 |
0x00 | 0x00-0x07 |
0x01 | 0x08-0x0f |
0x02 | 0x10-0x17 |
0x03 | 0x18-0x1f |
0x04 | 0x20-0x27 |
0x05 | 0x28-0x2f |
0x06 | 0x30-0x37 |
0x07 | 0x38-0x3f |
1.5 LCD1602初始化过程
a) 程序烧录到FPGA后首先复位15ms
b) 15ms后进入INIT初始化状态
c) INIT初始化状态分别写0x38 0x08 0x01 0x06 0x0c
每次写指令或数据间隔时间均远大于处理时间,故不用考虑读忙信号
二、部分代码
2.1 LCD1602循环滚动显示0-9-a-z-A-D
// -------------------状态机控制LCD数据/指令赋值
always @(posedge I_clk or negedge I_rst_n) begin
if (!I_rst_n) begin
O_lcd_data <= 8'd0;
end
else begin
case(S_state_c)
IDLE :begin O_lcd_data <= 8'h38; O_lcd_rs <= 0;end//初始化指令,设置lcd1602模式为8位数据接口;两行显示,5*7点阵(硬件限制)
S1 :begin O_lcd_data <= 8'h01; O_lcd_rs <= 0;end//清屏(清DDRAM以及AC计数器)
S2 :begin O_lcd_data <= 8'h06; O_lcd_rs <= 0;end//控制读写后AC自动增减一,控制画面不动
S3 :begin O_lcd_data <= 8'h0c; O_lcd_rs <= 0;end//控制显示开,光标关,闪烁关
ROW1_ADDR :begin O_lcd_data <= 8'h80; O_lcd_rs <= 0;end
WRITE :begin O_lcd_data <= S_data_display; O_lcd_rs <= 1;end
ROW2_ADDR :begin O_lcd_data <= 8'hc0; O_lcd_rs <= 0;end
stop :begin O_lcd_data <= 8'h18; O_lcd_rs <= 0;end//控制画面左移
default:;
endcase
end
end
2.2 LCD1602显示自定义字符“仰以殊观”
一开始用的字模软件生成的01序列,但是5*8点阵来显示汉字有点太挤了,看不出来字形,所以将“仰殊观”这三个汉字拆成了两部分,其中“仰”的第一部分用一个5*8点阵显示,第二部分和“以”的左边一个竖用一个5*8点阵显示,“以”的右边部分用一个5*8点阵显示,“殊观”两个字分别用两个5*8点阵显示
// -------------------字符显示寄存器S_data_display赋值
/*
向CGRAM写入数据
*/
always @(*) begin
case(S_char_cnt)
//-------------仰-------------
'd0: S_data_display = 8'h05;
'd1: S_data_display = 8'h0a;
'd2: S_data_display = 8'h1a;
'd3: S_data_display = 8'h0a;
'd4: S_data_display = 8'h0b;
'd5: S_data_display = 8'h0a;
'd6: S_data_display = 8'h08;
'd7: S_data_display = 8'h00;
//------------仰以------------
'd8: S_data_display = 8'h1d;
'd9: S_data_display = 8'h15;
'd10: S_data_display = 8'h15;
'd11: S_data_display = 8'h1d;
'd12: S_data_display = 8'h11;
'd13: S_data_display = 8'h11;
'd14: S_data_display = 8'h11;
'd15: S_data_display = 8'h00;
//-------------以-------------
'd16: S_data_display = 8'h04;
'd17: S_data_display = 8'h04;
'd18: S_data_display = 8'h14;
'd19: S_data_display = 8'h14;
'd20: S_data_display = 8'h14;
'd21: S_data_display = 8'h0a;
'd22: S_data_display = 8'h11;
'd23: S_data_display = 8'h00;
//-------------殊-------------
'd24: S_data_display = 8'h1f;
'd25: S_data_display = 8'h04;
'd26: S_data_display = 8'h0b;
'd27: S_data_display = 8'h15;
'd28: S_data_display = 8'h01;
'd29: S_data_display = 8'h02;
'd30: S_data_display = 8'h04;
'd31: S_data_display = 8'h00;
//-------------殊-------------
'd32: S_data_display = 8'h14;
'd33: S_data_display = 8'h1f;
'd34: S_data_display = 8'h04;
'd35: S_data_display = 8'h1f;
'd36: S_data_display = 8'h0e;
'd37: S_data_display = 8'h15;
'd38: S_data_display = 8'h04;
'd39: S_data_display = 8'h00;
//-------------观-------------
'd40: S_data_display = 8'h1f;
'd41: S_data_display = 8'h11;
'd42: S_data_display = 8'h0a;
'd43: S_data_display = 8'h04;
'd44: S_data_display = 8'h0a;
'd45: S_data_display = 8'h11;
'd46: S_data_display = 8'h00;
'd47: S_data_display = 8'h00;
//-------------观-------------
'd48: S_data_display = 8'h1f;
'd49: S_data_display = 8'h15;
'd50: S_data_display = 8'h15;
'd51: S_data_display = 8'h04;
'd52: S_data_display = 8'h0c;
'd53: S_data_display = 8'h15;
'd54: S_data_display = 8'h07;
'd55: S_data_display = 8'h00;
default:S_data_display = "P";
endcase
end
三、实测
3.1 LCD1602循环滚动显示0-9-a-z-A-D
这里采用的方法是将DDRAM的2行40列全部显示0-9-a-z-A-D(10+26+4=40),然后让屏幕滚动起来
3.1.1 第一行显示0-9-a-z-A-D
LCD1602循环显示0-9-a-z-A-D(一)
3.1.2 第二行显示0-9-a-z-A-D
LCD1602循环显示0-9-a-z-A-D(二)
3.1.3 滚动显示
LCD1602循环显示0-9-a-z-A-D(三)
3.2 LCD1602显示自定义字符“仰以殊观”
这里采用的方法是用excel自己排列每个汉字的01序列,然后写入CGRAM中。