资讯动态

FPGA驱动TFT-LCD:RGB彩条测试工程原理与调屏避坑指南

发布时间:2026/10/20 18:05:18 来源:尧图企业网站定制
简介面向FPGA入门与嵌入式进阶开发者这份完整的Altera Quartus工程演示了如何用FPGA驱动RGB接口TFT液晶屏并输出彩条覆盖像素时钟、行/列同步HSync/VSync生成、RGB并行数据发送等核心时序逻辑工程以Altera器件为平台。资源共126个文件约3.43MB包含7个Verilog源码文件、QSF/QPF工程配置、SOF比特流以及编译过程生成的cdb/hdb等数据库文件并附txt/readme/md说明文档Verilog源码为主逻辑QSF/QPF用于重建工程SOF可直接下载验证说明文档帮助上手排错。已有1720人浏览学习。开发者可据此快速搭建RGB LCD驱动环境复用彩条显示模块理解HSync/VSync与像素时钟的配合关系工程中的帧缓冲、时钟生成及调试思路也可迁移到其他显示方案。1. 先看这个 RAR 到底救了什么FPGA 调屏与 RGB 彩条第一次拿到带 TFT 屏的板子最怕的不是代码编译不过而是屏幕亮起来全是花屏或者白屏。到底是复位没拉对还是像素时钟差了几兆又或者只是 RGB 数据线松了一根这时候硬猜会把人逼疯。我习惯的做法是先跑一遍 fpga 彩条工程让屏幕按标准顺序显示白、黄、青、绿、品红、红、蓝、黑八条竖条纹眼睛扫一眼就能判断链路状态。tft_rgb_colorbar 这个 rar 就是这样一个基于 Verilog 的测试工程面向想快速验证 TFT 面板与 FPGA 之间接线、时序参数和颜色编码的开发者。不管你是刚接触 FPGA 的新手还是调屏调到头秃的老手这套固定彩条都比对着逻辑分析仪盲猜高效得多。2. 系统设计从像素时钟到 RGB 输出的完整链路2.1 拿到 .rar 先看这四类文件工程骨架比我之前想的清爽解压 tft_rgb_colorbar.rar 之后里面不是散落一堆 .v 文件而是按 RTL、约束、仿真、文档分好的标准工程结构。我见过太多丢三落四的 demo这个包里该有的东西基本都齐了tft_rgb_colorbar/ ├── rtl/ │ ├── tft_rgb_colorbar_top.v # 顶层模块 │ ├── clk_gen.v # 像素时钟生成PLL 包装 │ ├── tft_timing_gen.v # 行场同步、DE 与像素坐标生成 │ └── colorbar_gen.v # 彩条颜色生成 ├── con/ │ └── tft_colorbar.xdc # 引脚约束和时序约束 ├── sim/ │ ├── tb_tft_rgb_colorbar.v # 仿真顶层 │ └── tb_run.tcl # 一键跑仿真脚本 └── README.md # 使用说明和屏参记录这套结构的好处是职责分离clk_gen只管产生像素时钟tft_timing_gen只负责把时序跑对colorbar_gen只根据坐标给像素上色顶层就做实例化和连线。改屏参数时不用翻整个工程改颜色时也不怕碰坏时序。如果你之前拿到过一个几百行全堆在 top 里的 fpga 工程再看这个会觉得清爽不少。2.2 屏幕时序参数H_ACTIVE、H_FP、H_SYNC 这些数字从哪来所有调屏的血泪经验最后都会指向同一个源头屏幕数据手册里的时序图。tft_rgb_colorbar 工程里预设的是一块常见的 800x480 RGB TFT像素时钟大约 33.3MHz刷新率约 60Hz。我习惯先把这些参数抄到 README 里再写进代码避免下次翻车。参数值说明H_ACTIVE800每行有效像素数H_SYNC128行同步脉冲宽度H_BP88行后肩H_FP40行前肩V_ACTIVE480有效行数V_SYNC2帧同步脉冲宽度V_BP30帧后肩V_FP13帧前肩H_TOTAL1056行总周期等于 128 88 800 40V_TOTAL525帧总行数等于 2 30 480 13把这些数代进去算一下33.3MHz 除以 1056 再除以 525正好约等于 60Hz这个刷新率是合理的。如果你的屏是 480x272 或者 1280x800不要照抄而应以规格书 tming 参数为准。工程里这些参数都做成了 parameter改起来不用动逻辑。2.3 顶层模块的信号约定所有线头都汇到 tft_rgb_colorbar_top顶层模块的角色就是一个接线盒。输入只有外部晶振时钟和复位剩下的信号都输出到 TFT 排针。下面是精简后的顶层结构module tft_rgb_colorbar_top #( parameter H_ACTIVE 800, parameter H_SYNC 128, parameter H_BP 88, parameter H_FP 40, parameter V_ACTIVE 480, parameter V_SYNC 2, parameter V_BP 30, parameter V_FP 13 )( input wire clk_ref, input wire rst_n, output wire pclk, output wire hsync, output wire vsync, output wire de, output wire [7:0] data_r, output wire [7:0] data_g, output wire [7:0] data_b, output wire lcd_bl ); wire clk_pixel; wire locked; wire [11:0] hcnt, vcnt; clk_gen u_clk_gen( .clk_ref (clk_ref), .rst_n (rst_n), .clk_out (clk_pixel), .locked (locked) ); assign pclk clk_pixel; tft_timing_gen #( .H_ACTIVE(H_ACTIVE), .H_SYNC(H_SYNC), .H_BP(H_BP), .H_FP(H_FP), .V_ACTIVE(V_ACTIVE), .V_SYNC(V_SYNC), .V_BP(V_BP), .V_FP(V_FP) ) u_timing( .pclk (clk_pixel), .rst_n (rst_n locked), .hsync (hsync), .vsync (vsync), .de (de), .hcnt (hcnt), .vcnt (vcnt) ); colorbar_gen u_colorbar( .pclk (clk_pixel), .rst_n (rst_n locked), .de (de), .hcnt (hcnt), .vcnt (vcnt), .data_r(data_r), .data_g(data_g), .data_b(data_b) ); assign lcd_bl 1b1; endmodule注意rst_n locked这个细节外部复位虽然拉起来了但如果 FPGA 内部的时钟 IP 还没锁定从clk_gen出来的时钟可能是不完整的直接驱动时序模块会产生奇怪的毛刺。加上locked是为了让时序模块在时钟稳定之后再开始跑。lcd_bl是背光使能调试阶段直接拉高是最省事的做法有些屏的背光引脚是低有效这一步要看原理图。3. 核心模块拆解彩色条纹是怎么从坐标算出来的3.1 时序生成让像素坐标规规整整走完一帧TFT 显示的物理过程可以理解成一条扫描线从左上角走到右下角。tft_timing_gen.v里的核心就是两个计数器hcnt计数当前行内的像素序号vcnt计数当前是第几行。每次hcnt走到H_TOTAL - 1时回 0同时vcnt加 1vcnt走到V_TOTAL - 1时整帧结束回到第 1 行。这段逻辑我抽出来看localparam H_START H_SYNC H_BP; localparam H_END H_START H_ACTIVE - 1; localparam V_START V_SYNC V_BP; localparam V_END V_START V_ACTIVE - 1; always (posedge pclk or negedge rst_n) begin if (!rst_n) begin hcnt 0; vcnt 0; end else begin if (hcnt H_TOTAL - 1) begin hcnt 0; if (vcnt V_TOTAL - 1) vcnt 0; else vcnt vcnt 1; end else begin hcnt hcnt 1; end end end assign de (hcnt H_START) (hcnt H_END) (vcnt V_START) (vcnt V_END); assign hsync (hcnt H_SYNC) ? 1b0 : 1b1; assign vsync (vcnt V_SYNC) ? 1b0 : 1b1;这里H_START等于同步脉宽加后肩即有效区从同步结束后的第 216 个像素开始持续 800 个像素到 1015 结束。de信号就是有效显示窗口之后第 5 章二次开发时你会频繁用到它。可能有人会问为什么直接用de而不用hsync/vsync去锁数据。因为现在很多 RGB TFT 都支持 DE 同步模式DE 有效时送出颜色数据DE 无效时送 0就能避免花屏同步模式反而对时序要求更严格极性一错就滚屏。这个工程默认以 DE 为主行场同步只是按照屏规约拉出来属于双兼容做法。3.2 彩条生成用坐标区间给每个像素上色有了坐标之后彩条生成就是纯粹的翻译工作。标准彩条从左到右依次是白、黄、青、绿、品红、红、蓝、黑800 像素分成 8 段每段 100 像素。colorbar_gen.v里不需要复杂的除法直接比较横坐标落在哪个区间module colorbar_gen #( parameter H_START 216, parameter H_ACTIVE 800 )( input wire pclk, input wire rst_n, input wire de, input wire [11:0] hcnt, input wire [11:0] vcnt, output reg [7:0] data_r, output reg [7:0] data_g, output reg [7:0] data_b ); wire [11:0] h_act hcnt - H_START; always (posedge pclk or negedge rst_n) begin if (!rst_n) begin data_r 8h00; data_g 8h00; data_b 8h00; end else if (!de) begin data_r 8h00; data_g 8h00; data_b 8h00; end else if (h_act 100) begin data_r 8hFF; data_g 8hFF; data_b 8hFF; // 白 end else if (h_act 200) begin data_r 8hFF; data_g 8hFF; data_b 8h00; // 黄 end else if (h_act 300) begin data_r 8h00; data_g 8hFF; data_b 8hFF; // 青 end else if (h_act 400) begin data_r 8h00; data_g 8hFF; data_b 8h00; // 绿 end else if (h_act 500) begin data_r 8hFF; data_g 8h00; data_b 8hFF; // 品红 end else if (h_act 600) begin data_r 8hFF; data_g 8h00; data_b 8h00; // 红 end else if (h_act 700) begin data_r 8h00; data_g 8h00; data_b 8hFF; // 蓝 end else begin data_r 8h00; data_g 8h00; data_b 8h00; // 黑 end end endmodule这段代码里最容易漏掉的是!de时的置零分支。有些屏在有效区外会采样 RGB 数据如果不主动送 0残留上一段颜色屏幕边缘会出现一条彩色尾巴。h_act是用hcnt减H_START得到的有效横坐标范围是 0 到 799注意它不能直接在de为低时使用因为此时hcnt小于H_START相减会得到一个非常大的数所以一定要先把de拿来兜底。vcnt在这个模块里没有参与颜色计算因为竖条纹只和横坐标有关如果你想做横向渐变条再把vcnt用上。3.3 仿真用几行 testbench 检查一行帧时序仿真不是走形式仿真过了至少能证明两个坐标计数器的行为是对的。这个包里的sim/tb_tft_rgb_colorbar.v写法很朴素module tb_tft_rgb_colorbar; reg clk_ref 0; reg rst_n 0; wire pclk, hsync, vsync, de; wire [7:0] data_r, data_g, data_b; always #10 clk_ref ~clk_ref; tft_rgb_colorbar_top dut( .clk_ref (clk_ref), .rst_n (rst_n), .pclk (pclk), .hsync (hsync), .vsync (vsync), .de (de), .data_r (data_r), .data_g (data_g), .data_b (data_b), .lcd_bl () // 仿真时悬空 ); initial begin rst_n 0; #100 rst_n 1; #50_000_000 $finish; end always (posedge pclk) begin if (hcnt 0) $display(Frame: vsync%b hsync%b vcnt%d, vsync, hsync, vcnt); end endmodule跑仿真时重点关注几个点hsync的低脉冲宽度要在H_SYNC个像素时钟内de连续高电平的周期数应当是H_ACTIVE也就是 800vcnt到 524 之后跳回 0完成一帧。如果在波形上看到de只高了 799 拍或者 hsync 不对称先回 3.1 检查参数是不是被覆盖了。仿真看到的data_r/data_g/data_b在de为高时会按彩条顺序变化这就代表数据链路正确。4. 避坑指南TFT 彩条上板最常见的五个翻车现场4.1 现象一屏一直白屏彩条根本没出来白屏大概率意味着背光亮了但没有有效数据进入屏。我遇到第一次调这块屏时复位和时钟都拉对了综合也过了屏幕仍然全白。原因出在clk_gen的locked没有接进时序模块的复位外部复位拉高后时序模块立刻开跑而当时的像素时钟还在漂产生了大量无效跳变导致 de 从未正确拉高。解决方法是像 2.3 里那样写rst_n locked并且加一个仿真 log打印locked值确认时钟 IP 没有报错。上板前可以用板上 LED 引一个 status看到灯亮再收工否则就是时钟问题优先排查。4.2 现象二颜色顺序错乱红绿蓝互换屏幕能显示条纹但白色变成了绿色或者原本红色变蓝这种问题基本不是 FPGA 逻辑的问题而是 RGB 数据线接错或者位序映射不对。这个工程输出的是 RGB888 三个 8 位通道但很多屏的驱动板实际只引出了 18 位需要丢弃低位。如果接口定义里 RGB 顺序是 BGR数据必须交叉接线。解决方法是先别改代码拿放大镜对着转接板原理图看确认数据标号如果硬件固定不能换线就在colorbar_gen的端口赋值上做一次手工交叉映射即把红色通道接到屏的蓝色引脚其他通道同理让逻辑适配物理接线。4.3 现象三画面横滚或上下跳图像像被撕裂横滚最常见的直接原因是行同步极性反了。TFT 屏规格书里如果写HSYNC: Negative而工程里默认低有效代码会输出hcnt H_SYNC拉低应该没问题但如果规格书是正极性你需要把那句改为hcnt H_SYNC时拉低。还有一种情况是同时接入了 DE 模式和行场同步模式屏内部优先选了一个与外部冲突的信号导致画面整体偏移。解决方法是临时把de直接拉低只保留 hsync/vsync 跑一帧看是否滚屏如果滚屏说明 DE 模式的输出和同步冲突需要检查约束文件里是不是把 DE 引脚误接到了同步脚。4.4 现象四屏幕明显闪烁刷新率掉到 45Hz 以下800x480 跑到 33.3MHz 是 60Hz如果实际像素时钟只有 25MHz刷新率就会掉到 45Hz 左右肉眼可见闪烁。有时综合工具会把clk_gen的参数记错生成 27MHz 或 24MHz 的时钟flash 里被告警过但你忽略了。解决方法是不要只看倍频系数直接把pclk引到一个测试脚用示波器或者频率计量一下确认是 33.3MHz。更稳妥的办法是在 testbench 里用仿真测量两帧间隔打印出刷新率和屏规格书对一下再上板。4.5 现象五上板后亮度极暗只有边角有隐约图案这个现象背后十有八九是背光没有完全打开。很多 RGB TFT 的背光使能引脚是开漏输出外部必须上拉而 FPGA 的 IO 默认弱下拉代码里lcd_bl 1b1虽然写了但引脚约束可能没加PULLUP相当于悬空。还有一个坑是背光信号别和某个低频时钟共用一个管脚否则背光会被周期性关断亮度看起来忽明忽暗。解决方法是暂时把背光引脚绑到一个固定高电平换一个专用 IO并加上拉约束如果还是暗查背光电源是否只有 3.3V而屏需要 5V。5. 二次开发把静态彩条改成可滚动动画5.1 让彩条动起来一个偏移量搞定静态彩条验证完链路之后很多人想让它看起来更像“动态”一点。其实只需要在colorbar_gen里增加一个每帧递增的偏移量再用它替代h_act参与颜色区间判断。按这个思路可以写一个简单的滚动彩条reg [9:0] offset 0; always (posedge pclk or negedge rst_n) begin if (!rst_n) offset 0; else if (de hcnt 1015) offset offset 1; // 每行有效数据结束后偏移加一速度快 end wire [11:0] h_shift (h_act offset H_ACTIVE) ? h_act offset - H_ACTIVE : h_act offset;用h_shift替换掉原本h_act所在的比较判断屏幕上的条纹就会以每行 1 个像素的速度滚动。因为偏移量最大 799 加最大坐标 799 不会超过 1600做一次减法就能回绕。想控制速度就把加一的条件从每行改成每帧一次也就是检测vcnt到边界时再加。最后说个我自己的坏习惯以前拿到新屏总想跳过彩条直接跑自己的界面代码结果经常分不清是软件问题还是硬件问题白白耗掉一整天。从那以后我每次换屏或改板子第一件事就是先把 tft_rgb_colorbar 跑一遍确认时钟、同步、RGB 数据线全通再碰业务逻辑。这个习惯帮我省下的时间远比想象中多希望帮到你。本文还有配套的精品资源点击获取

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑