FPGA实现LCD12864控制

目录

注意!

a) 本工程采用野火征途PRO开发板,外接LCD12864部件进行测试。 本工程采用野火征途PRO开发板,外接LCD12864部件进行测试。)

b) 有偿提供代码!!!可以定制功能!!!有需要私信!!! 有偿提供代码!!!可以定制功能!!!有需要私信!!!)

c) 本文测试采用的是并口模式,只写不读 本文测试采用的是并口模式,只写不读)

d) 12864与1602的指令有很多相似之处,但功能以及使用方法差异还是比较大的 12864与1602的指令有很多相似之处,但功能以及使用方法差异还是比较大的)

e) 先放效果图 先放效果图)

一、基础知识

[1.1 引脚信息](#1.1 引脚信息)

[1.2 指令](#1.2 指令)

[1.2.1 清屏](#1.2.1 清屏)

[1.2.2 归位(返回)](#1.2.2 归位(返回))

[1.2.3 进入设定点](#1.2.3 进入设定点)

[1.2.4 显示模式控制](#1.2.4 显示模式控制)

[1.2.5 光标、画面位移](#1.2.5 光标、画面位移)

[1.2.6 功能设置](#1.2.6 功能设置)

[1.2.7 CG RAM地址设置](#1.2.7 CG RAM地址设置)

[1.2.8 DD RAM地址设置](#1.2.8 DD RAM地址设置)

[1.2.9 写数据](#1.2.9 写数据)

[1.2.10 进入扩展功能模式](#1.2.10 进入扩展功能模式)

[1.2.11 设置画图地址](#1.2.11 设置画图地址)

[1.3 常用指令](#1.3 常用指令)

[1.4 内置字符、自定义字符以及画图显示原理](#1.4 内置字符、自定义字符以及画图显示原理)

[1.5 LCD16384初始化过程](#1.5 LCD16384初始化过程)

二、部分代码

[2.1 LCD12864滚动显示字符](#2.1 LCD12864滚动显示字符)

[2.2 LCD12864显示自定义字符"仰以殊观"](#2.2 LCD12864显示自定义字符“仰以殊观”)

[2.3 LCD12864显示图像](#2.3 LCD12864显示图像)

三、实测

[3.1 LCD12864滚动显示字符](#3.1 LCD12864滚动显示字符)

[3.2 LCD12864显示自定义汉字](#3.2 LCD12864显示自定义汉字)

[3.3 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显示图像

左侧的白线消除不了,只要往第二部分的图像部分进行赋值,就会有这道白线(两个字节),暂时不清楚是逻辑问题还是硬件问题,不过不影响整体效果。

相关推荐
千穹凌帝1 小时前
SpinalHDL之结构(二)
开发语言·前端·fpga开发
一口一口吃成大V7 小时前
FPGA随记——FPGA时序优化小经验
fpga开发
贾saisai8 小时前
Xilinx系FPGA学习笔记(九)DDR3学习
笔记·学习·fpga开发
redcocal12 小时前
地平线秋招
python·嵌入式硬件·算法·fpga开发·求职招聘
思尔芯S2C1 天前
高密原型验证系统解决方案(下篇)
fpga开发·soc设计·debugging·fpga原型验证·prototyping·深度调试·多fpga 调试
坚持每天写程序1 天前
xilinx vivado PULLMODE 设置思路
fpga开发
redcocal2 天前
地平线内推码 kbrfck
c++·嵌入式硬件·mcu·算法·fpga开发·求职招聘
邹莉斯3 天前
FPGA基本结构和简单原理
fpga开发·硬件工程
悲喜自渡7213 天前
易灵思FPGA开发(一)——软件安装
fpga开发
ZxsLoves3 天前
【【通信协议ARP的verilog实现】】
fpga开发