差别

这里会显示出您选择的修订版和当前版本之间的差别。

到此差别页面的链接

两侧同时换到之前的修订记录 前一修订版
后一修订版
前一修订版
lcd显示模块 [2017/09/07 09:06]
anran [基于STEP FPGA的SPI RGB液晶屏功能驱动]
lcd显示模块 [2021/01/06 23:00] (当前版本)
gongyu
行 1: 行 1:
-======基于STEP FPGA的SPI RGB液晶屏显示驱动======+### 基于STEP FPGA的SPI RGB液晶屏显示驱动
  
 本节将和大家一起使用FPGA驱动底板上的1.8寸RGB液晶屏实现图片显示功能。 本节将和大家一起使用FPGA驱动底板上的1.8寸RGB液晶屏实现图片显示功能。
行 5: 行 5:
  
 ====硬件说明==== ====硬件说明====
 +
 ------- -------
-VGA(video graphics array)即视频图形阵列,是IBM在1987年随PS/​2一起推出使用拟信号一种视频传输标准VGA接口分公口和母口,如下图:+我们[[STEP-BaseBoard]]底板上集成了1.8寸彩色液晶屏TFT_LCD块,大家可以驱动LCD显示文字、图片或动态波形 
 \\ \\
-{{ :vga接口.jpg?400 |}}+首先了解一下液晶屏模块,相关资料下载:[[https://​pan.baidu.com/​s/​1bp6AYsR]] 
 +{{ :1.8寸lcd模块图.png?800 |}}
 \\ \\
-VGA接口引脚定义如下:+框图如下: 
 +{{ :​1.8寸lcd模块规格书.png?​800 |}}
 \\ \\
-{{ :vga接口定义.jpg?800 |}}+原理图如下: 
 +{{ :1.8寸lcd模块原理图.png?800 |}}
 \\ \\
-一个标准VGA接口应该有以下端口:+原理图中器件U1为液晶屏,液晶屏为1.8寸,128*RGB*160像素,串行总线(SPI),液晶屏集成了ST7735S的驱动器,处理器与ST7735S通信完成液晶屏的显示控制 
 +{{ :​1.8寸lcd规格书.png?​800 |}}
 \\ \\
-  * 红绿蓝三色号(R\G\B) +ST7735S为132RGB x 162像素点 262K 控制器/​驱动器,芯片可以直接跟外部处理器连接,支持串行SPI通和8/​9/​16/​18位并信(本液晶集成ST7735S时没有留并行接口所以只能使用串),详细参请参考数据手册:{{:​st7735s_datasheet.pdf|}}
-  * 场同步HS\VS) +
-  * 以及很多的地蔽; +
-三色信号都是模拟信号,行场同步号都是字信号;+
 \\ \\
-对于VGA的接口模拟电压,为0~0.714V,0代表无色,0.714代表满色,FPGA输出3.3V,所以还必须要经过DAC的转换。现今有两种比较成熟的方法:电阻分压方式和DAC转换方式。 +
-\\ +
-我们的底板上就是采用的电阻分压的方式,因VGA显示器端有75欧的下拉电阻,为了得到0.714V的电压我们给RGB信号线上串入270欧的电阻,3.3V*75/​(270+75)=0.717V。如下 +
-\\ +
-{{ :​vga接口电路.png?​800 |}} +
-\\ +
-VGA驱动显示器用的是扫描的方式,逐行扫描the HS (Horizontal Synchronization)逐行扫描是扫描从屏幕的左上角一点开始,由左向右逐点扫描,每扫描完一行,电子束回到屏幕的左边下一行的起始位置,在这期间CRT(阴极射线显像管)对电子束进行消隐,每行结束时,用行同步信号进行同步;当扫描完所有行之后形成一帧,用场同步信号进行同步,并使扫描回到屏幕左上方,同时进行场消隐,开始下一帧。VGA一直在扫描,每一场的扫描包括了若干行扫描,依次循环; +
-\\ +
-VGA显示时序如下: +
-{{ :​vga时序.png?​800 |}} +
-\\ +
-VGA显示区域和消隐区域: +
-{{ :​vga显示区域.png?​800 |}} +
-\\ +
-常见的VGA显示模式: +
-{{ :​常见的vga显示模式.png?​800 |}}+
  
 ====Verilog代码==== ====Verilog代码====
 +
 ------ ------
 <code verilog> <code verilog>
行 44: 行 33:
 // >>>>>>>>>>>>>>>>>>>>>>>>>​ COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<​ // >>>>>>>>>>>>>>>>>>>>>>>>>​ COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<​
 // -------------------------------------------------------------------- // --------------------------------------------------------------------
-// Module: ​Param_define+// Module: ​LCD_RGB
 //  // 
 // Author: Step // Author: Step
 //  // 
-// Description: ​Param_define+// Description: ​Drive TFT_RGB_LCD_1.8 to display
 //  // 
 // Web: www.stepfpga.com // Web: www.stepfpga.com
行 58: 行 47:
 // V1.1     ​|2016/​10/​30 ​  ​|Initial ver // V1.1     ​|2016/​10/​30 ​  ​|Initial ver
 // -------------------------------------------------------------------- // --------------------------------------------------------------------
-`timescale 1ns / 1ns +module ​LCD_RGB #
- +
-//​VGA显示器驱动只需要5个信号即可(行同步、场同步、红色、绿色、蓝色信号) +
-//​红绿蓝三色信号为模拟信号,输入电压范围为0.0V~0.7V +
-//​VGA时序中行同步和场同步都分为四个阶段(同步脉冲、后廊、有效线数、前廊) +
-//​VGA显示有很多模式,每种模式都是有固定的时钟和时序参数,需要根据要求控制 +
- +
-`ifdef VGA_800X600_60Hz //​不同VGA显示模式相应的参数 +
-//​--------------------------------------------------------------------------- +
-//-- Horizonal timing information +
-`define HSYNC_A ​  ​16'​d128 //​ 128 +
-`define HSYNC_B ​  ​16'​d216 //​ 128 + 88  +
-`define HSYNC_C ​  ​16'​d1016 //​ 128 + 88 + 800 +
-`define HSYNC_D ​  ​16'​d1056 //​ 128 + 88 + 800 + 40 //​行同步脉冲+后廊+有效线数+前廊 +
-//-- Vertical ​ timing information +
-`define VSYNC_O ​  ​16'​d4 //​ 4  +
-`define VSYNC_P ​  ​16'​d27 //​ 4 + 23 +
-`define VSYNC_Q ​  ​16'​d627 //​ 4 + 23 + 600 +
-`define VSYNC_R ​  ​16'​d628 //​ 4 + 23 + 600 + 1 //​场同步脉冲+后廊+有效线数+前廊 +
-//​--------------------------------------------------------------------------- +
-`endif +
- +
-`ifdef VGA_640X480_85Hz //​不同VGA显示模式相应的参数 +
-//​--------------------------------------------------------------------------- +
-//-- Horizonal timing information +
-`define HSYNC_A ​  ​16'​d48 //​ 48 +
-`define HSYNC_B ​  ​16'​d160 //​ 48 + 112 +
-`define HSYNC_C ​  ​16'​d800 //​ 48 + 112 + 640 +
-`define HSYNC_D ​  ​16'​d832 //​ 48 + 112 + 640 + 32 //​行同步脉冲+后廊+有效线数+前廊 +
-//-- Vertical ​ timing information +
-`define VSYNC_O ​  ​16'​d3 //​ 3  +
-`define VSYNC_P ​  ​16'​d28 //​ 3 + 25 +
-`define VSYNC_Q ​  ​16'​d508 //​ 3 + 25 + 480 +
-`define VSYNC_R ​  ​16'​d509 //​ 3 + 25 + 480 + 1 //​场同步脉冲+后廊+有效线数+前廊 +
-//​--------------------------------------------------------------------------- +
-`endif +
-</​code>​ +
- +
-<code verilog>​ +
-// -------------------------------------------------------------------- +
-// >>>>>>>>>>>>>>>>>>>>>>>>>​ COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<​ +
-// -------------------------------------------------------------------- +
-// Module: Vga_Module +
-//  +
-// Author: Step +
-//  +
-// Description:​ Vga_Module +
-//  +
-// Web: www.stepfpga.com +
-// +
-// -------------------------------------------------------------------- +
-// Code Revision History : +
-// -------------------------------------------------------------------- +
-// Version: |Mod. Date:   ​|Changes Made: +
-// V1.1     ​|2016/​10/​30 ​  ​|Initial ver +
-// -------------------------------------------------------------------- +
-`define VGA_800X600_60Hz //​定义使用的VGA显示模式 +
- +
-`ifdef VGA_800X600_60Hz //​根据VGA显示模式的定义调用相应的参数 +
-`include "​Param_define.v"​ //​调用Param_define.v文件中的全局定义 +
-`endif  +
- +
-module ​Vga_Module+
 ( (
-input  clk_in, //40MHz系统时钟 + parameter LCD_W = 8'​d132,​ //​液晶屏像素宽度 
-input  rst_n_in, //​系统复位,低有效 + parameter LCD_H = 8'​d162 //​液晶屏像素高度 
-output ​ reg sync_v, //VGA场同步sync_v +
-output ​ reg sync_h, //VGA行同步sync_h +
-output ​ reg [2:0] vga_data //VGA数据MSB~LSB = {R,G,B}+ input clk_in, //12MHz系统时钟 
 + input rst_n_in, //​系统复位,低有效 
 +  
 + output reg ram_lcd_clk_en, //RAM时钟使能 
 + output reg [7:​0] ram_lcd_addr, //RAM地址信号 
 + input [131:0] ram_lcd_data,​ //RAM数据信号 
 +  
 + output reg lcd_rst_n_out, //​LCD液晶屏复位 
 + output reg lcd_bl_out, //​LCD背光控制 
 + output reg lcd_dc_out,​ //​LCD数据指令控制 
 + output reg lcd_clk_out,​ //​LCD时钟信号 
 + output reg lcd_data_out //​LCD数据信号
 ); );
- 
-reg [15:0] x_cnt; 
-reg [15:0] y_cnt; 
-reg vga_valid;​  
   
-//对时钟计标识VGA一次行扫描需要时间 + localparam INIT_DEPTH = 16'​d73; ​//LCD初始化的命令及数量 
-always @ (posedge clk_in or negedge rst_n_in) +  
- if(!rst_n_in) x_cnt <= 16'​d0;​ //​复位时初始值 + localparam RED = 16'​hf800;​ //​红色 
- else if(x_cnt >= `HSYNC_D) x_cnt <= 16'​d0;​ //​一次行扫描需要1056个时钟(128+88+800+40) + localparam GREEN = 16'​h07e0;​ //​绿色 
- else x_cnt <= x_cnt + 1'​b1;​ + localparam BLUE = 16'​h001f;​ //​蓝色 
- + localparam BLACK = 16'​h0000;​ //​黑色 
-//对行扫描计数标识VGA一次场扫描需要的时间 + localparam WHITE = 16'​hffff;​ //​白色 
-always @ (posedge clk_in or negedge rst_n_in+ localparam YELLOW = 16'​hffe0;​ //​黄色 
- if(!rst_n_in) y_cnt <= 16'd0;​ //​复位时初始值 +  
- else if(x_cnt ​== `HSYNC_D) ​begin //每次行扫描时 + localparam IDLE = 3'​d0;​ 
- if(y_cnt >= `VSYNC_Ry_cnt <= 16'​d0;​ //​每次场扫描包含628次行扫描 + localparam MAIN = 3'​d1;​ 
- else y_cnt <= y_cnt + 1'​b1;​ + localparam INIT = 3'​d2;​ 
- end else y_cnt <= y_cnt; //在每次行扫描过程中场扫描计数器保持不变 + localparam SCAN = 3'​d3;​ 
- + localparam WRITE = 3'​d4;​ 
-//按照显示模式的参产生行同步扫描的脉冲 + localparam DELAY = 3'​d5;​ 
-always @ (posedge clk_in or negedge rst_n_in+  
- if(!rst_n_insync_h ​<= 1'​b1;​ + localparam LOW = 1'​b0;​ 
- else if(x_cnt ​`HSYNC_A) sync_h ​<= 1'b0;  + localparam HIGH = 1'​b1;​ 
- else sync_h ​<= 1'​b1;​  +  
- + //​assign lcd_bl_out = HIGH; // backlight active high level 
-//按照显示模式的参产生场步扫描脉冲 +  
-always @ (posedge clk_in or negedge rst_n_in) + wire [15:​0] color_t = YELLOW;​ //​顶层色为黄色 
- if(!rst_n_insync_v ​<= 1'b1+ wire [15:​0] color_b = BLACK;​ //​背景色为黑色 
- else if(y_cnt ​< `VSYNC_Osync_v ​<= 1'b0+  
- else sync_v ​<= 1'​b1;​  + reg [7:​0] x_cnt;​ 
- + reg [7:​0] y_cnt;​ 
-//根据行场同步信号有效线数确有效显示区域 + reg [131:​0] ram_data_r;​ 
-always @ (posedge clk_in or negedge rst_n_in+  
- if(!rst_n_in) ​ + reg [8:​0] data_reg;​ //​ 
- vga_valid ​<= 1'​b0;​ + reg [8:​0] reg_setxy [10:​0];​ 
- else if((x_cnt ​`HSYNC_B&& (x_cnt ​<`HSYNC_C) && (y_cnt > `VSYNC_P) && (y_cnt < `VSYNC_Q)) + reg [8:​0] reg_init [72:​0];​ 
- vga_valid ​<= 1'b1; //有效显示区域中vga_valid标志1 + reg [2:​0] cnt_main;​ 
- else + reg [2:​0] cnt_init;​ 
- vga_valid ​<= 1'b0;  + reg [2:​0] cnt_scan;​ 
- + reg [5:​0] cnt_write;​ 
-//在VGA有效显示区域不同的段显示不同的颜色 + reg [15:​0] cnt_delay;​ 
-always @ (posedge clk_in or negedge rst_n_in) + reg [15:​0] num_delay;​ 
-begin + reg [15:​0] cnt;​ 
- if(!rst_n_invga_data ​3'b111+ reg high_word;​ 
- else if(vga_valid)begin //在有效显示区域 + reg [2:​0] state = IDLE; 
- if((x_cnt > `HSYNC_B) && (x_cnt <`HSYNC_B + 10'd100))  + reg [2:​0] state_back = IDLE; 
- vga_data ​= 3'b100; //红色 + always@(posedge clk_in or negedge rst_n_in) ​begin 
- else if((x_cnt > `HSYNC_B + 10'd100) && (x_cnt <`HSYNC_B + 10'd200))  + if(!rst_n_in) ​begin 
- vga_data ​3'b010; //绿色 + x_cnt <= 8'​d0;​ 
- else if((x_cnt > `HSYNC_B + 10'd200) && (x_cnt <`HSYNC_B + 10'd300))  + y_cnt <= 8'​d0;​ 
- vga_data ​= 3'b001; //蓝色 + ram_lcd_clk_en <= 1'​b0;​ 
- else if((x_cnt > `HSYNC_B + 10'd300) && (x_cnt <`HSYNC_B + 10'd400))  + ram_lcd_addr <= 8'​d0;​ 
- vga_data ​3'b110; //黄色 + cnt_main <= 3'​d0;​ 
- else if((x_cnt > `HSYNC_B + 10'd400) && (x_cnt <`HSYNC_B + 10'd500))  + cnt_init <= 3'​d0;​ 
- vga_data ​3'b101; //紫色 + cnt_scan <= 3'​d0;​ 
- else if((x_cnt > `HSYNC_B + 10'd500) && (x_cnt <`HSYNC_B + 10'd600))  + cnt_write <= 6'​d0;​ 
- vga_data ​3'b011; //青色 + cnt_delay ​<= 16'​d0;​ 
- else if((x_cnt > `HSYNC_B + 10'd600) && (x_cnt <`HSYNC_B + 10'd700))  + num_delay <= 16'​d50;​ 
- vga_data ​3'b111; //白色 + cnt <= 16'​d0;​ 
- else if((x_cnt > `HSYNC_B + 10'd700) && (x_cnt <`HSYNC_B + 10'd800))  + high_word <= 1'​b1;​ 
- vga_data ​3'b000; //黑色 + lcd_bl_out <= LOW; 
- else + state <= IDLE; 
- vga_data ​3'b111; //白色 + state_back <= IDLE; 
- end else + end else begin 
- vga_data ​3'b111; //白色 + case(state) 
-end + IDLE:​begin 
 + x_cnt <= 8'​d0;​ 
 + y_cnt <= 8'​d0;​ 
 + ram_lcd_clk_en <= 1'​b0;​ 
 + ram_lcd_addr <= 8'​d0;​ 
 + cnt_main <= 3'​d0;​ 
 + cnt_init <= 3'​d0;​ 
 + cnt_scan <= 3'​d0;​ 
 + cnt_write <= 6'​d0;​ 
 + cnt_delay ​<= 16'd0; 
 + num_delay <= 16'​d50;​ 
 + cnt <= 16'​d0;​ 
 + high_word <= 1'​b1;​ 
 + state <= MAIN; 
 + state_back <= MAIN; 
 + end 
 + MAIN:​begin 
 + case(cnt_main) //MAIN状态 
 + 3'​d0:​ begin state <= INIT; cnt_main <= cnt_main ​1'b1; end 
 + 3'​d1:​ begin state <= SCAN; cnt_main <= cnt_main ​+ 1'​b1; ​end 
 + 3'​d2:​ begin cnt_main <= 1'b1; end 
 + default:​ state <= IDLE; 
 + endcase 
 + end 
 + INIT:​begin //初始化状态 
 + case(cnt_init
 + 3'​d0:​ begin lcd_rst_n_out ​<= 1'b0cnt_init <= cnt_init + 1'b1; end //复位有效 
 + 3'​d1:​ begin num_delay <= 16'​d3000;​ state <= DELAY; state_back <= INIT; cnt_init <= cnt_init + 1'b1; end //延时 
 + 3'​d2:​ begin lcd_rst_n_out <1'b1; cnt_init <cnt_init + 1'b1; end //​复位恢复 
 + 3'​d3:​ begin num_delay <= 16'​d3000;​ state <= DELAY; state_back <= INIT; cnt_init <= cnt_init + 1'b1; end //时 
 + 3'​d4:​ begin  
 + if(cnt>=INIT_DEPTHbegin //​当73条指令及数据发出后,配置完成 
 + cnt ​<= 16'​d0;​ 
 + cnt_init ​<= cnt_init ​+ 1'​b1;​ 
 + end else begin 
 + data_reg ​<= reg_init[cnt];​  
 + if(cnt==16'​d0) num_delay <= 16'​d50000; //第一条指令需要较长延时 
 + else num_delay <= 16'​d50;​ 
 + cnt <= cnt + 16'​d1;​ 
 + state <= WRITE; 
 + state_back <= INIT; 
 + end 
 + end 
 + 3'​d5:​ begin cnt_init <= 1'b0; state <= MAIN; end //初始化完成,返回MAIN状态 
 + default:​ state <= IDLE; 
 + endcase 
 + end 
 + SCAN:​begin //​刷屏状态,从RAM中读取据刷屏 
 + case(cnt_scan
 + 3'​d0:​ begin //​确定刷屏的区域坐标,这里为全屏 
 + if(cnt >= 11begin // 
 + cnt ​<= 16'​d0;​ 
 + cnt_scan <= cnt_scan + 1'​b1;​ 
 + end ​else begin 
 + data_reg ​<= reg_setxy[cnt];​ 
 + cnt ​<= cnt + 16'​d1;​ 
 + num_delay <= 16'​d50;​ 
 + state <= WRITE; 
 + state_back <= SCAN; 
 + end 
 + end 
 + 3'​d1:​ begin ram_lcd_clk_en <= HIGH; ram_lcd_addr <= y_cnt; cnt_scan <= cnt_scan + 1'b1end //​RAM时钟使能 
 + 3'​d2:​ begin cnt_scan ​<= cnt_scan + 1'​b1; ​end //​延时一个时钟 
 + 3'​d3:​ begin ram_lcd_clk_en <= LOW; ram_data_r <= ram_lcd_data;​ cnt_scan <= cnt_scan + 1'b1; end //读取RAM据,时关闭RAM时钟使能 
 + 3'​d4:​ begin //​每个像素点需要16bit数据,SPI每次传8bit,两次分别传送高8位和低8位 
 + if(x_cnt>​=LCD_Wbegin //​当一个数据(一行屏幕)写完后, 
 + x_cnt ​<= 8'd0;  
 + if(y_cnt>=LCD_Hbegin y_cnt <= 8'd0; cnt_scan <= cnt_scan + 1'b1end //​如果是最后一行就跳出循环 
 + else begin y_cnt <= y_cnt + 1'​b1; ​cnt_scan <= 3'd1; end //​否则跳转至RAM时钟使能,循环刷屏 
 + end else begin 
 + if(high_word) data_reg <= {1'​b1,​(ram_data_r[x_cnt]?​ color_t[15:​8]:​color_b[15:​8])};​ //根据相应bit状态判定显示顶层色或背景色,​根据high_word的状态判定写高8位或低8位 
 + else begin data_reg <= {1'b1,(ram_data_r[x_cnt]?​ color_t[7:​0]:​color_b[7:​0])}; x_cnt <= x_cnt + 1'b1; end //​根据相应bit的状态判定显示顶层色或背景色,​根据high_word的状态判定写高8位或低8位,同时指向下一个bit 
 + high_word <= ~high_word;​ //​high_word的状态翻转 
 + num_delay <= 16'​d50;​ //​设定延时时间 
 + state <= WRITE;​ //​跳转至WRITE状态 
 + state_back <= SCAN;​ //​执行完WRITE及DELAY操作后返回SCAN状态 
 + end 
 + end 
 + 3'​d5:​ begin cnt_scan ​<= 1'​b0; ​lcd_bl_out <= HIGH; state <= MAIN; end 
 + default:​ state <= IDLE; 
 + endcase 
 + end 
 + WRITE:​begin //​WRITE状态,将数据按照SPI时序发送给屏幕 
 + if(cnt_write ​>= 6'd17cnt_write ​<= 1'b0; 
 + else cnt_write ​<= cnt_write + 1'b1; 
 + case(cnt_write) 
 + 6'​d0:​ begin lcd_dc_out <= data_reg[8];​ end //9位数据最高位命令数据控制位 
 + 6'​d1:​ begin lcd_clk_out <= LOW; lcd_data_out <= data_reg[7];​ end //​先发高位数据 
 + 6'​d2:​ begin lcd_clk_out ​<= HIGH; end 
 + 6'​d3:​ begin lcd_clk_out <= LOW; lcd_data_out <= data_reg[6];​ end 
 + 6'​d4:​ begin lcd_clk_out <= HIGH; end 
 + 6'​d5:​ begin lcd_clk_out <= LOW; lcd_data_out <= data_reg[5];​ end 
 + 6'​d6:​ begin lcd_clk_out <= HIGH; end 
 + 6'​d7:​ begin lcd_clk_out <= LOW; lcd_data_out <= data_reg[4];​ end 
 + 6'​d8:​ begin lcd_clk_out <= HIGH; end 
 + 6'​d9:​ begin lcd_clk_out <= LOW; lcd_data_out <= data_reg[3];​ end 
 + 6'​d10:​ begin lcd_clk_out <= HIGH; end 
 + 6'​d11:​ begin lcd_clk_out <= LOW; lcd_data_out <= data_reg[2];​ end 
 + 6'​d12:​ begin lcd_clk_out <= HIGH; end 
 + 6'​d13:​ begin lcd_clk_out <= LOW; lcd_data_out <= data_reg[1]; end 
 + 6'd14: begin lcd_clk_out <= HIGHend 
 + 6'​d15:​ begin lcd_clk_out <= LOW; lcd_data_out <= data_reg[0];​ end //​后发低位数据 
 + 6'​d16:​ begin lcd_clk_out <= HIGH; end 
 + 6'​d17:​ begin lcd_clk_out <= LOW; state <= DELAY; end // 
 + default:​ state <= IDLE; 
 + endcase 
 + end 
 + DELAY:begin //​延时状态 
 + if(cnt_delay >= num_delaybegin 
 + cnt_delay <16'd0
 + state <= state_back;  
 + end ​else cnt_delay <= cnt_delay + 1'​b1;​ 
 + end 
 + default:​state <= IDLE; 
 + endcase 
 + end 
 + end 
 +  
 + // data for setxy 
 + initial //​设定显示区域指令及数据 
 + begin 
 + reg_setxy[0] = {1'b0,​8'​h2a};​ 
 + reg_setxy[1] = {1'​b1,​8'​h00};​ 
 + reg_setxy[2] = {1'​b1,​8'​h00};​ 
 + reg_setxy[3] = {1'b1,​8'​h00}; 
 + reg_setxy[4] = {1'​b1,​LCD_W-1};​ 
 + reg_setxy[5] = {1'b0,​8'​h2b};​ 
 + reg_setxy[6] = {1'b1,​8'​h00};​ 
 + reg_setxy[7] = {1'b1,​8'​h00}; 
 + reg_setxy[8] = {1'​b1,​8'​h00};​ 
 + reg_setxy[9] = {1'​b1,​LCD_H-1};​ 
 + reg_setxy[10] = {1'​b0,​8'​h2c};​ 
 + end 
 +  
 + // data for init 
 + initial //​LCD初始化的命令及数据 
 + begin 
 + reg_init[0] = {1'b0,​8'​h11};​  
 + reg_init[1] = {1'b0,​8'​hb1}; ​ 
 + reg_init[2] = {1'​b1,​8'​h05};​  
 + reg_init[3] = {1'​b1,​8'h3c} 
 + reg_init[4] = {1'​b1,​8'​h3c}; ​ 
 + reg_init[5] = {1'b0,​8'​hb2};​  
 + reg_init[6] = {1'b1,​8'​h05}; ​ 
 + reg_init[7] = {1'​b1,​8'h3c} 
 + reg_init[8] = {1'​b1,​8'​h3c}; ​ 
 + reg_init[9] = {1'​b0,​8'​hb3};​  
 + reg_init[10] = {1'b1,​8'​h05};​  
 + reg_init[11] = {1'b1,​8'​h3c}; ​ 
 + reg_init[12] = {1'b1,​8'​h3c} 
 + reg_init[13] = {1'​b1,​8'​h05}; ​ 
 + reg_init[14] = {1'b1,​8'​h3c};​  
 + reg_init[15] = {1'b1,​8'​h3c}; ​ 
 + reg_init[16] = {1'b0,​8'​hb4} 
 + reg_init[17] = {1'​b1,​8'​h03}; ​ 
 + reg_init[18] = {1'b0,​8'​hc0};​  
 + reg_init[19] = {1'b1,​8'​h28}; ​ 
 + reg_init[20] = {1'​b1,​8'h08} 
 + reg_init[21] = {1'​b1,​8'​h04}; ​ 
 + reg_init[22] = {1'b0,​8'​hc1};​  
 + reg_init[23] = {1'b1,​8'​hc0}; ​ 
 + reg_init[24] = {1'​b0,​8'hc2} 
 + reg_init[25] = {1'​b1,​8'​h0d}; ​ 
 + reg_init[26] = {1'​b1,​8'​h00}; ​ 
 + reg_init[27] = {1'​b0,​8'hc3} 
 + reg_init[28] = {1'​b1,​8'​h8d}; ​ 
 + reg_init[29] = {1'​b1,​8'​h2a}; ​ 
 + reg_init[30] = {1'​b0,​8'hc4};  
 + reg_init[31] = {1'​b1,​8'​h8d};​  
 + reg_init[32] = {1'​b1,​8'​hee};​  
 + reg_init[32] = {1'​b0,​8'​hc5};​  
 + reg_init[33] = {1'​b1,​8'​h1a};​  
 + reg_init[34] = {1'​b0,​8'​h36};​  
 + reg_init[35] = {1'​b1,​8'​hc0};​  
 + reg_init[36] = {1'​b0,​8'​he0};​  
 + reg_init[37] = {1'​b1,​8'​h04};​  
 + reg_init[38] = {1'​b1,​8'​h22};​  
 + reg_init[39] = {1'​b1,​8'​h07};​  
 + reg_init[40] = {1'​b1,​8'​h0a};​  
 + reg_init[41] = {1'​b1,​8'​h2e};​  
 + reg_init[42] = {1'​b1,​8'​h30};​  
 + reg_init[43] = {1'​b1,​8'​h25};​  
 + reg_init[44] = {1'​b1,​8'​h2a};​  
 + reg_init[45] = {1'​b1,​8'​h28};​  
 + reg_init[46] = {1'​b1,​8'​h26};​  
 + reg_init[47] = {1'​b1,​8'​h2e};​  
 + reg_init[48] = {1'​b1,​8'​h3a};​  
 + reg_init[49] = {1'​b1,​8'​h00};​  
 + reg_init[50] = {1'​b1,​8'​h01};​  
 + reg_init[51] = {1'​b1,​8'​h03};​  
 + reg_init[52] = {1'​b1,​8'​h13};​  
 + reg_init[53] = {1'​b0,​8'​he1};​  
 + reg_init[54] = {1'​b1,​8'​h04};​  
 + reg_init[55] = {1'​b1,​8'​h16};​  
 + reg_init[56] = {1'​b1,​8'​h06};​  
 + reg_init[57] = {1'​b1,​8'​h0d};​  
 + reg_init[58] = {1'​b1,​8'​h2d};​  
 + reg_init[59] = {1'​b1,​8'​h26};​  
 + reg_init[60] = {1'​b1,​8'​h23};​  
 + reg_init[61] = {1'​b1,​8'​h27};​  
 + reg_init[62] = {1'​b1,​8'​h27};​  
 + reg_init[63] = {1'​b1,​8'​h25};​  
 + reg_init[64] = {1'​b1,​8'​h2d};​  
 + reg_init[65] = {1'​b1,​8'​h3b};​  
 + reg_init[66] = {1'​b1,​8'​h00};​  
 + reg_init[67] = {1'​b1,​8'​h01};​  
 + reg_init[68] = {1'​b1,​8'​h04};​  
 + reg_init[69] = {1'​b1,​8'​h13};​  
 + reg_init[70] = {1'​b0,​8'​h3a};​  
 + reg_init[71] = {1'​b1,​8'​h05};​  
 + reg_init[72] = {1'​b0,​8'​h29};​  
 +  
 + end 
 +
 endmodule endmodule
 </​code>​ </​code>​
 +
 ====小结==== ====小结====
 +
 ------ ------
-本节主要为大家讲解了VGA显示的原理、时序及软件设计,需要大家掌握的同时自己创建工程,通过整个设计流程,生成FPGA配置文件加载测试。+本节主要为大家讲解了1.8寸RGB液晶屏图片显示的框架,需要大家掌握的同时自己创建工程,通过整个设计流程,生成FPGA配置文件加载测试。
 \\ \\
 如果你对Diamond软件的使用不了解,请参考这里:[[lattice_diamond的使用|Diamond的使用]]。 如果你对Diamond软件的使用不了解,请参考这里:[[lattice_diamond的使用|Diamond的使用]]。
  
 ====相关资料==== ====相关资料====
 +
 ------ ------
 \\ \\
-使用[[STEP-MXO2第二代]]的VGA显示驱动程序: ​ 后续会有下载连接 ​ 待更新+使用[[STEP-MXO2第二代]]的1.8寸RGB液晶屏显示驱动程序: ​ 后续会有下载连接 ​ 待更新
 \\ \\
-使用[[STEP-MAX10]]的VGA显示驱动程序: ​ 后续会有下载连接 ​ 待更新+使用[[STEP-MAX10]]的1.8寸RGB液晶屏显示驱动程序: ​ 后续会有下载连接 ​ 待更新
 \\ \\