• FPGA驱动LCD显示红绿蓝彩条


    实验目的:先简单熟悉LCD灯的驱动和时序图的代码实现。设计功能是让LCD显示红绿蓝三种颜色,即三个彩带。本次实验比较容易实现,主要是对LCD驱动时序图的理解和时序参数的配置。

    实验条件:1.LCD原理图2020-12-17-HXH_ESP32_E1。

             2.所用开发板用户手册:GW1NSR-LV4CQN48PC7I6_V1.1开发板用户手册

             3.LCD的数据手册:SC7283(确定LCD驱动设计的引脚和时序控制)

    注释:第一项和第二项结合是为了,分配LCD和FPGA的引脚。一般用PDF软件Adobe Acrobat DC进行查找引脚编号,再粘贴复制找到引脚的位置,在用一个EXCEL表格记下引脚名字,引脚的位置或编号,引脚的电压类型(LVCMOS33或LVCMOS18等)

    实验原理:

             LCD的分辨率为480RGB * 272  ,理解为有480列和272行,分别对应行同步计数器h_cnt 和场同步计数器v_cnt ,LCD有三种模式,SYNC, SYNC-DE and DE mode,本次选用的是第二种,和VGA的驱动很相似,先是行同步信号HSYNC,然后是场同步信号VSYNC(行同步信号(一个像素点)可以理解为把一行的所有列扫描完则就是场同步信号,即场同步信号比行同步信号大。)再是有效区域DE。由于对于行同步信号或者场同步信号的时许控制来讲,都是由行同步信号或场同步信号周期,前沿,有效区域,后沿等四个部分参数组成

    时许图如下:

    下图红框的是LCD分辨率为480RGB * 272时,对应时序图中的配置参数。

    三  代码设计:

           本设计代码分成两部分,一是顶层模块,二是LCD驱动控制模块。

                                                                        1.LCD顶层模块:

    module lcd_top#
    (
    parameter ROW_NUM = 272
    ,parameter COL_NUM = 480
    ,parameter DATA_LENGTH = 24 //传输数据位宽,RGB888是24位

    ,parameter CMD_SPACE = 43 //每次使能信号间隔
    ,parameter BURST_NUM = 32
    )
    (
    //////// SYSTEM ////////////////
    input sys_clk
    ///////// SPI //////////////////
    // ,input i_cs
    // ,input i_sclk
    // ,input i_mosi
    // ,input i_dcx

    //////// RGB ///////////////////
    ,output fv
    ,output lv
    ,output de
    ,output [DATA_LENGTH-1:0] pixdata//,output [15:0] pixdata
    ,output pixclk
    );


    ////////////// 延时复位 ///////////
    reg [29:0] init_delay = 0;
    always@(posedge sys_clk)begin
    if(init_delay >= 50000000)
    init_delay <= init_delay;
    else
    init_delay <= init_delay + 1'b1;
    end

    wire FPGA_RST_N;
    assign FPGA_RST_N = (init_delay >= 50000000)?1:0;

    LCD_CTRL #
    (
    .WORD_WIDTH (DATA_LENGTH)

    ,.H_FRONT_PORCH(8)
    ,.H_BACK_PORCH (43)
    ,.H_SYNC (4)

    ,.V_FRONT_PORCH(8) //V_TOTAL = VFP +VBP +V_SYNC + V_ACTIVE,V_TOTAL = 929
    ,.V_BACK_PORCH (12)
    ,.V_SYNC (4)

    ,.H_ACTIVE (COL_NUM)
    ,.V_ACTIVE (ROW_NUM)// 120//
    )
    u_RGB_CTRL
    (
    .rst_n(FPGA_RST_N)
    ,.sysclk(sys_clk)

    ,.lcd_A_vs(fv)
    ,.lcd_A_hs(lv)
    ,.lcd_A_de(de)

    ,.lcd_A_clk(pixclk)
    ,.lcd_A_rgb (pixdata)
    );

    endmodule

                                                                           2.LCD驱动模块


    module LCD_CTRL #
    (parameter WORD_WIDTH = 24

    ,parameter H_FRONT_PORCH = 8
    ,parameter H_BACK_PORCH = 43
    ,parameter H_SYNC = 4
    //H——TOTAL=HFP +HBP +H_SYNC + H_ACTIVE=531
    ,parameter V_FRONT_PORCH = 8 //V_TOTAL = VFP +VBP +V_SYNC + V_ACTIVE,V_TOTAL = 292
    ,parameter V_BACK_PORCH = 12
    ,parameter V_SYNC = 4

    ,parameter H_ACTIVE = 480
    ,parameter V_ACTIVE = 272// 120//
    )
    (//input rst_n
    input sysclk
    ,input wire rst_n

    ,output lcd_A_vs
    ,output lcd_A_hs
    ,output lcd_A_de
    ,output lcd_A_clk
    ,output [WORD_WIDTH-1:0] lcd_A_rgb
    ///////////init
    ,output wire rgb_en
    ,output wire lcd_disp
    // ,output wire o_mosi
    // ,output wire o_mclk
    // ,output wire o_cs
    );
    parameter BLACK = 24'h000000; //红色
    parameter RED = 24'hFF0000; //红色
    parameter GREEN = 24'h00FF00; //绿色
    parameter BLUE = 24'h0000FF; //蓝色
    //场同步信号的参数
    parameter RED_CNT = 16'd90; //红色
    parameter GREEN_CNT = 16'd180; //绿色
    parameter BLUE_CNT = 16'd270; //蓝色
    //行同步信号的参数
    parameter H_RED_CNT = 16'd160; //红色
    parameter H_GREEN_CNT = 16'd320; //绿色
    parameter H_BLUE_CNT = 16'd479; //蓝色
    //------------------------HSYNC的时间计数 begin
    reg[15:0] h_cnt;
    wire clk_9m;
    reg [WORD_WIDTH-1:0] pixel_data;
    Gowin_CLKDIV CLKDIV_9m (
    .clkout(clk_9m), //output clkout
    .hclkin(sysclk), //input hclkin
    .resetn(1) //input resetn
    );

    always @ (posedge clk_9m or negedge rst_n) begin
    if(!rst_n)
    h_cnt <= 'd0;
    else if(h_cnt >= H_SYNC+H_BACK_PORCH+H_ACTIVE+H_FRONT_PORCH-1)
    h_cnt <= 'd0;
    else
    h_cnt <= h_cnt + 'd1;
    end
    //------------------------HSYNC的时间计数 end

    //------------------------VSYNC的时间计数 begin
    reg[15:0] v_cnt;

    always @ (posedge clk_9m or negedge rst_n) begin
    if(!rst_n)
    v_cnt <= 'd0;
    else if(h_cnt == H_SYNC+H_BACK_PORCH+H_ACTIVE+H_FRONT_PORCH-1) begin//H_SYNC-2)
    if(v_cnt >= V_SYNC+V_BACK_PORCH+V_ACTIVE+V_FRONT_PORCH-1)
    v_cnt <= 'd0;
    else
    v_cnt <= v_cnt + 'd1;
    end
    else
    v_cnt <= v_cnt;
    end
    //------------------------VSYNC的时间计数 end

    //------------------------生成VSYNC信号 begin
    //vsync_r
    reg vsync_r;
    always @ (posedge clk_9m or negedge rst_n) begin
    if(!rst_n)
    vsync_r <= 'd1;
    else if((v_cnt >= 'd0) && (v_cnt <= V_SYNC-1)) //Negative
    vsync_r <= 'd0;
    else
    vsync_r <= 'd1;
    end
    //------------------------生成VSYNC信号 end

    //------------------------生成HSYNC信号 begin
    //hs
    reg hsync_r;
    always @ (posedge clk_9m or negedge rst_n) begin
    if(!rst_n)
    hsync_r <= 'd1;
    else if((h_cnt >= 'd0) && (h_cnt <= H_SYNC-1)) //Negative
    hsync_r <= 'd0;
    else
    hsync_r <= 'd1;
    end
    //------------------------生成HSYNC信号 end

    //------------------------生成DE信号 begin
    //de
    reg de_r;
    always @ (posedge clk_9m or negedge rst_n) begin
    if(!rst_n) begin
    de_r <= 0;
    end
    else if((h_cnt >= H_SYNC+H_BACK_PORCH) && (h_cnt <= H_SYNC+H_BACK_PORCH+H_ACTIVE-1)
    && (v_cnt >= V_SYNC+V_BACK_PORCH)&&(v_cnt <= V_SYNC+V_BACK_PORCH+V_ACTIVE-1)) begin
    de_r <= 1;
    end
    else begin
    de_r <= 'd0;
    end
    end
    //------------------------生成DE信号 end

    //------------------------把控制信号和FIFO读取的数据进行同步 begin
    reg de_r1,de_r2,de_r3;

    always @ (posedge clk_9m or negedge rst_n) begin
    if(!rst_n) begin
    de_r1 <= 0;
    de_r2 <= 0;
    de_r3 <= 0;
    end
    else begin
    de_r1 <= de_r;
    de_r2 <= de_r1;
    de_r3 <= de_r2;
    end
    end
    //------------------------把控制信号和FIFO读取的数据进行同步 end

    //------------------------将同步后的RGB数据按照协议进行映射输出 begin
    reg [WORD_WIDTH-1:0] lcd_rgb1_d;

    always @ (posedge clk_9m or negedge rst_n) begin
    if(!rst_n) begin
    lcd_rgb1_d <= 0;
    end
    else if(!de_r1)
    lcd_rgb1_d <= 0;
    else if(de_r1) begin
    lcd_rgb1_d <= pixel_data;
    end
    end

    //显示彩条红绿蓝
    always @(posedge clk_9m or negedge rst_n) begin
    if(!rst_n)
    pixel_data <= BLACK;
    else begin
    if((v_cnt >= 0) && (v_cnt < RED_CNT)&de_r)
    pixel_data <= RED;
    else if ((v_cnt >= RED_CNT) && (v_cnt < GREEN_CNT)&de_r)
    pixel_data <= GREEN;
    else
    pixel_data <= BLUE;
    end
    end

    assign lcd_A_rgb = lcd_rgb1_d;//16'hf0;//

    assign lcd_A_vs = vsync_r;
    assign lcd_A_hs = hsync_r;
    assign lcd_A_de = de_r2;
    assign lcd_A_clk = ~clk_9m;

    endmodule

    四实验中的问题:

    注意1:今天出现了FPGA设计软件布局布线时提示引脚错误,说这几个引脚已经有专用引脚了。其实,是同一个引脚复用,即LCD_PIXCLK,PIXDATA[16], PIXDATA[23],DE,LV引脚提示和MSPI引脚冲突,最后通过钩选引脚复用解决,如下所示:

     

    注意2:实验现象即开发板只亮了一半,开发板分辨率:480*272,马上想到是行或列的参数错误。

    parameter       ROW_NUM     = 480

             ,parameter      COL_NUM       = 272(H_ACTIVE),即列对应行同步信号。列应该是480=COL_NUM ,行是对应着场同步信号,即行是272=ROW_NUM

    五下板实验效果

     
  • 相关阅读:
    电子海图开发一百篇第五十五篇-电子江图传输规范 数据模型
    天气可视化,海浪,温度图层的绘制,温度热力图的可视化
    全球潮汐数据API使用方法,潮汐数据查询
    海洋气象数据可视化,以流场的方式显示风场图,海洋气象API使用
    g++ 编译module失败
    编译gcc error-*** LIBRARY_PATH shouldn‘t contain the current directory when *** building gcc.
    windows两种自启动的区别
    windows多线程加锁
    windows server 2012不显示此电脑
    pthread_cond_wait
  • 原文地址:https://www.cnblogs.com/Xwangzi66/p/14364849.html
Copyright © 2020-2023  润新知