明德扬论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

微信扫一扫,快捷登录!

查看: 177|回复: 0

【每周FPGA案例】至简设计系列_LCD入门案例_显示图片

[复制链接]
发表于 2020-10-8 14:00:13 | 显示全部楼层 |阅读模式

马上注册,看完整文章,学更多FPGA知识。

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
至简设计系列_LCD显示图片


--作者:肖肖肖

本文为明德扬原创及录用文章,转载请注明出处

1.1 总体设计1.1.1 概述
液晶显示器是一-种通过液晶和色彩过滤器过滤光源,在平面面板上产生图像的数字显示器。LCD 的构造是在两片平行的玻璃基板当中放置液晶盒,下基板玻璃上设置薄膜晶体管,.上基板玻璃上设置彩色滤光片,通过薄膜晶体管上的信号与电压改变来控制液晶分子的转动方向,从而达到控制每个像素点偏振光出射与否而达到显示目的。与传统的阴极射线管相比,LCD具有占用空间小,低功耗,低辐射,无闪烁,降低视觉疲劳等优点。现在LCD已渐替代CRT成为主流,价格也已经下降了很多,并已充分的普及。

1.1.2 设计目标
7LCD显示屏上实现图片的居中显示。

1.1.3 系统结构框图
系统结构框图如下所示:
31.JPG

图一
1.1.4模块功能PLL模块实现功能
1.       将输入的50MHz时钟分频输出40MHz时钟。

ROM模块实现功能
2.       存储图像数据。

LCD驱动模块实现功能
1、  产生驱动LCD屏显示的时序
2、  读取ROM里存储的数据并输出显示

1.1.5顶层信号
  
信号名
  
I/O
位宽
定义
clk
I
1
系统工作时钟 50M
rst_n
I
1
系统复位信号,低电平有效
hys
O
1
LCD 行时序信号
vys
O
1
LCD 场时序信号
lcd_de
O
1
LCD 数据输入使能信号
lcd_rgb
O
24
LCD RGB信号,RGB格式为使用24位来表示一个像素,RGB分量都用8位表示,取值范围为0-255。
lcd_dclk
O
1
LCD 数据采样时钟



1.1.6参考代码

  1. module top_mdyLcdPic(
  2.     clk       ,
  3.     rst_n     ,
  4.     hys       ,
  5.     vys       ,
  6.     lcd_de    ,
  7.     lcd_rgb   ,
  8.     lcd_dclk
  9.     );

  10.     parameter   PICTURE_W = 24  ;

  11.     input                   clk         ;
  12.     input                   rst_n       ;
  13.     output                  hys         ;
  14.     output                  vys         ;
  15.     output                  lcd_de      ;
  16.     output  [PICTURE_W-1:0] lcd_rgb     ;
  17.     output                  lcd_dclk    ;
  18.    

  19.     wire                     clk_0      ;
  20.    
  21.     wire                     hys        ;
  22.     wire                     vys        ;
  23.     wire                     lcd_de     ;
  24.     wire   [PICTURE_W-1:0]   lcd_rgb    ;
  25.     wire                     lcd_dclk   ;


  26. //40MHz
  27. pll_40m u_pll_40m(
  28.             .areset     (~rst_n ),
  29.         .inclk0     (clk    ),
  30.             .c0         (clk_0  )
  31.     );


  32. lcd_driver  u2(
  33.    .clk          (clk_0       ),//40MHz
  34.    .rst_n        (rst_n       ),
  35.                           
  36.    .hys          (hys         ),  
  37.    .vys          (vys         ),  
  38.    .lcd_de       (lcd_de      ),                  
  39.    .lcd_rgb      (lcd_rgb     ),
  40.    .lcd_dclk     (lcd_dclk    )
  41.     );

  42. endmodule
复制代码


1.2 PLL模块设计1.2.1接口信号
下面为使用矩阵键盘时的接口信号:

  
信号名
  
I/O
位宽
定义
areset
I
1
PLL复位信号,高电平有效
inclk0
I
1
PLL输入时钟 50MHz
c0
O
1
PLL输出时钟 40MHz

1.2.2 设计思路
本模块主要用于产生LCD驱动时序所需要的时钟,关于PLL的使用详细介绍请看下方链接:

1.3 ROM模块设计1.3.1接口信号
  
信号名
  
I/O
位宽
定义
address
I
16
ROM数据存放地址
clock
I
1
ROM工作时钟40MHz
q
O
8
ROM输出数据

1.3.2设计思路
本模块主要用于存储需要显示的图像数据,关于ROM的使用详细介绍请看下方数据手册:


1.4 LCD驱动模块设计
1.4.1接口信号
  
信号名
  
I/O
位宽
定义
clk
I
1
模块工作时钟 40MHz
rst_n
I
1
系统复位信号,低电平有效
hys
O
1
LCD 行时序信号
vys
O
1
LCD 场时序信号
lcd_de
O
1
LCD 数据输入使能信号
lcd_rgb
O
24
LCD RGB信号,RGB格式为使用24位来表示一个像素,RGB分量都用8位表示,取值范围为0-255。
lcd_dclk
O
1
LCD 数据采样时钟

1.4.2设计思路

产生驱动LCD显示的行场时序信号,其计数器架构如下图所示:

行计数器h_cnt:该计数器用来计算行同步信号的帧长。加一条件为1,表示一直在计数。结束条件为数1056个,也就是一行有1056个像素。
场计数器v_cnt:该计数器用来计算场同步信号的帧长。加一条件为end_h_cnt,即行计数器的计数器的结束条件,表示每计数完一行像素就加一。结束条件为数525个,也就是一共有525行像素。


1.4.3参考代码

  1. module lcd_driver(
  2.     clk          ,//40MHz
  3.     rst_n        ,

  4.     hys          ,
  5.     vys          ,
  6.     lcd_de       ,  
  7.     lcd_rgb      ,
  8.     lcd_dclk   
  9. );

  10.    input                    clk             ;
  11.    input                    rst_n           ;

  12.    output                   hys             ;
  13.    output                   vys             ;
  14.    output                   lcd_de          ;
  15.    output [23:0]            lcd_rgb         ;
  16.    output                   lcd_dclk        ;

  17.    reg                      hys             ;
  18.    reg                      vys             ;
  19.    reg                      lcd_de          ;
  20.    reg    [23:0]            lcd_rgb         ;
  21.    wire                     lcd_dclk        ;

  22.    //1056
  23.    parameter         THPW      = 20         ;   
  24.    parameter         THB       = 46         ;   
  25.    parameter         THD       = 800        ;   
  26.    parameter         THFP      = 210        ;   
  27.    
  28.    //525
  29.    parameter         TVPW      = 10         ;   
  30.    parameter         TVB       = 23         ;   
  31.    parameter         TVD       = 480        ;   
  32.    parameter         TVFP      = 22         ;   

  33.    parameter       HDE_CENTRE  = THD/2      ;//400
  34.    parameter       VDE_CENTRE  = TVD/2      ;//240

  35.    reg   [ 10:0]            h_cnt           ;
  36.    wire                     add_h_cnt       ;
  37.    wire                     end_h_cnt       ;
  38.    reg   [ 9:0]             v_cnt           ;
  39.    wire                     add_v_cnt       ;
  40.    wire                     end_v_cnt       ;


  41.    wire                     active_area     ;
  42.    reg                      rom_area        ;
  43.    reg      [15:0]          rom_addr        ;
  44.    wire     [7:0]           rom_data        ;


  45. always @(posedge clk or negedge rst_n) begin
  46.     if (rst_n==0) begin
  47.         h_cnt <= 0;
  48.     end
  49.     else if(add_h_cnt) begin
  50.         if(end_h_cnt)
  51.             h_cnt <= 0;
  52.         else
  53.             h_cnt <= h_cnt+1 ;
  54.    end
  55. end
  56. assign add_h_cnt = 1;
  57. assign end_h_cnt = add_h_cnt  && h_cnt == (THB + THD + THFP)-1 ;



  58. always @(posedge clk or negedge rst_n) begin
  59.     if (rst_n==0) begin
  60.         v_cnt <= 0;
  61.     end
  62.     else if(add_v_cnt) begin
  63.         if(end_v_cnt)
  64.             v_cnt <= 0;
  65.         else
  66.             v_cnt <= v_cnt+1 ;
  67.    end
  68. end
  69. assign add_v_cnt = end_h_cnt;
  70. assign end_v_cnt = add_v_cnt  && v_cnt == (TVB + TVD + TVFP)-1 ;

  71. /*******************************************************/
  72.     //dclk
  73.     assign lcd_dclk = clk;

  74.     //hsync
  75.     always  @(posedge clk or negedge rst_n)begin
  76.         if(rst_n==1'b0)begin
  77.             hys <= 0;
  78.         end
  79.         else if(add_h_cnt && h_cnt==THPW-1)begin
  80.             hys <= 1;
  81.         end
  82.         else if(end_h_cnt)begin
  83.             hys <= 0;
  84.         end
  85.     end


  86.     //vsync
  87.     always  @(posedge clk or negedge rst_n)begin
  88.         if(rst_n==1'b0)begin
  89.             vys <= 0;
  90.         end
  91.         else if(add_v_cnt && v_cnt==TVPW-1)begin
  92.             vys <= 1;
  93.         end
  94.         else if(end_v_cnt)begin
  95.             vys <= 0;
  96.         end
  97.     end
  98.    

  99.     //lcd_de
  100.     always  @(posedge clk or negedge rst_n)begin
  101.         if(rst_n==1'b0)begin
  102.             lcd_de <= 0;
  103.         end
  104.         else if(active_area)begin
  105.             lcd_de <= 1;
  106.         end
  107.         else begin
  108.             lcd_de <= 0;
  109.         end
  110.     end
  111.    

  112. /********************************************************************/   



  113. assign active_area = h_cnt>=(THB-1) && h_cnt<(THB+THD-1) && v_cnt>=(TVB-1) && v_cnt<(TVB+TVD-1);


  114. always  @(*)begin
  115.     rom_area = h_cnt >=((HDE_CENTRE-60) + (THB-1)) && h_cnt < ((HDE_CENTRE+60) + (THB-1)) && v_cnt >= ((VDE_CENTRE-27)+(TVB-1)) && v_cnt < ((VDE_CENTRE+28) +(TVB-1));
  116. end


  117. always  @(posedge clk or negedge rst_n)begin
  118.     if(rst_n==1'b0)begin
  119.         lcd_rgb <= 0;
  120.     end
  121.     else if(active_area)begin
  122.         if(rom_area)
  123.             lcd_rgb <= {rom_data[7:5],5'b11111,rom_data[4:2],5'b11111,rom_data[1:0],6'b111111};
  124.         else
  125.             lcd_rgb <= {24{1'b1}};
  126.     end
  127.     else begin
  128.         lcd_rgb <=0;
  129.     end
  130. end


  131. always  @(*)begin
  132.     if(active_area && rom_area)begin
  133.             rom_addr = (h_cnt-((HDE_CENTRE-60)+(THB-1))) + 120*(v_cnt-((VDE_CENTRE-27)+(TVB-1)));
  134.     end
  135. end




  136. FPGA_rom u_fpga_rom(
  137.                    .address (rom_addr),
  138.                    .clock   (clk     ),
  139.                    .q       (rom_data));


  140.     endmodule
复制代码


1.5 效果和总结
以下为工程上板后的现象效果图:

mp801开发板
LCD显示图片_mp801.jpg


ms980试验箱


LCD显示图片_实验箱.jpg


感兴趣的朋友也可以访问明德扬论坛(http://www.fpgabbs.cn/)进行FPGA相关工程设计学习,也可以看一下我们往期的文章:

1.6 公司简介

明德扬是一家专注于FPGA领域的专业性公司,公司主要业务包括开发板、教育培训、项目承接、人才服务等多个方向。点拨开发板——学习FPGA的入门之选。
MP801
开发板——千兆网、ADDA、大容量SDRAM等,学习和项目需求一步到位。网络培训班——不管时间和空间,明德扬随时在你身边,助你快速学习FPGA周末培训班——明天的你会感激现在的努力进取,升职加薪明德扬来助你。就业培训班——七大企业级项目实训,获得丰富的项目经验,高薪就业。专题课程——高手修炼课:提升设计能力;实用调试技巧课:提升定位和解决问题能力;FIFO架构设计课:助你快速成为架构设计师;时序约束、数字信号处理、PCIE、综合项目实践课等你来选。项目承接——承接企业FPGA研发项目。人才服务——提供人才推荐、人才代培、人才派遣等服务。


【设计教程下载】
至简设计系列_LCD显示图片.pdf (1.12 MB, 下载次数: 10)
FPGA视频课程  培训班 FPGA学习资料
吴老师 18022857217(微信同号) Q1241003385
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


QQ|手机版|小黑屋|MDYBBS ( 粤ICP备16061416号-1

GMT+8, 2020-10-23 02:23 , Processed in 0.594028 second(s), 13 queries , File On.

Powered by Discuz! X3.4

本论坛由广州健飞通信有限公司所有

© 2001-2019 Comsenz Inc.

快速回复 返回顶部 返回列表