Tiny ZYNQ板 工程二十二 基于PL的RGB888屏幕调试(配置由PS I2C完成)

本文对手上的4寸 RGB888屏程序进行调试,为了快速验证屏幕是否工作,这里先用PS的硬件I2C功能对屏幕进行初始化(以后会用PL重写配置部分)

如题,本次用的屏幕是 RGB+I2C屏,也就是屏幕可以通过I2C来进行初始化,初始化完成后通过RGB信号(RGB888,HSYNC VSYNC PCLK DE)来对屏幕持续性的输出图像数据。

对于其他的RGB屏其实也都大同小异,可以参考本工程来进行修改,(大部分是 SPI+RGB, 因为排针接口有限,所以这里我把屏幕硬件上配置成了 I2C+RGB,I2C和触摸屏的I2C共用信号线)

屏幕为NT35510屏 (可以设置成80端口 或者MIPI 端口,这里仅演示用RGB端口去驱动)

创建Vivado工程

1)具体步骤 新建一个VIVADO 工程,打开软件 选中Create Project, 如下图所示

2)点击NEXT ,在出现的第二个对话框“Project name”中输入工程名;在“Project location”中选择保存路径;勾选“Create project subdirectory”,最后点击“Next” 备注,所有的路径均不能出现中文名称

3)点击 RTL PROJECT 选项,点击NEXT

4) 第四步Add Sources 选项直接留空,NEXT

5)第五步Add Constraints 选项直接留空,NEXT

6)选择芯片型号 我们板子上用的芯片是XC7Z010 ,并在列表栏中选择对应的封装型号,完整型号是XC7Z010CLG400-1 如下所示,选中后点NEXT

7)确认所选信息 点击“Finish”,完成vivado的工程创建

创建一个BLOCK设计

1)IP INTEGRATOR→Create Block Design,在弹出的对话框中输入设计名,最后点击“OK”,如下图所示

2)在右侧的窗口里 ,点击加号,在选择框里搜索ZYNQ,并找到ZYNQ7 PROCESSING SYSTEM ,双击并打开

3)软件自动生成了一个 zynq的block 如下图所示,接下来要做一些相应的设置,双击下图中的ZYNQ核

4)依次在弹窗里找到DDR Configuration→DDR Controller Configuration→DDR3,在Memory Part下拉菜单中根据自己板子上的DDR来选择相应的DDR3,本实验所用到型号:MT41K128M16JT 125,数据位宽选择16bit 最后点击“OK”,如下图所示。

5)在PS的MIO配置选项的GPIO栏里,增加两路EMIO(因为本次除了I2C去配置屏幕外,还需要两路IO分别去控制RST信号和BL背光信号)

6)并且增加一路I2C资源,选EMIO方式(因为板子上所有的排针都是接在PL端的)

7)点击“Run Block Automation”如下图所示。在弹出的选项中保持默认,点击“OK”,即可完成对ZYNQ7 Processing System的配置

8)将刚才添加EMIO GPIO 引出 右键GPIO_0—->Make External

9)用同样的方法将EMIO I2C引出,右键 IIC_0 点选Make External

10)用线将M_AXI_GP0_ACLK与 FCLK_CLK0连接起来(如果嫌麻烦在配置页也可以将AXI功能关闭,这里没有用到AXI功能)

11)source→Design Source ,右键我们创建的BLOCK工程,点击create HDL wrapper如下图所示。

在弹出的对话框里保持默认

软件自动为我们生成HDL文件

创建工程PL的 RGB的VERILOG部分

RGB的工程其实之前有写过,Tiny ZYNQ板 工程五  基于ZYNQ PL资源的HDMI功能演示

这里我们把HDMI工程的 RGB部分搬过来并作简单修改。

1)首先我们先用锁相环创建一个33M的时钟(为什么是33M ,因为800X480的屏幕在60hz左右的时钟就是33M)

点击IP Catalog 打开模块选择器, 在里面的搜索栏输入 CLOCKING ,系统会自动跳出符合的 Clocking Wizard选项,双击它

2)在弹出的窗口中我们将input Frequence 输入频率修改为板子上焊接的50M时钟, 右边改为单端输入

3)在output Clocks选项中 将clk_out1改成33m

4)将界面托到最下面,因为我们这里的要求并不高,所以把时钟的复位reset,和locked选项去除,最后点击ok生成模块

之后点选OK完成创建

增加我们的VERILOG代码内容

1)这里创建一个显示模块显示模块负责输出标准的RGB时序,这里对HDMI工程中的RGB部分作了修改,调整了480X800的时序,以及增加了多种显示效果切换的部分,让显示结果更为丰富,具体如下( color_bar.v)

module COLOR_BAR(
	input                 clk,           //pixel clock
	input                 rst,           //reset signal high active
	output                hs,            //horizontal synchronization
	output                vs,            //vertical synchronization
	output                de,            //video valid
	output[7:0]           rgb_r,         //video red data
	output[7:0]           rgb_g,         //video green data
	output[7:0]           rgb_b          //video blue data
);
 
`define VIDEO_480_800
//800x480 33Mhz
`ifdef  VIDEO_480_800
parameter H_ACTIVE = 16'd480; 
parameter H_FP = 16'd1;      
parameter H_SYNC = 16'd3;   
parameter H_BP = 16'd160;      
parameter V_ACTIVE = 16'd800; 
parameter V_FP  = 16'd40;     
parameter V_SYNC  = 16'd128;    
parameter V_BP  = 16'd88;    
parameter HS_POL = 1'b0;
parameter VS_POL = 1'b0;
`endif


parameter H_TOTAL = H_ACTIVE + H_FP + H_SYNC + H_BP;//horizontal total time (pixels)
parameter V_TOTAL = V_ACTIVE + V_FP + V_SYNC + V_BP;//vertical total time (lines)
//define the RGB values for 8 colors
parameter WHITE_R       = 8'hff;
parameter WHITE_G       = 8'hff;
parameter WHITE_B       = 8'hff;
parameter YELLOW_R      = 8'hff;
parameter YELLOW_G      = 8'hff;
parameter YELLOW_B      = 8'h00;                                
parameter CYAN_R        = 8'h00;
parameter CYAN_G        = 8'hff;
parameter CYAN_B        = 8'hff;                                
parameter GREEN_R       = 8'h00;
parameter GREEN_G       = 8'hff;
parameter GREEN_B       = 8'h00;
parameter MAGENTA_R     = 8'hff;
parameter MAGENTA_G     = 8'h00;
parameter MAGENTA_B     = 8'hff;
parameter RED_R         = 8'hff;
parameter RED_G         = 8'h00;
parameter RED_B         = 8'h00;
parameter BLUE_R        = 8'h00;
parameter BLUE_G        = 8'h00;
parameter BLUE_B        = 8'hff;
parameter BLACK_R       = 8'h00;
parameter BLACK_G       = 8'h00;
parameter BLACK_B       = 8'h00;
reg hs_reg;                      //horizontal sync register
reg vs_reg;                      //vertical sync register
reg hs_reg_d0;                   //delay 1 clock of 'hs_reg'
reg vs_reg_d0;                   //delay 1 clock of 'vs_reg'
reg[11:0] h_cnt;                 //horizontal counter
reg[11:0] v_cnt;                 //vertical counter
reg[11:0] active_x;              //video x position 
reg[11:0] active_y;              //video y position 
reg[7:0] rgb_r_reg;              //video red data register
reg[7:0] rgb_g_reg;              //video green data register
reg[7:0] rgb_b_reg;              //video blue data register
reg h_active;                    //horizontal video active
reg v_active;                    //vertical video active
wire video_active;               //video active(horizontal active and vertical active)
reg video_active_d0;             //delay 1 clock of video_active
assign hs = hs_reg_d0;
assign vs = vs_reg_d0;
assign video_active = h_active & v_active;
assign de = video_active_d0;
assign rgb_r = rgb_r_reg;
assign rgb_g = rgb_g_reg;
assign rgb_b = rgb_b_reg;
always@(posedge clk or posedge rst)
begin
	if(rst == 1'b1)
		begin
			hs_reg_d0 <= 1'b0;
			vs_reg_d0 <= 1'b0;
			video_active_d0 <= 1'b0;
		end
	else
		begin
			hs_reg_d0 <= hs_reg;
			vs_reg_d0 <= vs_reg;
			video_active_d0 <= video_active;
		end
end
 
always@(posedge clk or posedge rst)
begin
	if(rst == 1'b1)
		h_cnt <= 12'd0;
	else if(h_cnt == H_TOTAL - 1)//horizontal counter maximum value
		h_cnt <= 12'd0;
	else
		h_cnt <= h_cnt + 12'd1;
end
 
always@(posedge clk or posedge rst)
begin
	if(rst == 1'b1)
		active_x <= 12'd0;
	else if(h_cnt >= H_FP + H_SYNC + H_BP - 1)//horizontal video active
		active_x <= h_cnt - (H_FP[11:0] + H_SYNC[11:0] + H_BP[11:0] - 12'd1);
	else
		active_x <= active_x;
end
 
always@(posedge clk or posedge rst)
begin
	if(rst == 1'b1)
		v_cnt <= 12'd0;
	else if(h_cnt == H_FP  - 1)//horizontal sync time
		if(v_cnt == V_TOTAL - 1)//vertical counter maximum value
			v_cnt <= 12'd0;
		else
			v_cnt <= v_cnt + 12'd1;
	else
		v_cnt <= v_cnt;
end
 
always@(posedge clk or posedge rst)
begin
	if(rst == 1'b1)
		hs_reg <= 1'b0;
	else if(h_cnt == H_FP - 1)//horizontal sync begin
		hs_reg <= HS_POL;
	else if(h_cnt == H_FP + H_SYNC - 1)//horizontal sync end
		hs_reg <= ~hs_reg;
	else
		hs_reg <= hs_reg;
end
 
always@(posedge clk or posedge rst)
begin
	if(rst == 1'b1)
		h_active <= 1'b0;
	else if(h_cnt == H_FP + H_SYNC + H_BP - 1)//horizontal active begin
		h_active <= 1'b1;
	else if(h_cnt == H_TOTAL - 1)//horizontal active end
		h_active <= 1'b0;
	else
		h_active <= h_active;
end
 
always@(posedge clk or posedge rst)
begin
	if(rst == 1'b1)
		vs_reg <= 1'd0;
	else if((v_cnt == V_FP - 1) && (h_cnt == H_FP - 1))//vertical sync begin
		vs_reg <= HS_POL;
	else if((v_cnt == V_FP + V_SYNC - 1) && (h_cnt == H_FP - 1))//vertical sync end
		vs_reg <= ~vs_reg;  
	else
		vs_reg <= vs_reg;
end
 
always@(posedge clk or posedge rst)
begin
	if(rst == 1'b1)
		v_active <= 1'd0;
	else if((v_cnt == V_FP + V_SYNC + V_BP - 1) && (h_cnt == H_FP - 1))//vertical active begin
		v_active <= 1'b1;
	else if((v_cnt == V_TOTAL - 1) && (h_cnt == H_FP - 1)) //vertical active end
		v_active <= 1'b0;   
	else
		v_active <= v_active;
end


reg [3:0]mode=4'd0;
parameter T1MS = 26'd60_000_000 ; 
reg [25:0]time_count;//时钟计数器
always@(posedge clk)
 if(time_count>=T1MS)begin
     time_count<=26'd0;
     if(mode<8)mode<=mode+1'b1;
     else mode<=4'd0;
 end
 else time_count<=time_count+1'b1;



 
always@(posedge clk or posedge rst)
begin
	if(rst == 1'b1)
		begin
			rgb_r_reg <= 8'h00;
			rgb_g_reg <= 8'h00;
			rgb_b_reg <= 8'h00;
		end
	else if(video_active)begin
	   if(mode==0)begin
		  if(active_x == 12'd0)
			begin
				rgb_r_reg <= WHITE_R;
				rgb_g_reg <= WHITE_G;
				rgb_b_reg <= WHITE_B;
			end
		else if(active_x == (H_ACTIVE/8) * 1)
			begin
				rgb_r_reg <= YELLOW_R;
				rgb_g_reg <= YELLOW_G;
				rgb_b_reg <= YELLOW_B;
			end         
		else if(active_x == (H_ACTIVE/8) * 2)
			begin
				rgb_r_reg <= CYAN_R;
				rgb_g_reg <= CYAN_G;
				rgb_b_reg <= CYAN_B;
			end
		else if(active_x == (H_ACTIVE/8) * 3)
			begin
				rgb_r_reg <= GREEN_R;
				rgb_g_reg <= GREEN_G;
				rgb_b_reg <= GREEN_B;
			end
		else if(active_x == (H_ACTIVE/8) * 4)
			begin
				rgb_r_reg <= MAGENTA_R;
				rgb_g_reg <= MAGENTA_G;
				rgb_b_reg <= MAGENTA_B;
			end
		else if(active_x == (H_ACTIVE/8) * 5)
			begin
				rgb_r_reg <= RED_R;
				rgb_g_reg <= RED_G;
				rgb_b_reg <= RED_B;
			end
		else if(active_x == (H_ACTIVE/8) * 6)
			begin
				rgb_r_reg <= BLUE_R;
				rgb_g_reg <= BLUE_G;
				rgb_b_reg <= BLUE_B;
			end 
		else if(active_x == (H_ACTIVE/8) * 7)
			begin
				rgb_r_reg <= BLACK_R;
				rgb_g_reg <= BLACK_G;
				rgb_b_reg <= BLACK_B;
			end
		else
			begin
				rgb_r_reg <= rgb_r_reg;
				rgb_g_reg <= rgb_g_reg;
				rgb_b_reg <= rgb_b_reg;
			end   
       end
       else if(mode==1)begin
          	rgb_r_reg <= active_x[7:0];
			rgb_g_reg <= 8'h00;
			rgb_b_reg <= 8'h00;
       end
       else if(mode==2)begin
          	rgb_r_reg <=8'h00 ;
			rgb_g_reg <=  active_x[7:0];
			rgb_b_reg <= 8'h00;
       end
       else if(mode==3)begin
          	rgb_r_reg <=8'h00 ;
			rgb_g_reg <=8'h00;
			rgb_b_reg <= active_x[7:0];
       end
       else if(mode==4)begin
          	rgb_r_reg <=active_x[7:0];
			rgb_g_reg <=active_x[7:0];
			rgb_b_reg <=active_x[7:0];
       end
       else if(mode==5)begin
          	rgb_r_reg <=8'hff;
			rgb_g_reg <=8'hff;
			rgb_b_reg <=8'hff;
       end
      else if(mode==6)begin
          	rgb_r_reg <=8'hff;
			rgb_g_reg <=8'h00;
			rgb_b_reg <=8'h00;
       end
       else if(mode==7)begin
          	rgb_r_reg <=8'h00;
			rgb_g_reg <=8'hff;
			rgb_b_reg <=8'h00;
       end
       else if(mode==8)begin
          	rgb_r_reg <=8'h00;
			rgb_g_reg <=8'h00;
			rgb_b_reg <=8'hff;
       end
		else begin
			rgb_r_reg <= 8'h00;
			rgb_g_reg <= 8'h00;
			rgb_b_reg <= 8'h00;
		end
    end
end
 
endmodule

其中 以下代码用来每两秒钟切换一次显示模式,而不同的mode 分别对应上面代码中不同颜色画面的显示。也就是系统每两秒切换一次模式 ,一共有8种模式

reg [3:0]mode=4'd0;
parameter T1MS = 26'd66_000_000 ;
reg [25:0]time_count;
always@(posedge clk)
 if(time_count>=T1MS)begin
     time_count<=26'd0;
     if(mode<8)mode<=mode+1'b1;
     else mode<=4'd0;
 end
 else time_count<=time_count+1'b1;

2)创建一个顶层模块,分别调用时钟、ZYNQ核 以及彩条纹显示模块(top.v)

`timescale 1ns / 1ps
module LCD_MODULE(
    input CLK,
    output [7:0]LCD_R,
    output [7:0]LCD_G,
    output [7:0]LCD_B,
    output LCD_HSYNC,
    output LCD_VSYNC,
    output LCD_PCLK,
    output LCD_DE, 
    inout  LCD_RST,
    inout  LCD_I2C_SCL,
    inout  LCD_I2C_SDA,
    inout  BL
);


wire clk_33m;
clk_wiz_0 u2(
    .clk_in1(CLK),
    .clk_out1(clk_33m)
);

assign LCD_PCLK=~clk_33m;

COLOR_BAR u4(
    .clk(clk_33m),         
    .rst(0),           
    .hs(LCD_HSYNC),     
    .vs(LCD_VSYNC),      
    .de(LCD_DE),        
    .rgb_r(LCD_R),     
    .rgb_g(LCD_G),      
    .rgb_b(LCD_B)     
);

 ZYNQ_wrapper U_zynq(
   .GPIO_0_0_tri_io({LCD_RST,BL}),
   .IIC_0_0_scl_io(LCD_I2C_SCL),
   .IIC_0_0_sda_io(LCD_I2C_SDA)
 );
  
endmodule

最后再增加约束文件 (LCD_TEST.XDC)

set_property IOSTANDARD LVCMOS33 [get_ports {LCD_R[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LCD_B[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports LCD_VSYNC]
set_property IOSTANDARD LVCMOS33 [get_ports {LCD_R[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LCD_G[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LCD_B[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LCD_R[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LCD_G[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LCD_B[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports LCD_HSYNC]
set_property IOSTANDARD LVCMOS33 [get_ports {LCD_R[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LCD_R[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LCD_G[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LCD_B[3]}]
set_property IOSTANDARD LVCMOS33 [get_ports CLK]
set_property IOSTANDARD LVCMOS33 [get_ports {LCD_G[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports LCD_PCLK]
set_property IOSTANDARD LVCMOS33 [get_ports LCD_DE]
set_property IOSTANDARD LVCMOS33 [get_ports {LCD_G[0]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LCD_B[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LCD_R[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LCD_G[5]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LCD_R[2]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LCD_B[1]}]
set_property IOSTANDARD LVCMOS33 [get_ports LCD_RST]
set_property IOSTANDARD LVCMOS33 [get_ports {LCD_G[4]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LCD_B[6]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LCD_R[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports LCD_I2C_SDA]
set_property IOSTANDARD LVCMOS33 [get_ports LCD_I2C_SCL]
set_property IOSTANDARD LVCMOS33 [get_ports {LCD_B[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports {LCD_G[7]}]
set_property IOSTANDARD LVCMOS33 [get_ports BL]

set_property PACKAGE_PIN W13 [get_ports {LCD_B[0]}]
set_property PACKAGE_PIN L16 [get_ports {LCD_B[4]}]
set_property PACKAGE_PIN M18 [get_ports {LCD_G[2]}]
set_property PACKAGE_PIN Y19 [get_ports {LCD_R[4]}]
set_property PACKAGE_PIN V17 [get_ports {LCD_R[6]}]
set_property PACKAGE_PIN W16 [get_ports {LCD_R[2]}]
set_property PACKAGE_PIN Y18 [get_ports {LCD_R[0]}]
set_property PACKAGE_PIN V16 [get_ports {LCD_G[6]}]
set_property PACKAGE_PIN Y16 [get_ports {LCD_G[0]}]
set_property PACKAGE_PIN W15 [get_ports {LCD_B[6]}]
set_property PACKAGE_PIN P16 [get_ports {LCD_G[1]}]
set_property PACKAGE_PIN M17 [get_ports {LCD_B[1]}]
set_property PACKAGE_PIN U19 [get_ports BL]
set_property PACKAGE_PIN T10 [get_ports {LCD_B[3]}]
set_property PACKAGE_PIN N17 [get_ports {LCD_B[5]}]
set_property PACKAGE_PIN N16 [get_ports {LCD_B[7]}]
set_property PACKAGE_PIN V12 [get_ports LCD_DE]
set_property PACKAGE_PIN P18 [get_ports {LCD_G[3]}]
set_property PACKAGE_PIN Y17 [get_ports {LCD_G[4]}]
set_property PACKAGE_PIN R16 [get_ports {LCD_G[5]}]
set_property PACKAGE_PIN R17 [get_ports {LCD_G[7]}]
set_property PACKAGE_PIN U12 [get_ports LCD_PCLK]
set_property PACKAGE_PIN K18 [get_ports CLK]
set_property PACKAGE_PIN V18 [get_ports {LCD_R[1]}]
set_property PACKAGE_PIN T17 [get_ports {LCD_R[3]}]
set_property PACKAGE_PIN T16 [get_ports {LCD_R[5]}]
set_property PACKAGE_PIN U17 [get_ports {LCD_R[7]}]
set_property PACKAGE_PIN U20 [get_ports LCD_RST]
set_property PACKAGE_PIN W14 [get_ports LCD_VSYNC]
set_property PACKAGE_PIN Y14 [get_ports {LCD_B[2]}]
set_property PACKAGE_PIN V13 [get_ports LCD_HSYNC]
set_property PACKAGE_PIN U15 [get_ports LCD_I2C_SCL]
set_property PACKAGE_PIN T15 [get_ports LCD_I2C_SDA]

set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets u2/inst/clk_in1_clk_wiz_0]
set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets CLK_IBUF]

4.生成bit文件

按下绿色箭头对工程进行编译

按下Generate Bitstream 完成综合以及生成bit文件

5.SDK程序编写

1)File→Export→Export hardware…,在弹出的对话框中勾选“include bitstream”,点击“OK”确认,如下图所示。

2)File→Lauch SDK,在弹出的对话框中,保存默认,点击“OK”,如下图所示。

系统将自动打开SDK开发环境

3)新建一个工程 file→new→Application Project,来新建一个“Application Project”,如下图所示。

4)在新建工程名中输入自己的工程名称,点击NEXT

5)选择空工程,点击完成FINISH

6) 在工程中添加main.c文件 src—>New—>Source File 如下图所示

7)在弹出的窗口中填入main.c 并且保存

8).打开刚才创建的main.c

然后 写入以下代码 有一个地方值得注意 EMIO的 IO口编号 是从54开始的,也就是我VIVADO 下创建的 EMIO端口,在PS端都是从54-55-56 依次排序的(小贴士 小于54的是MIO 也就是芯片PS的硬件IO口)

#include "xparameters.h"
#include "xstatus.h"
#include "xplatform_info.h"
#include "xgpiops.h"
#include "xiicps.h"

#include <xil_printf.h>

XGpioPs Gpio;	/* The driver instance for GPIO Device. */

#define GPIO_DEVICE_ID  	XPAR_XGPIOPS_0_DEVICE_ID

#define EMIO_LCD_RST  	55
#define EMIO_LCD_BL  	54

void Gpio_Init(void){
	XGpioPs_Config *ConfigPtr;

	ConfigPtr = XGpioPs_LookupConfig(GPIO_DEVICE_ID);
	XGpioPs_CfgInitialize(&Gpio, ConfigPtr,ConfigPtr->BaseAddr);

	XGpioPs_SetDirectionPin(&Gpio, EMIO_LCD_RST, 1);
	XGpioPs_SetOutputEnablePin(&Gpio, EMIO_LCD_RST, 1);
	XGpioPs_WritePin(&Gpio, EMIO_LCD_RST, 	1);

	XGpioPs_SetDirectionPin(&Gpio, EMIO_LCD_BL, 1);
	XGpioPs_SetOutputEnablePin(&Gpio, EMIO_LCD_BL, 1);
	XGpioPs_WritePin(&Gpio, EMIO_LCD_BL, 	0);
}


void LCD_delay(unsigned int i){
	volatile int Delay;
	volatile int k;
	for(k=0;k<i;k++)
	for (Delay = 0; Delay < 10000; Delay++);
}


#define IIC_DEVICE_ID		XPAR_XIICPS_0_DEVICE_ID
#define IIC_SCLK_RATE		50000
#define IIC_SLAVE_ADDR		0x4C  //4D
XIicPs Iic;

unsigned char  Send_date(unsigned int date1,unsigned char date2){
	u8 state=0;
	u8 SendBuffer[4];    /**< Buffer for Transmitting Data */
	SendBuffer[0]=(date1>>8)&0xff;
	SendBuffer[1]=date1&0xff;
	SendBuffer[2]=0x00;
	SendBuffer[3]=date2;

	state=XIicPs_MasterSendPolled(&Iic, SendBuffer,4, IIC_SLAVE_ADDR);
	return state;
}

void  Send_comm(unsigned int date1){
	u8 SendBuffer[2];    /**< Buffer for Transmitting Data */
	SendBuffer[0]=(date1>>8)&0xff;
	SendBuffer[1]=date1&0xff;

	XIicPs_MasterSendPolled(&Iic, SendBuffer,2, IIC_SLAVE_ADDR);
}


void Lcd_Init(void){
	XGpioPs_WritePin(&Gpio, EMIO_LCD_RST, 	1);
	LCD_delay(1000);
	XGpioPs_WritePin(&Gpio, EMIO_LCD_RST, 	0);
	LCD_delay(1000);
	XGpioPs_WritePin(&Gpio, EMIO_LCD_RST, 	1);
	LCD_delay(100);

	Send_date(0xF000,0x55);
	Send_date(0xF001,0xAA);
	Send_date(0xF002,0x52);
	Send_date(0xF003,0x08);
	Send_date(0xF004,0x01);//Page 1

	//*************AVDD Set AVDD 5.2V*************//
	Send_date(0xB000,0x0D);
	Send_date(0xB001,0x0D);
	Send_date(0xB002,0x0D);

	//************AVDD ratio****************//
	Send_date(0xB600,0x34);
	Send_date(0xB601,0x34);
	Send_date(0xB602,0x34);

	//************AVEE  -5.2V****************//
	Send_date(0xB100,0x0D);
	Send_date(0xB101,0x0D);
	Send_date(0xB102,0x0D);

	//***********AVEE ratio*************//
	Send_date(0xB700,0x34);
	Send_date(0xB701,0x34);
	Send_date(0xB702,0x34);

	//***********VCL  -2.5V*************//
	Send_date(0xB200,0x00);
	Send_date(0xB201,0x00);
	Send_date(0xB202,0x00);

	//**************VCL ratio*****************//
	Send_date(0xB800,0x24);
	Send_date(0xB801,0x24);
	Send_date(0xB802,0x24);


	//*************VGH 15V  (Free pump)*********//
	Send_date(0xBF00,0x01);
	Send_date(0xB300,0x0F);
	Send_date(0xB301,0x0F);
	Send_date(0xB302,0x0F);

	//*************VGH ratio*****************//
	Send_date(0xB900,0x34);
	Send_date(0xB901,0x34);
	Send_date(0xB902,0x34);

	//***************VGL_REG -10V**************//
	Send_date(0xB500,0x08);
	Send_date(0xB501,0x08);
	Send_date(0xB502,0x08);

	Send_date(0xC200,0x03);

	//*****************VGLX ratio***************//
	Send_date(0xBA00,0x24);
	Send_date(0xBA01,0x24);
	Send_date(0xBA02,0x24);

	//*************VGMP/VGSP 4.5V/0V*************//
	Send_date(0xBC00,0x00);
	Send_date(0xBC01,0x78);
	Send_date(0xBC02,0x00);

	//************VGMN/VGSN -4.5V/0V****************//
	Send_date(0xBD00,0x00);
	Send_date(0xBD01,0x78);
	Send_date(0xBD02,0x00);

	//************VCOM  -1.25V****************//
	Send_date(0xBE00,0x00);
	Send_date(0xBE01,0x64);    //67--------------

	//************Gamma Setting******************//
	Send_date(0xD100,0x00);
	Send_date(0xD101,0x33);
	Send_date(0xD102,0x00);
	Send_date(0xD103,0x34);
	Send_date(0xD104,0x00);
	Send_date(0xD105,0x3a);
	Send_date(0xD106,0x00);
	Send_date(0xD107,0x4A);
	Send_date(0xD108,0x00);
	Send_date(0xD109,0x5c);
	Send_date(0xD10A,0x00);
	Send_date(0xD10B,0x81);
	Send_date(0xD10C,0x00);
	Send_date(0xD10D,0xA6);
	Send_date(0xD10E,0x00);
	Send_date(0xD10F,0xE5);
	Send_date(0xD110,0x01);
	Send_date(0xD111,0x13);
	Send_date(0xD112,0x01);
	Send_date(0xD113,0x54);
	Send_date(0xD114,0x01);
	Send_date(0xD115,0x82);
	Send_date(0xD116,0x01);
	Send_date(0xD117,0xCA);
	Send_date(0xD118,0x02);
	Send_date(0xD119,0x00);
	Send_date(0xD11A,0x02);
	Send_date(0xD11B,0x01);
	Send_date(0xD11C,0x02);
	Send_date(0xD11D,0x34);
	Send_date(0xD11E,0x02);
	Send_date(0xD11F,0x67);
	Send_date(0xD120,0x02);
	Send_date(0xD121,0x84);
	Send_date(0xD122,0x02);
	Send_date(0xD123,0xA4);
	Send_date(0xD124,0x02);
	Send_date(0xD125,0xB7);
	Send_date(0xD126,0x02);
	Send_date(0xD127,0xCF);
	Send_date(0xD128,0x02);
	Send_date(0xD129,0xDE);
	Send_date(0xD12A,0x02);
	Send_date(0xD12B,0xF2);
	Send_date(0xD12C,0x02);
	Send_date(0xD12D,0xFE);
	Send_date(0xD12E,0x03);
	Send_date(0xD12F,0x10);
	Send_date(0xD130,0x03);
	Send_date(0xD131,0x33);
	Send_date(0xD132,0x03);
	Send_date(0xD133,0x6D);

	Send_date(0xD200,0x00);
	Send_date(0xD201,0x33);
	Send_date(0xD202,0x00);
	Send_date(0xD203,0x34);
	Send_date(0xD204,0x00);
	Send_date(0xD205,0x3A);
	Send_date(0xD206,0x00);
	Send_date(0xD207,0x4A);
	Send_date(0xD208,0x00);
	Send_date(0xD209,0x5C);
	Send_date(0xD20A,0x00);
	Send_date(0xD20B,0x81);
	Send_date(0xD20C,0x00);
	Send_date(0xD20D,0xA6);
	Send_date(0xD20E,0x00);
	Send_date(0xD20F,0xE5);
	Send_date(0xD210,0x01);
	Send_date(0xD211,0x13);
	Send_date(0xD212,0x01);
	Send_date(0xD213,0x54);
	Send_date(0xD214,0x01);
	Send_date(0xD215,0x82);
	Send_date(0xD216,0x01);
	Send_date(0xD217,0xCA);
	Send_date(0xD218,0x02);
	Send_date(0xD219,0x00);
	Send_date(0xD21A,0x02);
	Send_date(0xD21B,0x01);
	Send_date(0xD21C,0x02);
	Send_date(0xD21D,0x34);
	Send_date(0xD21E,0x02);
	Send_date(0xD21F,0x67);
	Send_date(0xD220,0x02);
	Send_date(0xD221,0x84);
	Send_date(0xD222,0x02);
	Send_date(0xD223,0xA4);
	Send_date(0xD224,0x02);
	Send_date(0xD225,0xB7);
	Send_date(0xD226,0x02);
	Send_date(0xD227,0xCF);
	Send_date(0xD228,0x02);
	Send_date(0xD229,0xDE);
	Send_date(0xD22A,0x02);
	Send_date(0xD22B,0xF2);
	Send_date(0xD22C,0x02);
	Send_date(0xD22D,0xFE);
	Send_date(0xD22E,0x03);
	Send_date(0xD22F,0x10);
	Send_date(0xD230,0x03);
	Send_date(0xD231,0x33);
	Send_date(0xD232,0x03);
	Send_date(0xD233,0x6D);

	Send_date(0xD300,0x00);
	Send_date(0xD301,0x33);
	Send_date(0xD302,0x00);
	Send_date(0xD303,0x34);
	Send_date(0xD304,0x00);
	Send_date(0xD305,0x3A);
	Send_date(0xD306,0x00);
	Send_date(0xD307,0x4A);
	Send_date(0xD308,0x00);
	Send_date(0xD309,0x5C);
	Send_date(0xD30A,0x00);
	Send_date(0xD30B,0x81);
	Send_date(0xD30C,0x00);
	Send_date(0xD30D,0xA6);
	Send_date(0xD30E,0x00);
	Send_date(0xD30F,0xE5);
	Send_date(0xD310,0x01);
	Send_date(0xD311,0x13);
	Send_date(0xD312,0x01);
	Send_date(0xD313,0x54);
	Send_date(0xD314,0x01);
	Send_date(0xD315,0x82);
	Send_date(0xD316,0x01);
	Send_date(0xD317,0xCA);
	Send_date(0xD318,0x02);
	Send_date(0xD319,0x00);
	Send_date(0xD31A,0x02);
	Send_date(0xD31B,0x01);
	Send_date(0xD31C,0x02);
	Send_date(0xD31D,0x34);
	Send_date(0xD31E,0x02);
	Send_date(0xD31F,0x67);
	Send_date(0xD320,0x02);
	Send_date(0xD321,0x84);
	Send_date(0xD322,0x02);
	Send_date(0xD323,0xA4);
	Send_date(0xD324,0x02);
	Send_date(0xD325,0xB7);
	Send_date(0xD326,0x02);
	Send_date(0xD327,0xCF);
	Send_date(0xD328,0x02);
	Send_date(0xD329,0xDE);
	Send_date(0xD32A,0x02);
	Send_date(0xD32B,0xF2);
	Send_date(0xD32C,0x02);
	Send_date(0xD32D,0xFE);
	Send_date(0xD32E,0x03);
	Send_date(0xD32F,0x10);
	Send_date(0xD330,0x03);
	Send_date(0xD331,0x33);
	Send_date(0xD332,0x03);
	Send_date(0xD333,0x6D);

	Send_date(0xD400,0x00);
	Send_date(0xD401,0x33);
	Send_date(0xD402,0x00);
	Send_date(0xD403,0x34);
	Send_date(0xD404,0x00);
	Send_date(0xD405,0x3A);
	Send_date(0xD406,0x00);
	Send_date(0xD407,0x4A);
	Send_date(0xD408,0x00);
	Send_date(0xD409,0x5C);
	Send_date(0xD40A,0x00);
	Send_date(0xD40B,0x81);
	Send_date(0xD40C,0x00);
	Send_date(0xD40D,0xA6);
	Send_date(0xD40E,0x00);
	Send_date(0xD40F,0xE5);
	Send_date(0xD410,0x01);
	Send_date(0xD411,0x13);
	Send_date(0xD412,0x01);
	Send_date(0xD413,0x54);
	Send_date(0xD414,0x01);
	Send_date(0xD415,0x82);
	Send_date(0xD416,0x01);
	Send_date(0xD417,0xCA);
	Send_date(0xD418,0x02);
	Send_date(0xD419,0x00);
	Send_date(0xD41A,0x02);
	Send_date(0xD41B,0x01);
	Send_date(0xD41C,0x02);
	Send_date(0xD41D,0x34);
	Send_date(0xD41E,0x02);
	Send_date(0xD41F,0x67);
	Send_date(0xD420,0x02);
	Send_date(0xD421,0x84);
	Send_date(0xD422,0x02);
	Send_date(0xD423,0xA4);
	Send_date(0xD424,0x02);
	Send_date(0xD425,0xB7);
	Send_date(0xD426,0x02);
	Send_date(0xD427,0xCF);
	Send_date(0xD428,0x02);
	Send_date(0xD429,0xDE);
	Send_date(0xD42A,0x02);
	Send_date(0xD42B,0xF2);
	Send_date(0xD42C,0x02);
	Send_date(0xD42D,0xFE);
	Send_date(0xD42E,0x03);
	Send_date(0xD42F,0x10);
	Send_date(0xD430,0x03);
	Send_date(0xD431,0x33);
	Send_date(0xD432,0x03);
	Send_date(0xD433,0x6D);

	Send_date(0xD500,0x00);
	Send_date(0xD501,0x33);
	Send_date(0xD502,0x00);
	Send_date(0xD503,0x33);
	Send_date(0xD504,0x00);
	Send_date(0xD505,0x3A);
	Send_date(0xD506,0x00);
	Send_date(0xD507,0x4A);
	Send_date(0xD508,0x00);
	Send_date(0xD509,0x5C);
	Send_date(0xD50A,0x00);
	Send_date(0xD50B,0x81);
	Send_date(0xD50C,0x00);
	Send_date(0xD50D,0xA6);
	Send_date(0xD50E,0x00);
	Send_date(0xD50F,0xE5);
	Send_date(0xD510,0x01);
	Send_date(0xD511,0x13);
	Send_date(0xD512,0x01);
	Send_date(0xD513,0x54);
	Send_date(0xD514,0x01);
	Send_date(0xD515,0x82);
	Send_date(0xD516,0x01);
	Send_date(0xD517,0xCA);
	Send_date(0xD518,0x02);
	Send_date(0xD519,0x00);
	Send_date(0xD51A,0x02);
	Send_date(0xD51B,0x01);
	Send_date(0xD51C,0x02);
	Send_date(0xD51D,0x34);
	Send_date(0xD51E,0x02);
	Send_date(0xD51F,0x67);
	Send_date(0xD520,0x02);
	Send_date(0xD521,0x84);
	Send_date(0xD522,0x02);
	Send_date(0xD523,0xA4);
	Send_date(0xD524,0x02);
	Send_date(0xD525,0xB7);
	Send_date(0xD526,0x02);
	Send_date(0xD527,0xCF);
	Send_date(0xD528,0x02);
	Send_date(0xD529,0xDE);
	Send_date(0xD52A,0x02);
	Send_date(0xD52B,0xF2);
	Send_date(0xD52C,0x02);
	Send_date(0xD52D,0xFE);
	Send_date(0xD52E,0x03);
	Send_date(0xD52F,0x10);
	Send_date(0xD530,0x03);
	Send_date(0xD531,0x33);
	Send_date(0xD532,0x03);
	Send_date(0xD533,0x6D);

	Send_date(0xD600,0x00);
	Send_date(0xD601,0x33);
	Send_date(0xD602,0x00);
	Send_date(0xD603,0x34);
	Send_date(0xD604,0x00);
	Send_date(0xD605,0x3A);
	Send_date(0xD606,0x00);
	Send_date(0xD607,0x4A);
	Send_date(0xD608,0x00);
	Send_date(0xD609,0x5C);
	Send_date(0xD60A,0x00);
	Send_date(0xD60B,0x81);
	Send_date(0xD60C,0x00);
	Send_date(0xD60D,0xA6);
	Send_date(0xD60E,0x00);
	Send_date(0xD60F,0xE5);
	Send_date(0xD610,0x01);
	Send_date(0xD611,0x13);
	Send_date(0xD612,0x01);
	Send_date(0xD613,0x54);
	Send_date(0xD614,0x01);
	Send_date(0xD615,0x82);
	Send_date(0xD616,0x01);
	Send_date(0xD617,0xCA);
	Send_date(0xD618,0x02);
	Send_date(0xD619,0x00);
	Send_date(0xD61A,0x02);
	Send_date(0xD61B,0x01);
	Send_date(0xD61C,0x02);
	Send_date(0xD61D,0x34);
	Send_date(0xD61E,0x02);
	Send_date(0xD61F,0x67);
	Send_date(0xD620,0x02);
	Send_date(0xD621,0x84);
	Send_date(0xD622,0x02);
	Send_date(0xD623,0xA4);
	Send_date(0xD624,0x02);
	Send_date(0xD625,0xB7);
	Send_date(0xD626,0x02);
	Send_date(0xD627,0xCF);
	Send_date(0xD628,0x02);
	Send_date(0xD629,0xDE);
	Send_date(0xD62A,0x02);
	Send_date(0xD62B,0xF2);
	Send_date(0xD62C,0x02);
	Send_date(0xD62D,0xFE);
	Send_date(0xD62E,0x03);
	Send_date(0xD62F,0x10);
	Send_date(0xD630,0x03);
	Send_date(0xD631,0x33);
	Send_date(0xD632,0x03);
	Send_date(0xD633,0x6D);


	//**************LV2 Page 0 enable*************//
	Send_date(0xF000,0x55);
	Send_date(0xF001,0xAA);
	Send_date(0xF002,0x52);
	Send_date(0xF003,0x08);
	Send_date(0xF004,0x00);//Page 0

	//Send_date(0xB000,0x00);//add RGB mode2
	//Send_date(0xB001,0x10);
	//Send_date(0xB002,0x10);
	//Send_date(0xB003,0x10);
	//Send_date(0xB004,0x10);
	Send_date(0xB300,0x00);

	//*************480x800*********************//
	Send_date(0xB500,0x50);

	//***************Display control**************//
	Send_date(0xB100,0xCC);
	Send_date(0xB101,0x00);

	//***************Source hold time*************//
	Send_date(0xB600,0x05);

	//**************Gate EQ control***************//
	Send_date(0xB700,0x70);
	Send_date(0xB701,0x70);

	//*************Source EQ control (Mode 2)******//
	Send_date(0xB800,0x01);
	Send_date(0xB801,0x03);
	Send_date(0xB802,0x03);
	Send_date(0xB803,0x03);

	//************Inversion mode  (2-dot)***********//
	Send_date(0xBC00,0x02);
	Send_date(0xBC01,0x00);
	Send_date(0xBC02,0x00);

	//***************Frame rate***************//
	/*
	Send_date(0xBD00,0x01);
	Send_date(0xBD01,0x84);
	Send_date(0xBD02,0x1C);  //0X1C
	Send_date(0xBD03,0x1C);
	Send_date(0xBD04,0x00);*/

	//********Timing control 4H w/ 4-Delayms *******//
	Send_date(0xC900,0xD0);
	Send_date(0xC901,0x02);
	Send_date(0xC902,0x50);
	Send_date(0xC903,0x50);
	Send_date(0xC904,0x50);

	Send_date(0x3600,0x00);//00
//	Send_date(0x3600,0xe0);//00
//
//	Send_date(0x2a00,0x00);
//	Send_date(0x2a01,0x00);
//	Send_date(0x2a02,0x03);
//	Send_date(0x2a03,0x1f);
//
//	Send_date(0x2b00,0x00);
//	Send_date(0x2b01,0x00);
//	Send_date(0x2b02,0x01);
//	Send_date(0x2b03,0xdf);


	Send_date(0x3500,0x00);
	//Send_date(0x3A00,0x55);
	Send_date(0x3A00,0x07);//RGB888
	Send_comm(0x1100);
	LCD_delay(120);
	Send_comm(0x2900);
	LCD_delay(10);
	Send_comm(0x2C00);

	XGpioPs_WritePin(&Gpio, EMIO_LCD_BL, 	1);

  }


void I2C_init(){
	XIicPs_Config *Config;
	Config = XIicPs_LookupConfig(IIC_DEVICE_ID);
	XIicPs_CfgInitialize(&Iic, Config, Config->BaseAddress);
	XIicPs_SetSClk(&Iic, IIC_SCLK_RATE);
}


int main(void)
{
	Gpio_Init();
	I2C_init();
	Lcd_Init();
	while(1);

	return XST_SUCCESS;
}

主程序种 只对GPIO I2C 的硬件资源进行初始化, 然后通过Lcd_Init();将屏幕的初始化指令通过I2C 对LCD进行配置, 完成后打开背光EMIO_LCD_BL

6.下载到板子上进行验证

选中工程中的硬件平台,并点击右键→Program FPGA,在弹出的对话框中选择默认,点击“program”,完成FPGA PL部分的Program工作

2)选中我们生成的GPIO工程 展开绿色箭头(RUN)右边的图标,选择Run As→1 Launch on Hardware(System Debugger)

可以看到板子上的屏幕开始显示图像,并且以2秒的时间间隔在变换着不同的颜色

备注 :为了方便调试可以按照下列描述进行勾选,这样每次debug的时候就自动重新对PL部分进行配置了(强烈推荐把每个工程都这样设置)

之后点 APPLY 然后 再选择Run As→1 Launch on Hardware(System Debugger)就可

另外 此次芯片用的是NT35510 ,内部是带GRAM的,默认是竖屏显示(通过配置 我们可以将屏幕设置成横屏 也就是从480X800改成800X480),只需要将MV 和 显示区域进行调整就可,大家可以自行尝试(实际横屏可以显示,但是横屏的时候画面切换会出现斜对角撕裂,所以这里就不推荐用横屏了,如需要横屏可以在ZYNQ将图像缓存到DDR上,做软件横屏,效果会比硬件配置成横屏更好,后面有时间会进行演示)

另外I2C配置部分也可以用VERILOG去编写,后面有时间会更新这块

板子上的触摸屏后续会例程上会增加

以下是本次项目的完整工程 仅供参考

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注