首页 > 其他分享 >fpga LCD屏幕显示

fpga LCD屏幕显示

时间:2024-11-08 12:44:28浏览次数:7  
标签:12 fpga get 屏幕显示 vga LCD data ports define

目录

matlab生成coe文件

150x150的JPG转化为coe文件

 ROM ip核配置​编辑

LCD显示驱动代码 

原理和vga一致。

 vga_parameter_cfg,v

 gen_data

 vga_driver

 vga_top

top_pin_xdc

上板验证


matlab生成coe文件

150x150的JPG转化为coe文件

%实现将图片的格式转换为数据处理中常用的RGB格式
clc;
clear;
rgb1=imread('laugh150x150.jpg');
rgb_r=rgb1(1:150,1:150,1);
rgb_g=rgb1(1:150,1:150,2);
rgb_b=rgb1(1:150,1:150,3);
rgb2_1=bitor(bitshift(uint32(rgb_r),16),bitshift(uint32(rgb_g),8));
rgb2 = bitor(rgb2_1,uint32(rgb_b)) ;
fid0 = fopen('laugh150x150.coe', 'wt');
%要以文本模式打开文件,请将字母 't' 附加到permission 参数,例如 'rt' 或 'wt+'。
fprintf(fid0,'MEMORY_INITIALIZATION_RADIX=16;\nMEMORY_INITIALIZATION_VECTOR=\n');
%先写入coe文件都需要加的一句话
fprintf(fid0, '%06x ', rgb2');%将矩阵按照6位16进制数输出,填充0占位
fid0 = fclose(fid0);%关闭这个文件
%显示图像
subplot(2,2,1),imshow(rgb_r),title('红色分量');
subplot(2,2,2),imshow(rgb_g),title('绿色分量');
subplot(2,2,3),imshow(rgb_b),title('蓝色分量');
subplot(2,2,4),imshow(rgb1),title('原图像');

 ROM ip核配置

 检查无误后点击OK,生成ip核

LCD显示驱动代码 

原理和vga一致。

VGA 即 Video Graphics Array 的缩写,也就是视频图形阵列。作为一种标准的显示接口得到广泛的应用。

常见的彩色显示器一般由 CRT(阴极射线管)构成,色彩是由 R、 G、 B(红、黄、蓝)三基色组成。显示是用逐行扫描的方式解决,阴极射线枪发出电子束打在涂有荧光粉的荧光屏上,产生 RGB 三基色,合成一个彩色像素。扫描从屏幕的左上方开始,从左到右,从上到下,进行扫描,每扫完一行,电子束回到屏幕的左边下一行的起始位置,在这其间 CRT 对电子束进行消隐。每行结束时,用行同步信号进行同步;扫描完所有行,用场同步信号进行同步,并使扫描回到屏幕左上方,同时进行场消隐,预备下一场的扫描。
对于普通的 VGA 显示器,共有 5 个信号:R、 G、 B 三基色、 HS(行同步信号); VS(场同步信号)、 DE(数据有效信号)、 VGA 时钟信号。对于时序驱动, VGA 显示器要严格遵循“VGA"工业标准, 通常我们用的显示器都满足工业标准
 

VGA 的驱动主要一共有涉及到如下信号:

Vga_clk: VGA 的时钟,所有信号都在这个信号同步下产生,以本次实验使用到 480x272@60Hz 模式为例, 480,272 分别表示的是屏幕上行,列的像素个数, 对应于上图中的 Addr time , 480x272@60Hz 模式,实际上是每场对应 525 行周期, 286 列周期, 所以时钟频率为 525*286*60Hz,大约 9Mhz。

HSync:行同步信号,用于同步行数据,本实验同的 lcd 显示屏是高电平有效。

VSync:场同步信号,用于同步场数据, 本实验中的 lcd 显示屏是高电平有效。

Vga_de:数据有效信号,高电平的时候表明数据有效。

Vga_data:像素数据,本实验为 24 位的数据, r、 g、 b 各 8 位。

 

 vga_parameter_cfg,v


`define  vga_480x272_60HZ
`define vga_1024x768_60Hz
`define vga_1920x1080_60Hz
`ifdef vga_480x272_60HZ 

	   `define       H_TOTAL 	        12'd525    //一行所需要的总的周期
	   `define       H_SYNC        	        12'd41     //行同步信号
	   `define       H_START 	        12'd43    //H_START=Hor Sync Time +H Back Porch +H Left Border
	   `define       H_END 		        12'd523   //数据有效位结束的值 
	   `define       V_TOTAL 	        12'd286    //场计数的总的值
	   `define       V_SYNC		        12'd10     //场同步信号
	   `define       V_START 	        12'd12     //场数据有效的开始
	   `define       V_END 		        12'd284   //场数据有效的结束
	   `define       SCREEN_X               12'd480     //屏幕的长度   //方块的长度
	   `define       SCREEN_Y               12'd272     //屏幕的宽度   //方块的宽度
           `define       SQUARE_X               12'd150      
	   `define       SQUARE_Y               12'd150      
`elsif vga_1024x768_60Hz
        `define          H_TOTAL                12'd1344           //一行总共需要计数的值
        `define          H_SYNC                 12'd136            //行同步计数值
        `define          H_START                12'd296            //行图像数据有效开始计数值
        `define          H_END                  12'd1320           //行图像数据有效结束计数值
        `define          V_TOTAL                12'd806            //场总共需要计数的值
        `define          V_SYNC                 12'd6              //场同步计数值
        `define          V_START                12'd35             //场图像数据有效开始计数值
        `define          V_END                  12'd803             //场图像数据有效结束计数值

        `define          SCREEN_X               12'd1024           //屏幕的长度
        `define          SCREEN_Y               12'd768            //屏幕的宽度
        `define          SQUARE_X               12'd256            //方块的长度
        `define          SQUARE_Y               12'd256            //方块的宽度
`elsif vga_1920x1080_60Hz
        `define         H_TOTAL                  12'd2200         //一行所需要的总的周期
        `define         H_SYNC                   12'd44           //行同步信号
        `define         H_START                  12'd192           //H_START=Hor Sync Time +H Back Porch +H Left Border                                   //数据有效信号开始的值
        `define         H_END                    12'd2112         //数据有效位结束的值 
        `define         V_TOTAL                  12'd1125         //场计数的总的值
        `define         V_SYNC                   12'd5            //场同步信号
        `define         V_START                  12'd41           //场数据有效的开始
        `define         V_END                    12'd1121         //场数据有效的结束
        
        `define         SCREEN_X                 12'd1920           //屏幕的长度
        `define         SCREEN_Y                 12'd1080           //屏幕的宽度
        `define         SQUARE_X                 12'd256            //方块的长度
        `define         SQUARE_Y                 12'd256             //方块的宽度
`endif 
 

 gen_data


`include "vga_parameter_cfg.v"
module gen_wave(
    input                 clk_in       ,
    input                 rst_n        ,  
    //与vga_driver模块连接的信号  
    input                 rd_data_req  , 
    output  reg  [23:0]   rd_data      , //{R,G,B}
    input        [11:0]   h_addr       , //数据横坐标地址
    input        [11:0]   v_addr       ,  //数据纵坐标
    //读取ROM中的接口信号
    output               rd_rom_req     ,
    input       [23:0]   rom_data   
);

//用两个计数器计数一同方块的左上角的位置
reg [11:0] square_x;//方块左上角横坐标
reg [11:0] square_y;//方块右上角纵坐标

//方块移动的标志
reg x_flag;//方块左右移动标志 0:向左移动  1:向右移动
reg y_flag;//方块上下移动标志 0: 向上移动  1:向下移动

//***************square_x********************
always@(posedge clk_in or negedge rst_n)begin
  if(!rst_n)                         
      square_x<='d0;                      
  else if(h_addr==`SCREEN_X-1'b1&&v_addr==`SCREEN_Y-1'b1)begin//一帧图像结束
            if(x_flag)
                 square_x<=square_x+1'b1;
            else 
                 square_x<=square_x-1'b1;  
  end 
  else   square_x<=square_x;                                                
end

//***************square_y********************
always@(posedge  clk_in or negedge rst_n)begin
  if(!rst_n)                         
      square_y<='d0;                      
  else if(h_addr==`SCREEN_X-1'b1&&v_addr==`SCREEN_Y-1'b1)begin//一帧图像结束
            if(y_flag)
                 square_y<=square_y+1'b1;
            else 
                 square_y<=square_y-1'b1;  
  end 
  else   square_y<=square_y;                                                
end

//***************x_flag********************
always@(posedge  clk_in or negedge rst_n)begin
  if(!rst_n)                         
        x_flag<=1'b1;//初始为1向右移动                      
  else if(h_addr==`SCREEN_X-1'b1&&v_addr==`SCREEN_Y-1'b1)begin    
            if(x_flag==1'b1&&square_x==`SCREEN_X-`SQUARE_X-'d3)
                   x_flag<=1'b0;
            else if(x_flag==1'b0&&square_x=='d2)
                   x_flag<=1'b1;
            else   x_flag<=x_flag;        
  end 
  else  x_flag<=x_flag;                                                  
end

//***************y_flag********************
always@(posedge  clk_in or negedge rst_n)begin
  if(!rst_n)                         
        y_flag<=1'b1;//初始为1向下移动                      
  else if(h_addr==`SCREEN_X-1'b1&&v_addr==`SCREEN_Y-1'b1)begin    
            if(y_flag==1'b1&&square_y==`SCREEN_Y-`SQUARE_Y-'d3)
                   y_flag<=1'b0;
            else if(y_flag==1'b0&&square_y=='d2)
                   y_flag<=1'b1;
            else   y_flag<=y_flag;        
  end 
  else  y_flag<=y_flag;                                                  
end

//显示移动的方块
always@(*)begin
  if(!rst_n) 
    rd_data='d0;
  else if(rd_data_req)begin
         if(h_addr>=square_x&&h_addr<square_x+`SQUARE_X&&v_addr>=square_y&&v_addr<square_y+`SQUARE_Y)
             rd_data=rom_data;
         else if(h_addr[5:0]<20)
                   rd_data=24'hff0000;
         else if(h_addr[5:0]<40)
                   rd_data=24'h00ff00;
         else   rd_data=24'h0000ff;      
  end
  else 
          rd_data=24'hffffff; 
end
assign rd_rom_req=rd_data_req&&h_addr>=square_x-1&&h_addr<square_x+`SQUARE_X-1&&v_addr>=square_y&&v_addr<square_y+`SQUARE_Y;
endmodule

 vga_driver


`include "vga_parameter_cfg.v"
module vga_driver
(
    input           clk_in,
    input           rst_n ,
    output          rd_data_req  , 
    input  [23:0]   rd_data, //{R,G,B}
    output [11:0]   h_addr , //数据横坐标地址
    output [11:0]   v_addr , //数据纵坐标
            
    output  reg     vga_hs ,         //vga行同步信号
    output  reg     vga_vs ,         //vga列同步信号
    output  reg     vga_de ,
    output          vga_clk,
    output [23:0]   vga_data  //{R,G,B}
);


reg [11:0]	cnt_h;//行计数器
reg [11:0]	cnt_v;//场计数器
//vga_clk
assign vga_clk=clk_in;    
//cnt_h 行计数器
always @(posedge vga_clk or negedge rst_n) begin
    if(rst_n==1'b0)
        cnt_h<=12'd0;
    else if(cnt_h==`H_TOTAL-1'b1)
            cnt_h<=12'd0;
    else   cnt_h<=cnt_h+1'b1;
end
//cnt_v 列计数器
always @(posedge vga_clk or negedge rst_n) begin
    if(rst_n==1'b0)
        cnt_v<=12'd0;
    else if(cnt_v==`V_TOTAL-1'b1&&cnt_h==`H_TOTAL-1'b1)
            cnt_v<=12'd0;
    else if(cnt_h==`H_TOTAL- 1'b1) 
            cnt_v<=cnt_v+1'b1;
    else   cnt_v<=cnt_v;
end
//vga_hs 行同步信号
always @(posedge vga_clk or negedge rst_n) begin
    if(rst_n==1'b0)
        vga_hs<=1'b1;
    else if(cnt_h==`H_TOTAL- 1'b1)
            vga_hs<=1'b1;
    else if(cnt_h==`H_SYNC- 1'b1)
            vga_hs<=1'b0;
    else  vga_hs<=vga_hs;
end
//vga_vs 列同步信号
always @(posedge vga_clk or negedge rst_n) begin
    if(rst_n==1'b0)
        vga_vs<=1'b1;
    else if(cnt_v==`V_TOTAL- 1'b1&&cnt_h==`H_TOTAL- 1'b1)
            vga_vs<=1'b1;
    else if(cnt_v==`V_SYNC- 1'b1&&cnt_h==`H_TOTAL- 1'b1)
            vga_vs<=1'b0;
    else    vga_vs<=vga_vs;
end
//vga_de 数据有效信号
always @(posedge vga_clk or negedge rst_n) begin
    if(rst_n==1'b0)
        vga_de<=1'b0;
    else if(cnt_v>`V_START- 1'b1&&cnt_v <=`V_END- 1'b1)begin
                if(cnt_h==`H_START- 1'b1)
                       vga_de<=1'b1;
                else if(cnt_h==`H_END- 1'b1)
                      vga_de<=1'b0;
                else  vga_de<=vga_de;
    end
    else  vga_de<=1'b0;
end
assign h_addr=vga_de?(cnt_h-`H_START):'d0;
assign v_addr=vga_de?(cnt_v-`V_START):'d0;
assign rd_data_req     = vga_de   ;
assign vga_data  = rd_data  ;
endmodule

 vga_top

`timescale 1ns / 1ps
`include "vga_parameter_cfg.v"
module vga_top(
        input           clk   ,
        input           rst_n    ,
        
        output          vga_en   ,
        output          vga_hs   ,
        output          vga_vs   ,
        output          vga_de   ,
        output          vga_clk  ,
        output [23:0]   vga_data  //{R,G,B}
    );

wire        clk_9m      ;
wire        rd_data_req ;
wire [23:0] rd_data     ;
wire [11:0] h_addr      ;
wire [11:0] v_addr      ;
wire        rd_rom_req  ;
wire [23:0] rom_data    ; 
reg  [16:0] rom_addr    ;
wire        locked      ;
wire        syn_rst_n   ;
assign  vga_en=1'b1     ;



clock clock_inst
(
    .clk_out1(clk_9m),    
    .resetn(rst_n), 
    .locked(locked),       
    .clk_in1(clk)
); 

asyc_rst_n u_asyc_rst_n(
    .clk        ( clk_9m    ),
    .rst_n      ( locked    ),
    .syn_rst_n  ( syn_rst_n  )
);


rom rom_inst 
(
  .clka(clk_9m),    // input wire clka
  .addra(rom_addr),  // input wire [16 : 0] addra
  .douta(rom_data)  // output wire [23 : 0] douta
);



always@(posedge clk_9m or negedge syn_rst_n)begin
  if(!syn_rst_n)                         
       rom_addr <='d0;                      
  else  if(rd_rom_req)begin   
            if(rom_addr==`SQUARE_X*`SQUARE_Y-1'b1)                         
                rom_addr <= 'd0;
            else 
                rom_addr <=  rom_addr+1'b1;  
  end 
  else   rom_addr <=  rom_addr;                    
end

gen_wave u_gen_wave(
    .clk_in       ( clk_9m       ),
    .rst_n        ( syn_rst_n    ),
    .rd_data_req  ( rd_data_req  ),
    .rd_data      ( rd_data      ),
    .h_addr       ( h_addr       ),
    .v_addr       ( v_addr       ),
     //读取ROM中的接口信号
    .rd_rom_req    (rd_rom_req),
    .rom_data     (rom_data)
);


vga_driver u_vga_driver(
    .clk_in       ( clk_9m      ),
    .rst_n        ( syn_rst_n        ),
    .rd_data_req  ( rd_data_req   ),
    .rd_data      ( rd_data   ),
    .h_addr       ( h_addr       ),
    .v_addr       ( v_addr       ),
    .vga_hs       ( vga_hs       ),
    .vga_vs       ( vga_vs       ),

    .vga_de       ( vga_de       ),
    .vga_clk      ( vga_clk      ),
    .vga_data     ( vga_data     )
);

endmodule

top_pin_xdc

create_clock -period 20.00  [get_ports clk]  
set_property -dict {PACKAGE_PIN J19  IOSTANDARD LVCMOS33} [get_ports  clk] 
set_property -dict {PACKAGE_PIN L18  IOSTANDARD LVCMOS33} [get_ports  rst_n] 

#########################GPIO2 VGA########################################## 
set_property -dict {PACKAGE_PIN W19   IOSTANDARD LVCMOS33} [get_ports  vga_en] 
set_property -dict {PACKAGE_PIN AB18  IOSTANDARD LVCMOS33} [get_ports  vga_hs] 
set_property -dict {PACKAGE_PIN AA18  IOSTANDARD LVCMOS33} [get_ports  vga_vs] 
set_property -dict {PACKAGE_PIN V19   IOSTANDARD LVCMOS33} [get_ports  vga_de] 
set_property -dict {PACKAGE_PIN W20   IOSTANDARD LVCMOS33} [get_ports  vga_clk] 

set_property -dict {PACKAGE_PIN AB22  IOSTANDARD LVCMOS33} [get_ports  vga_data[0]]
set_property -dict {PACKAGE_PIN AB21  IOSTANDARD LVCMOS33} [get_ports  vga_data[1]] 
set_property -dict {PACKAGE_PIN AB20  IOSTANDARD LVCMOS33} [get_ports  vga_data[2]]
set_property -dict {PACKAGE_PIN AA19  IOSTANDARD LVCMOS33} [get_ports  vga_data[3]]   
set_property -dict {PACKAGE_PIN V20   IOSTANDARD LVCMOS33} [get_ports  vga_data[4]]
set_property -dict {PACKAGE_PIN U20   IOSTANDARD LVCMOS33} [get_ports  vga_data[5]] 
set_property -dict {PACKAGE_PIN Y19   IOSTANDARD LVCMOS33} [get_ports  vga_data[6]]
set_property -dict {PACKAGE_PIN Y18   IOSTANDARD LVCMOS33} [get_ports  vga_data[7]] 
set_property -dict {PACKAGE_PIN W22   IOSTANDARD LVCMOS33} [get_ports  vga_data[8]]
set_property -dict {PACKAGE_PIN V22   IOSTANDARD LVCMOS33} [get_ports  vga_data[9]] 
set_property -dict {PACKAGE_PIN U22   IOSTANDARD LVCMOS33} [get_ports  vga_data[10]]
set_property -dict {PACKAGE_PIN Y22   IOSTANDARD LVCMOS33} [get_ports  vga_data[11]] 
set_property -dict {PACKAGE_PIN W21   IOSTANDARD LVCMOS33} [get_ports  vga_data[12]]
set_property -dict {PACKAGE_PIN Y21   IOSTANDARD LVCMOS33} [get_ports  vga_data[13]] 
set_property -dict {PACKAGE_PIN AA21  IOSTANDARD LVCMOS33} [get_ports  vga_data[14]]
set_property -dict {PACKAGE_PIN AA20  IOSTANDARD LVCMOS33} [get_ports  vga_data[15]] 
set_property -dict {PACKAGE_PIN U21  IOSTANDARD LVCMOS33} [get_ports  vga_data[16]]
set_property -dict {PACKAGE_PIN T21  IOSTANDARD LVCMOS33} [get_ports  vga_data[17]] 
set_property -dict {PACKAGE_PIN T18  IOSTANDARD LVCMOS33} [get_ports  vga_data[18]]
set_property -dict {PACKAGE_PIN R18  IOSTANDARD LVCMOS33} [get_ports  vga_data[19]] 
set_property -dict {PACKAGE_PIN R19  IOSTANDARD LVCMOS33} [get_ports  vga_data[20]]
set_property -dict {PACKAGE_PIN P19  IOSTANDARD LVCMOS33} [get_ports  vga_data[21]] 
set_property -dict {PACKAGE_PIN P17  IOSTANDARD LVCMOS33} [get_ports  vga_data[22]]
set_property -dict {PACKAGE_PIN N17  IOSTANDARD LVCMOS33} [get_ports  vga_data[23]] 

上板验证

标签:12,fpga,get,屏幕显示,vga,LCD,data,ports,define
From: https://blog.csdn.net/2301_79235594/article/details/143623077

相关文章

  • 基于Zynq FPGA对雷龙SD NAND的测试
    一、SDNAND特征1.1SD卡简介雷龙的SDNAND有很多型号,在测试中使用的是CSNP4GCR01-AMW与CSNP32GCR01-AOW。芯片是基于NANDFLASH和SD控制器实现的SD卡。具有强大的坏块管理和纠错功能,并且在意外掉电的情况下同样能保证数据的安全。其特点如下:接口支持SD2......
  • FPGA实现复杂状态机的跳转-判断标准数据帧
    填补之前的状态机跳转挖的坑;数据源对比标准帧:第一步:ROM当做数据源:使能开启,使用地址addr控制其输出。(使用状态机写入RAM时的控制选用addr)RAM作为标准帧的缓存,使用addr_ram作为RAM的写入地址。此时ROM的地址比RAM的地址延迟了一个节拍;(addr_ram<=addr;)第二步:RAM缓存写满之......
  • LCD TV电源逆变器工作原理
    LCDTV电源逆变器工作原理本文将介绍一款基于ARM控制的逆变器电源电路设计方案及其应用。系统总体方案1、总体设计框图如图1所示,逆变器系统由升压电路、逆变电路、控制电路和反馈电路组成。低压直流电源DC12V经过升压电路升压、整流和滤波后得到约DC170V高压直流电,然后经全......
  • 基于FPGA的可控分频器设计与应用
    ###标题:基于FPGA的可控分频器设计与应用---####正文:可控分频器在数字电路中扮演着重要角色,尤其是在频率合成和时钟管理方面。基于FPGA的实现不仅灵活且易于修改,本文将详细介绍如何设计和实现一个可控分频器,并展示其应用实例。---###一、可控分频器的基本概念可控分频......
  • FPGA在图像伽玛校正中的应用
    随着数字图像处理技术的不断发展,图像质量优化成为了一个重要的研究方向。在图像处理中,伽玛(Gamma)校正是一种广泛应用的技术,用于调整图像的亮度和对比度,以改善图像质量,使之更符合人眼的视觉感知。特别是在FPGA(现场可编程门阵列)平台上实现伽玛校正,由于其高并行性和灵活性,成为了图像处......
  • FPGA中的图像平移技术
    在图像处理领域,图像平移是一种基本的几何变换操作,它能够将图像中的所有像素在二维平面上按照指定的方向和距离进行移动。这种操作不改变图像的形状或大小,但会显著影响图像在坐标系中的位置。随着FPGA(现场可编程门阵列)技术的快速发展,将图像平移算法部署到FPGA上已成为提高图像处理......
  • 转存——Quartus II FPGA程序仿真运行时出现错误“error occurred during modelsim si
    起因使用QuartusII软件进行FPGA程序仿真,运行时出现错误“erroroccurredduringmodelsimsimulation”,上网查询解决方法,找了很久都没找到,最后在一个CSDN博客的评论里找到解决方法。现将解决方法转存如下。错误示例解决步骤1.依次点击simulation,option2.依次点击Quartus......
  • FPGA图像处理实战:图像裁剪技术
    在图像处理领域,图像裁剪是一项基础且关键的技术,它允许我们从原始图像中裁剪出感兴趣的区域,同时丢弃不相关的部分。这种技术在人脸识别、目标跟踪、图像分割等多种应用场景中发挥着重要作用。随着FPGA(现场可编程门阵列)技术的快速发展,将图像裁剪算法部署到FPGA上已成为提高处理速度......
  • FPGA(现场可编程门阵列)的时序分析
    在FPGA(现场可编程门阵列)的时序分析中,tsu(建立时间)、th(保持时间)、tco(时钟到输出延时)、tpd(引脚到引脚延时)以及tcd(可能指的是信号在组合逻辑中的传输延时,尽管它在FPGA时序分析中不是一个标准的术语,但在此为全面解答而提及)是几个至关重要的参数。这些参数共同决定了FPGA电路的性......
  • FPGA实例——按键消抖和自定义IP封装
    按键消抖:简介:目前,在大部分的FPGA开发板上都带有机械按键,由于机械按键的物理特性,按键在按下和释放的过程中,存在一段时间的抖动,这就导致在识别按键的时候可以检测到多次的按键按下,而通常检测到一次按键输入信号的状态为低电平,就可以确认按键被按下了,所以我们在使用按键时往往需......