目录
注意!
a) 本工程采用野火征途PRO开发板,外接LCD12864部件进行测试。
b) 有偿提供代码!!!可以定制功能!!!有需要私信!!!
c) 本文测试采用的是并口模式,只写不读
d) 12864与1602的指令有很多相似之处,但功能以及使用方法差异还是比较大的
e) 先放效果图
一、基础知识
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.2.10 进入扩展功能模式
1.2.11 设置画图地址
1.3 常用指令
1.4 内置字符、自定义字符以及画图显示原理
1.5 LCD16384初始化过程
二、部分代码
2.1 LCD12864滚动显示字符
2.2 LCD12864显示自定义字符“仰以殊观”
2.3 LCD12864显示图像
三、实测
3.1 LCD12864滚动显示字符
3.2 LCD12864显示自定义汉字
3.3 LCD12864显示图像
注意!
a) 本工程采用野火征途PRO开发板,外接LCD12864部件进行测试。
b) 有偿提供代码!!!可以定制功能!!!有需要私信!!!
c) 本文测试采用的是并口模式,只写不读
d) 12864与1602的指令有很多相似之处,但功能以及使用方法差异还是比较大的
e) 先放效果图
一、基础知识
1.1 引脚信息
VSS | 电源地 |
VDD/VCC | 电源正极 |
V0 | 偏压(可不接或接地或接电位器调整电压) |
RS | 寄存器选择(Register Select,选择数据或命令寄存器) |
RW | 读/写 |
E | 使能 |
D0-D7 | 8位数据 |
A | 背光正极 |
K | 背光负极 |
PSB | 给高电平 |
RST | 给高电平 |
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.2.10 进入扩展功能模式
1.2.11 设置画图地址
1.3 常用指令
'h30:功能设置(初始化指令)
'h34:进入扩展指令模式(画图关)
'h01:显示清屏(清DDRAM和AC(AddressCount地址计数器)值-1.3.1)
'h18:画面左移(1.3.5)
1.4 内置字符、自定义字符以及画图显示原理
这部分个人感觉有点复杂,还需要时间思考一下怎样才能表述清楚,过两天写
1.5 LCD16384初始化过程
a) 程序烧录到FPGA后首先复位15ms
b) 15ms后进入INIT初始化状态
c) INIT初始化状态分别写0x34 0x34 0x01
每次写指令或数据间隔时间均远大于处理时间,故不用考虑读忙信号
二、部分代码
2.1 LCD12864滚动显示字符
// -------------------字符显示寄存器S_data_display赋值
/*
两行循环显示0-9-a-z-A-D
*/
always @(*) begin
case(S_char_cnt)
'd0: S_data_display = "0";
'd1: S_data_display = "1";
'd2: S_data_display = "2";
'd3: S_data_display = "3";
'd4: S_data_display = "4";
'd5: S_data_display = "5";
'd6: S_data_display = "6";
'd7: S_data_display = "7";
'd8: S_data_display = "8";
'd9: S_data_display = "9";
'd10: S_data_display = "a";
'd11: S_data_display = "b";
'd12: S_data_display = "c";
'd13: S_data_display = "d";
'd14: S_data_display = "e";
'd15: S_data_display = "f";
'd16: S_data_display = "f";
'd17: S_data_display = "e";
'd18: S_data_display = "d";
'd19: S_data_display = "c";
'd20: S_data_display = "b";
'd21: S_data_display = "a";
'd22: S_data_display = "9";
'd23: S_data_display = "8";
'd24: S_data_display = "7";
'd25: S_data_display = "6";
'd26: S_data_display = "5";
'd27: S_data_display = "4";
'd28: S_data_display = "3";
'd29: S_data_display = "2";
'd30: S_data_display = "1";
'd31: S_data_display = "0";
'd32: S_data_display = "A";
'd33: S_data_display = "B";
'd34: S_data_display = "C";
'd35: S_data_display = "D";
'd36: S_data_display = "E";
S2 :begin O_lcd_data <= 8'h06; O_lcd_rs <= 0;end//控制读写后AC自动增减一,控制画面不动
S3 :begin O_lcd_data <= 8'h0E; O_lcd_rs <= 0;end//控制显示开/0c关游标显示,oe开游标显示
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'h90; O_lcd_rs <= 0;end
ROW3_ADDR :begin O_lcd_data <= 8'h88; O_lcd_rs <= 0;end
ROW4_ADDR :begin O_lcd_data <= 8'h98; O_lcd_rs <= 0;end
stop :begin O_lcd_data <= 8'h18; O_lcd_rs <= 0;end//控制画面左移
// stop :begin O_lcd_data <= 8'h30; O_lcd_rs <= 0;end//控制画面左移
stop1 :begin O_lcd_data <= 8'h30; O_lcd_rs <= 0;end//控制画面左移
stop2 :begin O_lcd_data <= 8'h30; O_lcd_rs <= 0;end//控制画面左移
default:;
endcase
end
end
endmodule
2.2 LCD12864显示自定义字符“仰以殊观”
//-------------------寄存器定义
reg [31:0] S_clk_cnt ;//时钟计数器,用来对系统时钟分频
reg [4:0] S_state_c ;//状态机
reg [4:0] S_state_n ;//状态机
reg [7:0] S_char_cnt ;//字符计数器
reg [7:0] S_data_display ;//字符显示寄存器
//-------------------定义状态
localparam
IDLE = 'd0 ,
INIT = 'd1 ,
S0 = 'd2 ,
S1 = 'd3 ,
S2 = 'd4 ,
S3 = 'd5 ,
WR_CGRAM_ADDR = 'd6 ,
WRITE = 'd7 ,
RD_CGRAM_ADDR1 = 'd8 ,
RD_CGRAM_ADDR2 = 'd22 ,
RD_CGRAM_H0 = 'd9 ,
RD_CGRAM_H1 = 'd10 ,
/*
显示自定义字形
//仰
{0x08,0x00,0x08,0x80,0x0B,0x3C,0x12,0x24,0x12,0x24,0x32,0x24,0x32,0x24,0x52,0x24},
{0x92,0x24,0x12,0x24,0x12,0xB4,0x13,0x28,0x12,0x20,0x10,0x20,0x10,0x20,0x10,0x20},
//以
{0x00,0x10,0x04,0x10,0x22,0x10,0x21,0x10,0x21,0x10,0x20,0x10,0x20,0x10,0x20,0x20},
{0x20,0x20,0x20,0x20,0x24,0x40,0x28,0x50,0x30,0x88,0x21,0x04,0x02,0x02,0x04,0x02},
//殊
{0x00,0x20,0x01,0x20,0xFD,0x20,0x21,0xFC,0x21,0x20,0x3E,0x20,0x44,0x20,0x47,0xFE},
{0x64,0x70,0x94,0xA8,0x08,0xA8,0x09,0x24,0x11,0x24,0x22,0x22,0x40,0x20,0x80,0x20},
//观
{0x00,0x00,0x01,0xFC,0x01,0x04,0xFD,0x04,0x05,0x24,0x05,0x24,0x49,0x24,0x29,0x24},
{0x11,0x24,0x11,0x54,0x28,0x50,0x24,0x90,0x44,0x90,0x81,0x12,0x02,0x12,0x04,0x0E},
*/
RD_CGRAM_ADDR1:begin O_lcd_data <= 8'h93; O_lcd_rs <= 0;end//设置DDRAM显示地址
RD_CGRAM_ADDR2:begin O_lcd_data <= 8'h8b; O_lcd_rs <= 0;end//设置DDRAM显示地址
RD_CGRAM_H0 :begin O_lcd_data <= 8'h00; O_lcd_rs <= 1;end//读CGRAM显示
RD_CGRAM_H1 :begin O_lcd_data <= 8'h00; O_lcd_rs <= 1;end//读CGRAM显示
RD_CGRAM_H2 :begin O_lcd_data <= 8'h00; O_lcd_rs <= 1;end//读CGRAM显示
RD_CGRAM_H3 :begin O_lcd_data <= 8'h00; O_lcd_rs <= 1;end//读CGRAM显示
RD_CGRAM_L0 :begin O_lcd_data <= 8'h00; O_lcd_rs <= 1;end//读CGRAM显示
RD_CGRAM_L1 :begin O_lcd_data <= 8'h02; O_lcd_rs <= 1;end//读CGRAM显示
RD_CGRAM_L2 :begin O_lcd_data <= 8'h04; O_lcd_rs <= 1;end//读CGRAM显示
RD_CGRAM_L3 :begin O_lcd_data <= 8'h06; O_lcd_rs <= 1;end//读CGRAM显示
2.3 LCD12864显示图像
//-------------------寄存器定义
reg [31:0] S_clk_cnt ;//时钟计数器,用来对系统时钟分频
reg [7:0] S_state_c ;//状态机
reg [7:0] S_state_n ;//状态机
reg [15:0] S_char_cnt ;//字符计数器
reg [7:0] S_data_display ;//字符显示寄存器
//-------------------定义状态
localparam
IDLE = 'd0 ,
INIT = 'd1 ,
S0 = 'd2 ,
S1 = 'd3 ,
S2 = 'd4 ,
S3 = 'd5 ,
WR_X_ADDR0 = 'd6 ,
WR_Y_ADDR0 = 'd7 ,
WR_Y_ADDR1 = 'd8 ,
WR_DATA = 'd9 ,
OPEN = 'd10 ,
stop = 'd11 ;
// -------------------字符显示寄存器S_data_display赋值
/*
显示自定义图像
'h00'h00'h00'h36'h00'h60'h38'h00'hC0'h03'hF8'h00'h00'h00'h00'h00
'h00'h00'h00'h7F'hF8'h64'h39'hFF'hC0'hFF'hF8'h00'h00'h00'h00'h00
'h00'h00'h00'h7D'hF8'h6E'h39'hFF'hF8'hFF'h18'h00'h00'h00'h00'h00
'h00'h00'h00'h7D'hD8'h67'h38'h67'hFC'h1B'h78'h00'h00'h00'h00'h00
'h00'h00'h00'hFD'hD8'h63'hB0'h7E'hC0'hDB'h78'h00'h00'h00'h00'h00
'h00'h00'h01'hFD'hD8'h61'h30'hFE'hC0'hFB'h78'h00'h00'h00'h40'h00
'h00'h00'h01'hFD'hD8'h60'h30'hDF'hFC'h7B'h78'h00'h00'h0F'hF8'h00
'h00'h00'h01'hFD'hD8'h6C'h31'hFF'hFC'h3B'h78'h00'h00'h7F'hF8'h00
'h00'h00'h00'hFF'hD8'h7C'h71'hFB'hE0'h3B'hF8'h00'h01'hFF'hF8'h00
'h00'h00'h00'hFF'hD8'h78'h70'h33'hF0'h7C'hE0'h00'h0F'hFF'hF0'h00
'h00'h00'h00'hFF'hF8'h70'hF8'h77'hF8'hED'hE0'h00'h3F'hFF'hE0'h00
'h00'h00'h00'hFD'hF8'hE3'hDC'hEE'hDD'hC3'hEE'h00'hFF'hFF'hC0'h00
'h00'h00'h00'hF9'hC0'h7F'h8D'hDC'hCC'h8F'h7E'h03'hFF'hFF'h80'h00
'h00'h00'h00'hC1'hC0'h0E'h08'h88'hC0'h0E'h7C'h0F'hFF'hFF'h00'h00
'h00'h00'h00'h00'h00'h01'h80'h00'hC0'h00'h00'h3F'hFF'hFE'h00'h00
'h00'h00'h00'h00'h00'h1F'hE0'h00'h00'h00'h00'hFF'hFF'hF8'h00'h00
'h00'h00'h00'h00'h00'hFF'hE0'h07'h80'h00'h03'hFF'hFF'hF0'h00'h00
'h00'h00'h3F'hFF'h83'hFF'hC0'h3F'hC0'h00'h0F'hFF'hFF'hC0'h00'h00
'h00'h00'h7F'hFF'hFF'hFF'h81'hFF'hC0'h00'h3F'hFF'hFF'h80'h00'h00
'h00'h03'hFF'hFF'hFF'hFF'hFF'hFF'h80'h00'hFF'hFF'hFE'h00'h00'h00
'h00'h03'hFF'hFF'hFF'hFF'hFF'hFF'hFF'h83'hFF'hFF'hFC'h00'h00'h00
'h00'h00'hFF'hFF'hFF'hFF'hFF'hFF'hFF'hFF'hFF'hFF'hF0'h00'h00'h00
'h00'h00'h07'hFF'hFF'hFF'hFF'hFF'hFF'hFF'hFF'hFF'hC0'h00'h00'h00
'h00'h00'h00'h3F'hFF'hFF'hFF'hFF'hFF'hFF'hFF'hFF'h80'h00'h00'h00
'h00'h00'h00'h03'hFF'hFF'hFF'hFF'hFF'hFF'hFF'hFE'h00'h00'h00'h00
'h00'h00'h00'h00'h1F'hFF'hFF'hFF'hFF'hFF'hFF'hF8'h00'h00'h00'h00
'h00'h00'h00'h00'h00'hFF'hFF'hFF'hFF'hFF'hFF'hE0'h00'h00'h00'h00
'h00'h00'h00'h00'h00'h07'hFF'hFF'hFF'hFF'hFF'hC0'h00'h00'h00'h00
'h00'h00'h00'h00'h00'h00'h7F'hFF'hFF'hFF'hFF'h80'h00'h00'h00'h00
'h00'h00'h00'h00'h00'h00'h03'hFF'hFF'hFF'hFF'hC0'h00'h00'h00'h00
'h00'h00'h00'h00'h00'h00'h00'h0F'hFF'hFF'hFF'hC0'h00'h00'h00'h00
'h00'h00'h00'h00'h00'h00'h00'h0F'hFF'hFF'hFF'hC0'h00'h00'h00'h00
'h00'h00'h00'h00'h00'h00'h00'h3F'hFF'hFF'hFF'hE0'h00'h00'h00'h00
'h00'h00'h00'h00'h00'h00'h00'h7F'hFF'hFF'hFF'hE0'h00'h00'h00'h00
'h00'h00'h00'h00'h00'h00'h01'hFF'hFF'hFF'hFF'hFF'hC0'h00'h00'h00
'h00'h00'h00'h00'h00'h00'h07'hFF'hFF'hFF'hFF'hFF'hC0'h00'h00'h00
'h00'h00'h00'h00'h00'h00'h0F'hFF'hFF'hFF'hFF'hFF'h80'h00'h00'h00
'h00'h00'h00'h00'h00'h00'h3F'hFF'hFC'hFF'hFF'hFF'h80'h00'h00'h00
'h00'h00'h00'h00'h00'h00'h7F'hFF'hF0'h7F'hFF'hFF'h00'h00'h00'h00
'h00'h00'h00'h00'h00'h01'hFF'hFF'hC0'h3F'hFF'hFC'h00'h00'h00'h00
'h00'h00'h00'h00'h00'h03'hFF'hFF'h00'h3F'hFF'hF8'h00'h00'h00'h00
'h00'h00'h00'h00'h00'h0F'hFF'hFC'h00'h1F'hFF'hF8'h00'h00'h00'h00
'h00'h00'h00'h00'h00'h1F'hFF'hE0'h00'h0F'hFF'hF9'hF0'h00'h00'h00
'h00'h00'h00'h00'h00'h7F'hFF'h80'h00'h0F'hFF'hFF'hF8'h00'h00'h00
'h00'h00'h03'hE0'h00'hFF'hFE'h00'h00'h07'hFF'hFF'hF8'h00'h00'h00
'h00'h00'h07'hFF'hFF'hFF'hF8'h00'h00'h03'hFF'hFF'hF0'h00'h00'h00
'h00'h00'h1F'hFF'hFF'hFF'hE0'h00'h00'h03'hFF'hFF'hE0'h00'h00'h00
'h00'h00'h3F'hFF'hFF'hFF'h80'h00'h00'h01'hFF'hFF'hC0'h00'h00'h00
'h00'h00'h07'hFF'hFF'hFE'h00'h00'h00'h00'hFF'hFF'h80'h00'h00'h00
'h00'h00'h00'hFF'hFF'hF8'h00'h00'h00'h00'h7F'hFE'h00'h00'h00'h00
'h00'h00'h00'h0F'hFF'hF8'h00'h00'h00'h00'h7F'hFE'h00'h00'h00'h00
'h00'h00'h00'h00'hFF'hFC'h00'h00'h00'h00'h3F'hFE'h00'h00'h00'h00
'h00'h00'h00'h00'h3F'hFC'h00'h00'h00'h00'h1F'hFF'h00'h00'h00'h00
'h00'h00'h00'h00'h1F'hFC'h00'h00'h00'h00'h1F'hFF'h00'h00'h00'h00
'h00'h00'h00'h00'h0F'hFC'h00'h00'h00'h00'h0F'hFF'h00'h00'h00'h00
'h00'h00'h00'h00'h07'hFC'h00'h00'h00'h00'h07'hFF'h00'h00'h00'h00
'h00'h00'h00'h00'h03'hFE'h00'h00'h00'h00'h07'hFF'h00'h00'h00'h00
'h00'h00'h00'h00'h01'hFE'h00'h00'h00'h00'h03'hFF'h80'h00'h00'h00
'h00'h00'h00'h00'h01'hF8'h00'h00'h00'h00'h01'hFF'h80'h00'h00'h00
'h00'h00'h00'h00'h00'hF0'h00'h00'h00'h00'h01'hFF'h80'h00'h00'h00
'h00'h00'h00'h00'h00'h40'h00'h00'h00'h00'h00'hFE'h00'h00'h00'h00
'h00'h00'h00'h00'h00'h00'h00'h00'h00'h00'h00'h78'h00'h00'h00'h00
'h00'h00'h00'h00'h00'h00'h00'h00'h00'h00'h00'h70'h00'h00'h00'h00
'h00'h00'h00'h00'h00'h00'h00'h00'h00'h00'h00'h00'h00'h00'h00'h00C:\Users\26058\Desktop\1.bmp0
*/
三、实测
3.1 LCD12864滚动显示字符
LCD12864滚动显示字符
3.2 LCD12864显示自定义汉字
3.3 LCD12864显示图像
左侧的白线消除不了,只要往第二部分的图像部分进行赋值,就会有这道白线(两个字节),暂时不清楚是逻辑问题还是硬件问题,不过不影响整体效果。