正点原子zynq的RGB彩条实验

行场信号

名称 本质 对应坐标
行(H) 一行扫描 x(横向)
场(V) 一帧逐行 y(纵向)

800x480屏逻辑等价1056x525屏幕

类别 名称 数值 计数区间 含义 是否显示 本质
计数器 h_cnt --- 0 ~ 1055 一行里第几个像素 --- 横向(x)
计数器 v_cnt --- 0 ~ 524 当前第几行 --- 纵向(y)
横向 H_SYNC 128 [0, 128) 行同步 时序填充
横向 H_BACK 88 [128, 216) 行后沿 黑边
横向 H_DISP 800 [216, 1016) 行有效显示 可见像素
横向 H_FRONT 40 [1016, 1056) 行前沿 黑边
横向 H_TOTAL 1056 [0, 1056) 行扫描周期 --- 一行总长度
纵向 V_SYNC 2 [0, 2) 场同步 时序填充
纵向 V_BACK 33 [2, 35) 场后沿 黑边
纵向 V_DISP 480 [35, 515) 场有效显示 可见像素
纵向 V_FRONT 10 [515, 525) 场前沿 黑边
纵向 V_TOTAL 525 [0, 525) 场扫描周期 --- 一帧总高度

扫描方向

bash 复制代码
pclk ↑   ⟹ h_cnt++; 
h_cnt 满 ⟹ v_cnt++
# 扫描展开:
v_cnt = 0 			⟹ → → → → →
v_cnt = 1 			⟹ → → → → →
v_cnt = 2 			⟹ → → → → →
...                 ⟹ → → → → →
v_cnt = V_TOTAL-1   ⟹ → → → → →
bash 复制代码
        行内计数h_cnt →
        0                                                1055
        │----------------------------------------------│
        
v_cnt ↓ │ H_SYNC │ H_BACK │      H_DISP      │ H_FRONT │
        │  128   │   88   │       800        │   40    │
        
0       ├────────┼────────┼──────────────────┼─────────┤
        │                V_SYNC (2 行)                 │
2       ├──────────────────────────────────────────────┤
        │                V_BACK (33 行)                │
35      ├────────┬────────┬──────────────────┬─────────┤
        │        │        │                  │         │
        │        │        │   有效显示区      │         │
        │        │        │   800 × 480       │        │
        │        │        │                  │         │
515     ├────────┴────────┴──────────────────┴─────────┤
        │               V_FRONT (10 行)                │
524     └──────────────────────────────────────────────┘

LCD / FPS / 时钟计算

ffps=fpclkHtotal×Vtotalf_{fps} = \frac{f_{pclk}}{H_{total} \times V_{total}}ffps=Htotal×Vtotalfpclk (帧率 = 像素时钟 / 一帧像素总数)\quad \text{(帧率 = 像素时钟 / 一帧像素总数)}(帧率 = 像素时钟 / 一帧像素总数)

fpclk=ffps×Htotal×Vtotalf_{pclk} = f_{fps} \times H_{total} \times V_{total}fpclk=ffps×Htotal×Vtotal (像素时钟 = 帧率 × 一帧像素总数)\quad \text{(像素时钟 = 帧率 × 一帧像素总数)}(像素时钟 = 帧率 × 一帧像素总数)

lcd_rgb_colorbar.v

verilog 复制代码
module lcd_rgb_colorbar(
    input               i_sys_clk,     // 系统时钟输入(pixel clock / PLL源)
    input               i_sys_rst_n,   // 系统复位(低有效)
    //========================
    // RGB LCD 控制接口输出
    //========================
    output              o_lcd_de,      // 数据有效使能(Data Enable)
    output              o_lcd_hs,      // 行同步信号(HSYNC)
    output              o_lcd_vs,      // 场同步信号(VSYNC)
    output              o_lcd_bl,      // 背光控制(Back Light)
    output              o_lcd_clk,     // LCD像素时钟输出
    output              o_lcd_rst,     // LCD复位信号(低有效/高有效视屏而定)
    output      [23:0]  o_lcd_rgb      // RGB888像素数据输出(R[23:16] G[15:8] B[7:0])
);

//====================================================
// wire
//====================================================
wire w_lcd_pclk;

wire [10:0] w_pixel_xpos;
wire [10:0] w_pixel_ypos;
wire [10:0] w_h_disp;
wire [10:0] w_v_disp;

wire [23:0] w_pixel_data;

//====================================================
// clk
//====================================================
clk_div u_clk_div(
    .i_clk      (i_sys_clk),
    .i_rst_n    (i_sys_rst_n),
    .o_pclk (w_lcd_pclk)
);

//====================================================
// display
//====================================================
lcd_display u_lcd_display(
    .i_lcd_pclk (w_lcd_pclk),
    .i_rst_n    (i_sys_rst_n),

    .i_x_pos    (w_pixel_xpos),
    .i_y_pos    (w_pixel_ypos),
    .i_h_disp   (w_h_disp),
    .i_v_disp   (w_v_disp),

    .o_pixel_data(w_pixel_data)
);

//====================================================
// driver
//====================================================
lcd_driver u_lcd_driver(
    .i_lcd_pclk (w_lcd_pclk),
    .i_rst_n    (i_sys_rst_n),

    .i_pixel_data(w_pixel_data),

    .o_pixel_xpos(w_pixel_xpos),
    .o_pixel_ypos(w_pixel_ypos),
    .o_h_disp   (w_h_disp),
    .o_v_disp   (w_v_disp),

    .o_data_req (),

    .o_lcd_de   (o_lcd_de),
    .o_lcd_hs   (o_lcd_hs),
    .o_lcd_vs   (o_lcd_vs),
    .o_lcd_bl   (o_lcd_bl),
    .o_lcd_clk  (o_lcd_clk),
    .o_lcd_rst  (o_lcd_rst),
    .o_lcd_rgb  (o_lcd_rgb)
);

endmodule

clk_div.v

verilog 复制代码
module clk_div #(
    parameter DIV = 2   
)(
    input           i_clk,
    input           i_rst_n,

    output          o_clk_en,   // 时钟使能
    output          o_pclk      // 可选:分频时钟
);

//====================================================
// 内部信号
//====================================================
reg [$clog2(DIV)-1:0] r_cnt;
reg                   r_clk_en;
reg                   r_pclk;


//====================================================
// 分频逻辑
//====================================================
always @(posedge i_clk or negedge i_rst_n) begin
    if (!i_rst_n) begin
        r_cnt    <= 0;
        r_clk_en <= 1'b0;
        r_pclk   <= 1'b0;
    end else begin
        if (r_cnt == DIV/2 - 1) begin
            r_cnt    <= 0;
            r_clk_en <= 1'b1;      
            r_pclk   <= ~r_pclk;   
        end else begin
            r_cnt    <= r_cnt + 1;
            r_clk_en <= 1'b0;
        end
    end
end

//====================================================
// 输出
//====================================================
assign o_clk_en = r_clk_en;
assign o_pclk   = r_pclk;

endmodule

lcd_driver.v

verilog 复制代码
//*******************************************************
//** Module name: lcd_driver (Fixed 4.3' 800*480)
//*******************************************************
module lcd_driver(
    input                i_lcd_pclk,    //时钟
    input                i_rst_n,       //复位,低电平有效
    input        [23:0]  i_pixel_data,  //像素数据

    output  reg  [10:0]  o_pixel_xpos,  //当前像素点横坐标
    output  reg  [10:0]  o_pixel_ypos,  //当前像素点纵坐标   
    output  reg  [10:0]  o_h_disp,      //LCD屏水平分辨率 (固定输出)
    output  reg  [10:0]  o_v_disp,      //LCD屏垂直分辨率 (固定输出)
    output  reg          o_data_req,    //数据请求信号

    //RGB LCD接口
    output  reg         o_lcd_de,      //LCD 数据使能信号
    output               o_lcd_hs,      //LCD 行同步信号
    output               o_lcd_vs,      //LCD 场同步信号
    output               o_lcd_bl,      //LCD 背光控制信号
    output               o_lcd_clk,     //LCD 像素时钟
    output               o_lcd_rst,     //LCD复位
    output       [23:0]  o_lcd_rgb      //LCD RGB888颜色数据
    );

//*********** 4.3' 800*480 参数定义 (固定) ***********
// 这些参数直接取自原代码中的 H_SYNC_4384 等定义
parameter  H_SYNC      =  11'd128;    //行同步
parameter  H_BACK      =  11'd88;     //行显示后沿
parameter  H_DISP      =  11'd800;    //行有效数据 (分辨率宽)
parameter  H_FRONT     =  11'd40;     //行显示前沿
parameter  H_TOTAL     =  11'd1056;   //行扫描周期

parameter  V_SYNC      =  11'd2;      //场同步
parameter  V_BACK      =  11'd33;     //场显示后沿
parameter  V_DISP      =  11'd480;    //场有效数据 (分辨率高)
parameter  V_FRONT     =  11'd10;     //场显示前沿
parameter  V_TOTAL     =  11'd525;    //场扫描周期

//reg define
reg  [10:0] h_cnt;                    //行计数器
reg  [10:0] v_cnt;                    //场计数器

//**************************************************
//**                    main code
//**************************************************

//RGB LCD 采用DE模式时,行场同步信号需要拉高
assign  o_lcd_hs  = 1'b1;        
assign  o_lcd_vs  = 1'b1;        
assign  o_lcd_bl  = 1'b1;        
assign  o_lcd_clk = i_lcd_pclk;   
assign  o_lcd_rst = 1'b1;        

//RGB888数据输出
assign o_lcd_rgb = o_lcd_de ? i_pixel_data : 24'd0;

//像素点x坐标
always@ (posedge i_lcd_pclk or negedge i_rst_n) begin
    if(!i_rst_n)
        o_pixel_xpos <= 11'd0;
    else if(o_data_req)
        // 计算当前像素在屏幕内的X位置
        o_pixel_xpos <= h_cnt - H_SYNC - H_BACK; 
    else 
        o_pixel_xpos <= 11'd0;
end
   
//像素点y坐标   
always@ (posedge i_lcd_pclk or negedge i_rst_n) begin
    if(!i_rst_n)
        o_pixel_ypos <= 11'd0;
    else if(o_data_req)
        o_pixel_ypos <= v_cnt - V_SYNC - V_BACK;
    else 
        o_pixel_ypos <= 11'd0;
end

// 固定分辨率输出 (供外部模块使用)
always @(*) begin
    o_h_disp = H_DISP;
    o_v_disp = V_DISP;
end

//数据使能信号 (固定逻辑)
always@ (posedge i_lcd_pclk or negedge i_rst_n) begin
    if(!i_rst_n)    
        o_data_req <= 1'b0;
    else if( (h_cnt >= H_SYNC + H_BACK) && (h_cnt < H_SYNC + H_BACK + H_DISP) &&
             (v_cnt >= V_SYNC + V_BACK) && (v_cnt < V_SYNC + V_BACK + V_DISP) )
        o_data_req <= 1'b1;
    else
        o_data_req <= 1'b0;
end

//行计数器对像素时钟计数
always@ (posedge i_lcd_pclk or negedge i_rst_n) begin
    if(!i_rst_n) 
        h_cnt <= 11'd0;
    else begin
        if(h_cnt == H_TOTAL - 1'b1)
            h_cnt <= 11'd0;
        else
            h_cnt <= h_cnt + 1'b1;           
    end
end

//场计数器对行计数
always@ (posedge i_lcd_pclk or negedge i_rst_n) begin
    if(!i_rst_n) 
        v_cnt <= 11'd0;
    else begin
        if(h_cnt == H_TOTAL - 1'b1) begin
            if(v_cnt == V_TOTAL - 1'b1)
                v_cnt <= 11'd0;
            else
                v_cnt <= v_cnt + 1'b1;    
        end
    end    
end

//数据使能信号延迟寄存(DE)
always@ (posedge i_lcd_pclk or negedge i_rst_n) begin
    if(!i_rst_n)    
        o_lcd_de <= 1'b0;
    else
        o_lcd_de <= o_data_req;
end

endmodule

lcd_display.v

verilog 复制代码
module lcd_display(
    input                i_lcd_pclk,    //时钟
    input                i_rst_n,       //复位,低电平有效
    input        [10:0]  i_x_pos,       //当前像素点横坐标
    input        [10:0]  i_y_pos,       //当前像素点纵坐标  
    input        [10:0]  i_h_disp,      //LCD屏水平分辨率
    input        [10:0]  i_v_disp,      //LCD屏垂直分辨率       
    output  reg  [23:0]  o_pixel_data   //像素数据
    );

//parameter define  
parameter WHITE = 24'hFFFFFF;  //白色
parameter BLACK = 24'h000000;  //黑色
parameter RED   = 24'hFF0000;  //红色
parameter GREEN = 24'h00FF00;  //绿色
parameter BLUE  = 24'h0000FF;  //蓝色

//*****************************************************
//**                    main code
//*****************************************************

//根据当前像素点坐标指定当前像素点颜色数据,在屏幕上显示彩条
always @(posedge i_lcd_pclk or negedge i_rst_n) begin
    if(!i_rst_n)
        o_pixel_data <= BLACK;
    else begin
        if((i_x_pos >= 11'd0) && (i_x_pos < i_h_disp/5*1))
            o_pixel_data <= WHITE;
        else if((i_x_pos >= i_h_disp/5*1) && (i_x_pos < i_h_disp/5*2))    
            o_pixel_data <= BLACK;
        else if((i_x_pos >= i_h_disp/5*2) && (i_x_pos < i_h_disp/5*3))    
            o_pixel_data <= RED;   
        else if((i_x_pos >= i_h_disp/5*3) && (i_x_pos < i_h_disp/5*4))    
            o_pixel_data <= GREEN;                
        else
            o_pixel_data <= BLUE; 
    end    
end
  
endmodule

pin.xdc

bash 复制代码
create_clock -period 20.000 -name i_sys_clk -waveform {0.000 10.000} [get_ports i_sys_clk]

set_property -dict {PACKAGE_PIN U18 IOSTANDARD LVCMOS33} [get_ports i_sys_clk]
set_property -dict {PACKAGE_PIN N16 IOSTANDARD LVCMOS33} [get_ports i_sys_rst_n]

set_property -dict {PACKAGE_PIN W18 IOSTANDARD LVCMOS33} [get_ports {o_lcd_rgb[0]}]
set_property -dict {PACKAGE_PIN W19 IOSTANDARD LVCMOS33} [get_ports {o_lcd_rgb[1]}]
set_property -dict {PACKAGE_PIN R16 IOSTANDARD LVCMOS33} [get_ports {o_lcd_rgb[2]}]
set_property -dict {PACKAGE_PIN R17 IOSTANDARD LVCMOS33} [get_ports {o_lcd_rgb[3]}]
set_property -dict {PACKAGE_PIN W20 IOSTANDARD LVCMOS33} [get_ports {o_lcd_rgb[4]}]
set_property -dict {PACKAGE_PIN V20 IOSTANDARD LVCMOS33} [get_ports {o_lcd_rgb[5]}]
set_property -dict {PACKAGE_PIN P18 IOSTANDARD LVCMOS33} [get_ports {o_lcd_rgb[6]}]
set_property -dict {PACKAGE_PIN N17 IOSTANDARD LVCMOS33} [get_ports {o_lcd_rgb[7]}]
set_property -dict {PACKAGE_PIN V17 IOSTANDARD LVCMOS33} [get_ports {o_lcd_rgb[8]}]
set_property -dict {PACKAGE_PIN V18 IOSTANDARD LVCMOS33} [get_ports {o_lcd_rgb[9]}]
set_property -dict {PACKAGE_PIN T17 IOSTANDARD LVCMOS33} [get_ports {o_lcd_rgb[10]}]
set_property -dict {PACKAGE_PIN R18 IOSTANDARD LVCMOS33} [get_ports {o_lcd_rgb[11]}]
set_property -dict {PACKAGE_PIN Y18 IOSTANDARD LVCMOS33} [get_ports {o_lcd_rgb[12]}]
set_property -dict {PACKAGE_PIN Y19 IOSTANDARD LVCMOS33} [get_ports {o_lcd_rgb[13]}]
set_property -dict {PACKAGE_PIN P15 IOSTANDARD LVCMOS33} [get_ports {o_lcd_rgb[14]}]
set_property -dict {PACKAGE_PIN P16 IOSTANDARD LVCMOS33} [get_ports {o_lcd_rgb[15]}]
set_property -dict {PACKAGE_PIN V16 IOSTANDARD LVCMOS33} [get_ports {o_lcd_rgb[16]}]
set_property -dict {PACKAGE_PIN W16 IOSTANDARD LVCMOS33} [get_ports {o_lcd_rgb[17]}]
set_property -dict {PACKAGE_PIN T14 IOSTANDARD LVCMOS33} [get_ports {o_lcd_rgb[18]}]
set_property -dict {PACKAGE_PIN T15 IOSTANDARD LVCMOS33} [get_ports {o_lcd_rgb[19]}]
set_property -dict {PACKAGE_PIN Y17 IOSTANDARD LVCMOS33} [get_ports {o_lcd_rgb[20]}]
set_property -dict {PACKAGE_PIN Y16 IOSTANDARD LVCMOS33} [get_ports {o_lcd_rgb[21]}]
set_property -dict {PACKAGE_PIN T16 IOSTANDARD LVCMOS33} [get_ports {o_lcd_rgb[22]}]
set_property -dict {PACKAGE_PIN U17 IOSTANDARD LVCMOS33} [get_ports {o_lcd_rgb[23]}]

set_property -dict {PACKAGE_PIN N18 IOSTANDARD LVCMOS33} [get_ports o_lcd_hs]
set_property -dict {PACKAGE_PIN T20 IOSTANDARD LVCMOS33} [get_ports o_lcd_vs]
set_property -dict {PACKAGE_PIN U20 IOSTANDARD LVCMOS33} [get_ports o_lcd_de]
set_property -dict {PACKAGE_PIN M20 IOSTANDARD LVCMOS33} [get_ports o_lcd_bl]
set_property -dict {PACKAGE_PIN P19 IOSTANDARD LVCMOS33} [get_ports o_lcd_clk]
set_property -dict {PACKAGE_PIN L17 IOSTANDARD LVCMOS33} [get_ports o_lcd_rst]
相关推荐
FPGA-ADDA2 小时前
第六篇:多速率信号处理——抽取、插值与半带滤波器
fpga开发·信号处理·软件无线电·rfsoc·47dr
ALINX技术博客2 小时前
【黑金云课堂】VMware Ubuntu 开发环境安装教程
linux·fpga开发·fpga
LCMICRO-133108477463 小时前
国产长芯微LDC4048完全P2P替代DAC128S085,是一款 8 通道、带输出放大器的数模转换器 (DAC)
stm32·单片机·嵌入式硬件·fpga开发·硬件工程·数模转换器dac
雅斯驰3 小时前
逐周期限流+频率折返+热关断:TPS54360DDAR的全套保护机制解析
fpga开发
雅斯驰3 小时前
电流模式控制+快速瞬态响应:LTM4650AY的FPGA供电技术解析
stm32·单片机·嵌入式硬件·物联网·fpga开发·汽车
北京青翼科技16 小时前
青翼科技PCIe总线架构的2路10G光纤通道适配器丨数据采集卡丨PCIe接口板卡 2 路 SFP+光纤收发器
fpga开发·采集卡·fpga板卡·pcie接口·多功能板卡
9527华安18 小时前
2026年FPGA就业培训,临时抱佛脚版本
fpga开发
水云桐程序员18 小时前
Quartus II集成开发环境 |FPGA
笔记·fpga开发·硬件工程·创业创新
XINVRY-FPGA2 天前
XC7VX690T-2FFG1157I Xilinx AMD Virtex-7 FPGA
arm开发·人工智能·嵌入式硬件·深度学习·fpga开发·硬件工程·fpga