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

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

相关推荐
DS小龙哥7 小时前
基于Zynq FPGA的雷龙SD NAND存储芯片性能测试
fpga开发·sd nand·雷龙·spi nand·spi nand flash·工业级tf卡·嵌入式tf卡
上理考研周导师17 小时前
第二章 虚拟仪器及其构成原理
fpga开发
FPGA技术实战18 小时前
《探索Zynq MPSoC》学习笔记(二)
fpga开发·mpsoc
bigbig猩猩1 天前
FPGA(现场可编程门阵列)的时序分析
fpga开发
Terasic友晶科技1 天前
第2篇 使用Intel FPGA Monitor Program创建基于ARM处理器的汇编或C语言工程<二>
fpga开发·汇编语言和c语言
码农阿豪1 天前
基于Zynq FPGA对雷龙SD NAND的测试
fpga开发·sd nand·spi nand·spi nand flash·工业级tf卡·嵌入式tf卡
江山如画,佳人北望1 天前
EDA技术简介
fpga开发
淘晶驰AK1 天前
电子设计竞赛准备经历分享
嵌入式硬件·fpga开发
最好有梦想~1 天前
FPGA时序分析和约束学习笔记(4、IO传输模型)
笔记·学习·fpga开发