verilog驱动RGB接口TFT液晶屏
1.驱动原理
驱动TFT屏幕与驱动VGA显示器的原理很相似。
行、场同步模式
DE同步模式
在正点原子的教程中有如下说明:
液晶屏有两种驱动模式,分别为行场驱动模式(HV MODE)和数据使能同步模式(DE MODE)
HV MODE:数据使能信号(DE)必须为低电平
DE MODE:行同步和场同步信号必须为高电平
但是在我实际实验的过程中,当在HV模式中,DE信号也必须正确工作,如果DE为低电平,显示的图像会错位。但是只要DE信号是正确的,行同步和场同步信号一直保持高电平或者低电平都可以正常工作。
2.模块框图![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/a070fee127a8199c2697e879c5304c6c.jpeg#pic_center)
3.时钟模块
时钟使用锁相环IP核生成,时钟频率如框图所示。
3.TFT驱动模块
module tft_ctrl (
input wire tft_clk,
input wire rst_n,
input wire [15:0] pic_data,
output wire [9:0] pic_y,
output wire [9:0] pic_x,
output wire [15:0] rgb_data,
output wire hsync,
output wire vsync,
output wire tft_de,
output wire tft_clk_out,
output wire tft_bl
);
//parameter define
parameter H_SYNC = 10'd128 , //行同步
H_BACK = 10'd88 , //行时序后沿
H_VALID = 10'd800 , //行有效数据
H_FRONT = 10'd40 , //行时序前沿
H_TOTAL = 11'd1056 ; //行扫描周期
parameter V_SYNC = 10'd2 , //场同步
V_BACK = 10'd33 , //场时序后沿
V_VALID = 10'd480 , //场有效数据
V_FRONT = 10'd10 , //场时序前沿
V_TOTAL = 10'd525 ; //场扫描周期
wire rgb_valid;//计数到有效图像时拉高
wire rgb_request;//请求RGB像素信息
reg [10:0] count_h;//行同步计数
reg [10:0] count_v;//场同步计数
assign tft_clk_out = tft_clk;
assign tft_de = rgb_valid;
assign tft_bl = rst_n;
//行同步计数
always @(posedge tft_clk or negedge rst_n) begin
if (!rst_n) begin
count_h <= 11'b0;
end
else if (count_h == H_TOTAL - 1'b1) begin
count_h <= 11'b0;
end
else
count_h <= count_h + 1'b1;
end
assign hsync =/* (count_h <= H_SYNC - 1'b1) ? 1'b1 : 1'b0*/ 1'b0 ;
//场同步计数
always @(posedge tft_clk or negedge rst_n) begin
if (!rst_n) begin
count_v <= 11'b0;
end
else if ((count_v == V_TOTAL - 1'b1) && (count_h == H_TOTAL - 1'b1)) begin
count_v <= 11'b0;
end
else if (count_h == H_TOTAL - 1'b1) begin
count_v <= count_v + 1'b1;
end
else
count_v <= count_v;
end
assign vsync = /*(count_v <= V_SYNC - 1'b1) ? 1'b1 : 1'b0 */ 1'b0 ;
//rgb信号有效rgb_valid
assign rgb_valid = (((count_h >= H_SYNC + H_BACK)
&& (count_h < H_SYNC + H_BACK + H_VALID))
&&((count_v >= V_SYNC + V_BACK)
&& (count_v < V_SYNC + V_BACK + V_VALID))) ? 1'b1 : 1'b0;
//请求RGB像素信息rgb_request
assign rgb_request = (((count_h >= H_SYNC + H_BACK - 1'b1)
&& (count_h < H_SYNC + H_BACK + H_VALID - 1'b1))
&&((count_v >= V_SYNC + V_BACK)
&& (count_v < V_SYNC + V_BACK + V_VALID))) ? 1'b1 : 1'b0;
assign pic_x = (rgb_request == 1'b1)
? (count_h - (H_SYNC + H_BACK - 1'b1)) : 10'h3ff;
assign pic_y = (rgb_request == 1'b1)
? (count_v - (V_SYNC + V_BACK )) : 10'h3ff;
//rgb_tft:输出像素点色彩信息
assign rgb_data = (rgb_valid == 1'b1) ? pic_data : 16'b0 ;
endmodule //tft_ctrl
代码中控制行同步和场同步的信号被注释掉了,只有de信号,因此工作在DE同步模式。
4.图像控制模块
module tft_pic (
input wire tft_clk,
input wire rst_n,
output reg [15:0] pic_data,
input wire [9:0] pic_y,
input wire [9:0] pic_x
);
parameter H_VALID = 10'd800 , //行有效数据
V_VALID = 10'd480 ; //场有效数据
parameter RED = 16'hF800, //红色
ORANGE = 16'hFC00, //橙色
YELLOW = 16'hFFE0, //黄色
GREEN = 16'h07E0, //绿色
CYAN = 16'h07FF, //青色
BLUE = 16'h001F, //蓝色
PURPPLE = 16'hF81F, //紫色
BLACK = 16'h0000, //黑色
WHITE = 16'hFFFF, //白色
GRAY = 16'hD69A; //灰色
//pic_data:输出像素点色彩信息,根据当前像素点坐标指定当前像素点颜色数据
always@(posedge tft_clk or negedge rst_n)
if(rst_n == 1'b0)
pic_data <= 16'd0;
else if((pic_x >= 0) && (pic_x < (H_VALID/10)*1))
pic_data <= RED;
else if((pic_x >= (H_VALID/10)*1) && (pic_x < (H_VALID/10)*2))
pic_data <= ORANGE;
else if((pic_x >= (H_VALID/10)*2) && (pic_x < (H_VALID/10)*3))
pic_data <= YELLOW;
else if((pic_x >= (H_VALID/10)*3) && (pic_x < (H_VALID/10)*4))
pic_data <= GREEN;
else if((pic_x >= (H_VALID/10)*4) && (pic_x < (H_VALID/10)*5))
pic_data <= CYAN;
else if((pic_x >= (H_VALID/10)*5) && (pic_x < (H_VALID/10)*6))
pic_data <= BLUE;
else if((pic_x >= (H_VALID/10)*6) && (pic_x < (H_VALID/10)*7))
pic_data <= PURPPLE;
else if((pic_x >= (H_VALID/10)*7) && (pic_x < (H_VALID/10)*8))
pic_data <= BLACK;
else if((pic_x >= (H_VALID/10)*8) && (pic_x < (H_VALID/10)*9))
pic_data <= WHITE;
else if((pic_x >= (H_VALID/10)*9) && (pic_x < H_VALID))
pic_data <= GRAY;
else
pic_data <= BLACK;
endmodule //tft_pic
5.顶层模块
module tft_rgb_colorbar (
input wire sys_clk,
input wire sys_rst_n,
output wire hsync,
output wire vsync,
output wire tft_de,
output wire tft_clk_out,
output wire tft_bl,
output wire [15:0] rgb_data
);
wire tft_clk;
wire locked;
wire [9:0] pic_y;
wire [9:0] pic_x;
wire [15:0] pic_data;
assign rst_n = (locked & sys_rst_n);
clk_gen u_clk_gen(
.areset (~sys_rst_n),
.inclk0 (sys_clk),
.c0 (tft_clk),
.locked (locked )
);
tft_ctrl u_tft_ctrl(
.tft_clk (tft_clk ),
.rst_n (rst_n ),
.pic_data (pic_data ),
.pic_y (pic_y ),
.pic_x (pic_x ),
.rgb_data (rgb_data ),
.hsync (hsync ),
.vsync (vsync ),
.tft_de (tft_de ),
.tft_clk_out (tft_clk_out ),
.tft_bl (tft_bl )
);
tft_pic u_tft_pic(
.tft_clk (tft_clk ),
.rst_n (rst_n ),
.pic_data (pic_data ),
.pic_y (pic_y ),
.pic_x (pic_x )
);
endmodule //tft_rgb_colorbar