LCD彩条显示——FPGA学习笔记10

2024-09-07 14:44

本文主要是介绍LCD彩条显示——FPGA学习笔记10,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

                                                                                                                        部分素材来自原子哥

一、LCD简介

        基本原理:在两块平行玻璃板中填充液晶材料,通过电场控制液晶分子旋转从而达到透光和遮光的目的。

LCD屏幕重要参数:分辨率、像素格式、驱动时序

分辨率:

像素格式:

        RGB:由红 绿 蓝三种颜色通道构成,这三种颜色的分量叠加决定实际颜色;通常,会给RGB图像加一个通道alpha,即透明度,这样就会有四个分量共同控制颜色。

        YUV:YUV是编译true-color颜色空间(color space)的种类,Y'UV, YUV, YCbCrYPbPr等专有名词都可以称为YUV,彼此有重叠。“Y”表示明亮度(LuminanceLuma),也就是灰阶值,“U”和“V”表示的则是色度(ChrominanceChroma),作用是描述影像色彩及饱和度,用于指定像素的颜色。

格式转换:

驱动时序:

VSYNC:场同步信号        一帧信号的起始标志(切换下一张图片的标志)

VBP:场同步后沿

VFP:场同步前沿

HSYNC:行同步信号        切换下一行的标志

HBP:行同步后沿

HFP:行同步前沿

(行场同步前后沿统称消隐时间)

LCD屏幕参数:注意行显示周期单位是CLK,场显示周期是行

LCD行同步时序(DE):

可以使用DE做数据有效信号,DE拉高时,给出DATA数据。

LCD帧同步时序(DE):

可以使用DE做数据有效信号,DE拉高时,对DE进行计数,第一次拉高给出第一行数据,第二次拉高给出第二行数据........以此类推。

LCD屏幕接口:

LCD_RSTLCD复位信号
LCD_BL

背光

LCD_DE数据有效

二、实验任务

        本节的实验任务是使用正点原子开发板上的RGB TFT-LCD接口,驱动RGB LCD液晶屏(支持目前推出的所有RGB LCD屏),并显示出彩条。

三、程序设计

        1、框架设计

2、时序设计

(1)rd_id:

(2)clk_div:

(3) lcd_driver:

(4)lcd_display

(5)完整程序框架

3、波形时序图、代码编写

 (1)rd_id:

`timescale 1ns / 1psmodule rd_id(
input                   sys_clk     ,
input                   sys_rst_n   ,
input           [23:0]  lcd_rgb     ,
output  reg     [15:0]  lcd_id);reg  rd_flag;always @(posedge sys_clk or negedge sys_rst_n ) beginif (!sys_rst_n) beginrd_flag <= 1'b0;lcd_id  <= 15'd0;endelse beginif (rd_flag == 1'b0) beginrd_flag <= 1'b1;case ({lcd_rgb[7],lcd_rgb[15],lcd_rgb[23]})//BGR3'b000: lcd_id <= 16'h4342;     //4.3' RGB-LCD RES:480x2723'b001: lcd_id <= 16'h7084;     //7' RGB-LCD RES:800x4803'b010: lcd_id <= 16'h7016;     //7' RGB-LCD RES:1024x6003'b100: lcd_id <= 16'h4384;     //4.3' RGB-LCD RES:800x4803'b101: lcd_id <= 16'h1018;     //10' RGB-LCD RES:1280x800default: ;endcaseendend
endendmodule

(2)clk_div:(使用4384屏幕,驱动时钟25M)

`timescale 1ns / 1psmodule clk_div(
input           sys_clk     ,
input           sys_rst_n   ,
input   [15:0]  lcd_id      ,
output  reg     lcd_pclk);reg     div_4_cnt;
reg     clk_25M;
reg     clk_12_5M;//25Mhz时钟
always @(posedge sys_clk or negedge sys_rst_n ) beginif (!sys_rst_n) beginclk_25M <= 1'b0;endelse beginclk_25M <= !clk_25M;end
end//12.5Mhz时钟
//位宽为1,会自动溢出,无需手动清零
always @(posedge sys_clk or negedge sys_rst_n ) beginif (!sys_rst_n) begindiv_4_cnt <= 1'b0;clk_12_5M <= 1'b0;end    else beginif (div_4_cnt == 1'b1) beginclk_12_5M <= !clk_12_5M;endelse beginclk_12_5M <= clk_12_5M;endend
end//使用组合逻辑进行赋值
always @(*) begincase (lcd_id)16'h4342: lcd_pclk = clk_12_5M     ;16'h7084: lcd_pclk = clk_25M       ;16'h7016: lcd_pclk = sys_clk       ;16'h4384: lcd_pclk = clk_25M       ;16'h1018: lcd_pclk = sys_clk       ;default:  lcd_pclk = 1'b0          ;endcase
endendmodule

 (3) lcd_driver:

`timescale 1ns / 1ps
//LCD屏幕驱动
module lcd_driver(
input               lcd_pclk         ,           //时钟
input               sys_rst_n       ,           //复位,低电平有效
input       [14:0]  lcd_id          ,           //LCD屏ID
input       [23:0]  pixel_data      ,           //像素数据output              lcd_clk         ,           //LCD 像素时钟       
output              lcd_hs          ,           //LCD 行同步信号   
output              lcd_vs          ,           //LCD 场同步信号   
output              lcd_bl          ,           //LCD 背光控制信号  
output  reg         lcd_de          ,           //LCD 数据使能信号   
output              lcd_rst         ,           //LCD 屏幕复位信号      
output      [23:0]  lcd_rgb         ,           //LCD RGB888颜色数据       
output      [10:0]  pixel_xpos      ,           //当前像素点横坐标       
output      [10:0]  pixel_ypos      ,           //当前像素点纵坐标        
output  reg [10:0]  h_disp          ,           //LCD屏水平分辨率   
output  reg [10:0]  v_disp          ,           //LCD屏垂直分辨率   
output  reg         data_req                    //LCD屏幕 数据请求信号    );// 4.3' 480*272
parameter  H_SYNC_4342   =  11'd41;     //行同步
parameter  H_BACK_4342   =  11'd2;      //行显示后沿
parameter  H_DISP_4342   =  11'd480;    //行有效数据
parameter  H_FRONT_4342  =  11'd2;      //行显示前沿
parameter  H_TOTAL_4342  =  11'd525;    //行扫描周期parameter  V_SYNC_4342   =  11'd10;     //场同步
parameter  V_BACK_4342   =  11'd2;      //场显示后沿
parameter  V_DISP_4342   =  11'd272;    //场有效数据
parameter  V_FRONT_4342  =  11'd2;      //场显示前沿
parameter  V_TOTAL_4342  =  11'd286;    //场扫描周期// 7' 800*480   
parameter  H_SYNC_7084   =  11'd128;    //行同步
parameter  H_BACK_7084   =  11'd88;     //行显示后沿
parameter  H_DISP_7084   =  11'd800;    //行有效数据
parameter  H_FRONT_7084  =  11'd40;     //行显示前沿
parameter  H_TOTAL_7084  =  11'd1056;   //行扫描周期parameter  V_SYNC_7084   =  11'd2;      //场同步
parameter  V_BACK_7084   =  11'd33;     //场显示后沿
parameter  V_DISP_7084   =  11'd480;    //场有效数据
parameter  V_FRONT_7084  =  11'd10;     //场显示前沿
parameter  V_TOTAL_7084  =  11'd525;    //场扫描周期 // 7' 1024*600   
parameter  H_SYNC_7016   =  11'd20;     //行同步
parameter  H_BACK_7016   =  11'd140;    //行显示后沿
parameter  H_DISP_7016   =  11'd1024;   //行有效数据
parameter  H_FRONT_7016  =  11'd160;    //行显示前沿
parameter  H_TOTAL_7016  =  11'd1344;   //行扫描周期parameter  V_SYNC_7016   =  11'd3;      //场同步
parameter  V_BACK_7016   =  11'd20;     //场显示后沿
parameter  V_DISP_7016   =  11'd600;    //场有效数据
parameter  V_FRONT_7016  =  11'd12;     //场显示前沿
parameter  V_TOTAL_7016  =  11'd635;    //场扫描周期// 10.1' 1280*800   
parameter  H_SYNC_1018   =  11'd10;     //行同步
parameter  H_BACK_1018   =  11'd80;     //行显示后沿
parameter  H_DISP_1018   =  11'd1280;   //行有效数据
parameter  H_FRONT_1018  =  11'd70;     //行显示前沿
parameter  H_TOTAL_1018  =  11'd1440;   //行扫描周期parameter  V_SYNC_1018   =  11'd3;      //场同步
parameter  V_BACK_1018   =  11'd10;     //场显示后沿
parameter  V_DISP_1018   =  11'd800;    //场有效数据
parameter  V_FRONT_1018  =  11'd10;     //场显示前沿
parameter  V_TOTAL_1018  =  11'd823;    //场扫描周期// 4.3' 800*480   
parameter  H_SYNC_4384   =  11'd128;    //行同步
parameter  H_BACK_4384   =  11'd88;     //行显示后沿
parameter  H_DISP_4384   =  11'd800;    //行有效数据
parameter  H_FRONT_4384  =  11'd40;     //行显示前沿
parameter  H_TOTAL_4384  =  11'd1056;   //行扫描周期parameter  V_SYNC_4384   =  11'd2;      //场同步
parameter  V_BACK_4384   =  11'd33;     //场显示后沿
parameter  V_DISP_4384   =  11'd480;    //场有效数据
parameter  V_FRONT_4384  =  11'd10;     //场显示前沿
parameter  V_TOTAL_4384  =  11'd525;    //场扫描周期 reg  [10:0] h_sync ;    //行同步
reg  [10:0] h_back ;    //行显示后沿
reg  [10:0] h_total;    //行扫描周期
reg  [10:0] v_sync ;    //场同步
reg  [10:0] v_back ;    //场显示后沿
reg  [10:0] v_total;    //场扫描周期
reg  [10:0] h_cnt  ;    //行计数
reg  [10:0] v_cnt  ;    //场计数assign  lcd_clk  =  lcd_pclk ;
assign  lcd_hs   =  1'b1     ;
assign  lcd_vs   =  1'b1     ;
assign  lcd_bl   =  1'b1     ;
assign  lcd_rst  =  1'b1     ;assign  lcd_rgb = lcd_de ? pixel_data : 24'd0;//行场时序参数
always @(posedge lcd_pclk) begincase(lcd_id)16'h4342 : beginh_sync  <= H_SYNC_4342; h_back  <= H_BACK_4342; h_disp  <= H_DISP_4342; h_total <= H_TOTAL_4342;v_sync  <= V_SYNC_4342; v_back  <= V_BACK_4342; v_disp  <= V_DISP_4342; v_total <= V_TOTAL_4342;            end16'h7084 : beginh_sync  <= H_SYNC_7084; h_back  <= H_BACK_7084; h_disp  <= H_DISP_7084; h_total <= H_TOTAL_7084;v_sync  <= V_SYNC_7084; v_back  <= V_BACK_7084; v_disp  <= V_DISP_7084; v_total <= V_TOTAL_7084;        end16'h7016 : beginh_sync  <= H_SYNC_7016; h_back  <= H_BACK_7016; h_disp  <= H_DISP_7016; h_total <= H_TOTAL_7016;v_sync  <= V_SYNC_7016; v_back  <= V_BACK_7016; v_disp  <= V_DISP_7016; v_total <= V_TOTAL_7016;            end16'h4384 : beginh_sync  <= H_SYNC_4384; h_back  <= H_BACK_4384; h_disp  <= H_DISP_4384; h_total <= H_TOTAL_4384;v_sync  <= V_SYNC_4384; v_back  <= V_BACK_4384; v_disp  <= V_DISP_4384; v_total <= V_TOTAL_4384;             end        16'h1018 : beginh_sync  <= H_SYNC_1018; h_back  <= H_BACK_1018; h_disp  <= H_DISP_1018; h_total <= H_TOTAL_1018;v_sync  <= V_SYNC_1018; v_back  <= V_BACK_1018; v_disp  <= V_DISP_1018; v_total <= V_TOTAL_1018;        enddefault : beginh_sync  <= H_SYNC_4342; h_back  <= H_BACK_4342; h_disp  <= H_DISP_4342; h_total <= H_TOTAL_4342;v_sync  <= V_SYNC_4342; v_back  <= V_BACK_4342; v_disp  <= V_DISP_4342; v_total <= V_TOTAL_4342;          endendcase
end//行计数
always @(posedge lcd_pclk or negedge sys_rst_n ) beginif (!sys_rst_n) beginh_cnt <= 11'd0;end else beginif (h_cnt == h_total - 1'd1) beginh_cnt <= 11'd0;endelse beginh_cnt <= h_cnt + 1'b1;endend
end//场计数
always @(posedge lcd_pclk or negedge sys_rst_n ) beginif (!sys_rst_n) beginv_cnt <= 11'b0;end else beginif (h_cnt == h_total - 1'd1) beginif (v_cnt == v_total - 1'b1) beginv_cnt <= 11'd0;end else beginv_cnt <= v_cnt +1'b1;endendend
end//数据请求信号,data_req
always @(posedge lcd_pclk or negedge sys_rst_n) beginif (!sys_rst_n) begindata_req <= 1'b0;end else if((h_cnt >= h_sync + h_back - 2'd2) && (h_cnt < h_sync + h_back + h_disp - 2'd2) && (v_cnt >= v_sync + v_back) && (v_cnt < v_sync + v_back + v_disp))begindata_req <= 1'b1;endelse begindata_req <= 1'b0;end
end//阻塞赋值,会延迟一拍,因此lcd_de 比 data_req晚一拍
always @(posedge lcd_pclk or negedge sys_rst_n ) beginif (!sys_rst_n) beginlcd_de <= 1'b0;endelse beginlcd_de <= data_req;end
end//像素点坐标  
assign pixel_xpos = data_req ? (h_cnt - (h_sync + h_back - 1'b1)) : 11'd0;
assign pixel_ypos = data_req ? (v_cnt - (v_sync + v_back - 1'b1)) : 11'd0;endmodule

(4)lcd_display:

`timescale 1ns / 1psmodule lcd_display(
input               sys_clk     ,
input               sys_rst_n   ,
input   [10:0]      pixel_xpos  ,
input   [10:0]      pixel_ypos  ,
input   [10:0]      h_disp      ,
input   [10:0]      v_disp      ,
output  reg[23:0]   pixel_data                
);parameter WHITE = 24'hFFFFFF;  //白色
parameter BLACK = 24'h000000;  //黑色
parameter RED   = 24'hFF0000;  //红色
parameter GREEN = 24'h00FF00;  //绿色
parameter BLUE  = 24'h0000FF;  //蓝色//根据当前像素点坐标指定当前像素点颜色数据,在屏幕上显示彩条
always @(posedge sys_clk or negedge sys_rst_n) beginif(!sys_rst_n)pixel_data <= BLACK;else beginif((pixel_xpos >= 11'd0) && (pixel_xpos < h_disp/5*1))pixel_data <= WHITE;else if((pixel_xpos >= h_disp/5*1) && (pixel_xpos < h_disp/5*2))    pixel_data <= BLACK;else if((pixel_xpos >= h_disp/5*2) && (pixel_xpos < h_disp/5*3))    pixel_data <= RED;   else if((pixel_xpos >= h_disp/5*3) && (pixel_xpos < h_disp/5*4))    pixel_data <= GREEN;                else pixel_data <= BLUE;      end    
endendmodule

(5)lcd_top:

三态门:

`timescale 1ns / 1psmodule LCD_RGB_colorbar(
input               sys_clk     ,
input               sys_rst_n   ,output              lcd_clk         ,           //LCD 像素时钟       
output              lcd_hs          ,           //LCD 行同步信号   
output              lcd_vs          ,           //LCD 场同步信号   
output              lcd_bl          ,           //LCD 背光控制信号  
output  reg         lcd_de          ,           //LCD 数据使能信号   
output              lcd_rst         ,           //LCD 屏幕复位信号      
inout      [23:0]  lcd_rgb                     //LCD RGB888颜色数据 
);wire    [23:0]  lcd_rgb_o   ;
wire    [23:0]  lcd_rgb_i   ;
wire    [15:0]  lcd_id      ;wire    [10:0]  pixel_xpos  ;
wire    [10:0]  pixel_ypos  ;
wire    [10:0]  h_disp      ;
wire    [10:0]  v_disp      ;assign  lcd_rgb   = lcd_de ? lcd_rgb_o :{24{1'bz}} ;
assign  lcd_rgb_i = lcd_rgb ;//识别屏幕ID
rd_id u_rd_id(
.sys_clk            (sys_clk  ),
.sys_rst_n          (sys_rst_n),
.lcd_rgb            (lcd_rgb_i),
.lcd_id             (lcd_id   )
);//产生驱动屏幕时钟
clk_div u_clk_div(
.sys_clk            (sys_clk  ),
.sys_rst_n          (sys_rst_n),
.lcd_id             (lcd_id   ),
.lcd_pclk           (lcd_pclk )   
);//LCD屏幕驱动
lcd_driver u_lcd_driver(
.lcd_pclk           (lcd_pclk  ),           //时钟
.sys_rst_n          (sys_rst_n ),           //复位,低电平有效
.lcd_id             (lcd_id    ),           //LCD屏ID
.pixel_data         (pixel_data),           //像素数据.lcd_clk            (lcd_clk   ),           //LCD 像素时钟       
.lcd_hs             (lcd_hs    ),           //LCD 行同步信号   
.lcd_vs             (lcd_vs    ),           //LCD 场同步信号   
.lcd_bl             (lcd_bl    ),           //LCD 背光控制信号  
.lcd_de             (lcd_de    ),           //LCD 数据使能信号   
.lcd_rst            (lcd_rst   ),           //LCD 屏幕复位信号      
.lcd_rgb            (lcd_rgb_o ),           //LCD RGB888颜色数据       
.pixel_xpos         (pixel_xpos),           //当前像素点横坐标       
.pixel_ypos         (pixel_ypos),           //当前像素点纵坐标        
.h_disp             (h_disp    ),           //LCD屏水平分辨率 有效显示区域  
.v_disp             (v_disp    ),           //LCD屏垂直分辨率 有效显示区域  
.data_req           (data_req  )            //LCD屏幕 数据请求信号    
);lcd_display u_lcd_display(
.sys_clk            (lcd_pclk   ),
.sys_rst_n          (sys_rst_n ),
.pixel_xpos         (pixel_xpos),
.pixel_ypos         (pixel_ypos),
.h_disp             (h_disp    ),
.v_disp             (v_disp    ),
.pixel_data         (pixel_data)              
);endmodule

4、仿真文件

`timescale 1ns / 1psmodule lcd_rgb_tb();reg     sys_clk         ;
reg     sys_rst_n       ;
wire    lcd_clk         ;
wire    lcd_hs          ;
wire    lcd_vs          ;
wire    lcd_bl          ;
wire    lcd_de          ;
wire    lcd_rst         ;
wire   [23:0]  lcd_rgb  ;         always #10 sys_clk = !sys_clk;
assign lcd_rgb = lcd_de ? {24{1'bz}} : 24'h80;initial beginsys_clk = 1'b0;sys_rst_n = 1'b0;#200sys_rst_n = 1'b1;
endLCD_RGB_colorbar LCD_RGB_colorbar(
.sys_clk         (sys_clk  ),
.sys_rst_n       (sys_rst_n),
.lcd_clk         (lcd_clk  ),           //LCD 像素时钟       
.lcd_hs          (lcd_hs   ),           //LCD 行同步信号   
.lcd_vs          (lcd_vs   ),           //LCD 场同步信号   
.lcd_bl          (lcd_bl   ),           //LCD 背光控制信号  
.lcd_de          (lcd_de   ),           //LCD 数据使能信号   
.lcd_rst         (lcd_rst  ),           //LCD 屏幕复位信号      
.lcd_rgb         (lcd_rgb  )           //LCD RGB888颜色数据 );endmodule

五、下载验证

4.3寸
7寸

总结:

这篇关于LCD彩条显示——FPGA学习笔记10的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1145346

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

Ilya-AI分享的他在OpenAI学习到的15个提示工程技巧

Ilya(不是本人,claude AI)在社交媒体上分享了他在OpenAI学习到的15个Prompt撰写技巧。 以下是详细的内容: 提示精确化:在编写提示时,力求表达清晰准确。清楚地阐述任务需求和概念定义至关重要。例:不用"分析文本",而用"判断这段话的情感倾向:积极、消极还是中性"。 快速迭代:善于快速连续调整提示。熟练的提示工程师能够灵活地进行多轮优化。例:从"总结文章"到"用

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

安卓链接正常显示,ios#符被转义%23导致链接访问404

原因分析: url中含有特殊字符 中文未编码 都有可能导致URL转换失败,所以需要对url编码处理  如下: guard let allowUrl = webUrl.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {return} 后面发现当url中有#号时,会被误伤转义为%23,导致链接无法访问

C#实战|大乐透选号器[6]:实现实时显示已选择的红蓝球数量

哈喽,你好啊,我是雷工。 关于大乐透选号器在前面已经记录了5篇笔记,这是第6篇; 接下来实现实时显示当前选中红球数量,蓝球数量; 以下为练习笔记。 01 效果演示 当选择和取消选择红球或蓝球时,在对应的位置显示实时已选择的红球、蓝球的数量; 02 标签名称 分别设置Label标签名称为:lblRedCount、lblBlueCount

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

【机器学习】高斯过程的基本概念和应用领域以及在python中的实例

引言 高斯过程(Gaussian Process,简称GP)是一种概率模型,用于描述一组随机变量的联合概率分布,其中任何一个有限维度的子集都具有高斯分布 文章目录 引言一、高斯过程1.1 基本定义1.1.1 随机过程1.1.2 高斯分布 1.2 高斯过程的特性1.2.1 联合高斯性1.2.2 均值函数1.2.3 协方差函数(或核函数) 1.3 核函数1.4 高斯过程回归(Gauss

【学习笔记】 陈强-机器学习-Python-Ch15 人工神经网络(1)sklearn

系列文章目录 监督学习:参数方法 【学习笔记】 陈强-机器学习-Python-Ch4 线性回归 【学习笔记】 陈强-机器学习-Python-Ch5 逻辑回归 【课后题练习】 陈强-机器学习-Python-Ch5 逻辑回归(SAheart.csv) 【学习笔记】 陈强-机器学习-Python-Ch6 多项逻辑回归 【学习笔记 及 课后题练习】 陈强-机器学习-Python-Ch7 判别分析 【学