发 帖  
原厂入驻New
[经验]

【每周FPGA案例】LCD入门案例-动态矩形

2020-10-23 00:25:27  732 FPGA LCD
分享
3
【设计教程】

第1节 LCD入门案例_边框显示
--作者:喝喝

本文为明德扬原创及录用文章,转载请注明出处
1.1 总体设计1.1.1 概述
液晶显示器是一-种通过液晶和色彩过滤器过滤光源,在平面面板上产生图像的数字显示器。LCD 的构造是在两片平行的玻璃基板当中放置液晶盒,下基板玻璃上设置薄膜晶体管,.上基板玻璃上设置彩色滤光片,通过薄膜晶体管上的信号与电压改变来控制液晶分子的转动方向,从而达到控制每个像素点偏振光出射与否而达到显示目的。与传统的阴极射线管相比,LCD具有占用空间小,低功耗,低辐射,无闪烁,降低视觉疲劳等优点。现在LCD已渐替代CRT成为主流,价格也已经下降了很多,并已充分的普及。
本设计的主要任务是基于FPGALCD显示控制器设计,兼顾程序的易用性,方便此后模块的移植和应用。采用VHDL硬件描述语言在QUARTUS II软件平台上实现FPGALCD的控制,在LCD模块上实现任意彩色图片的显示,与此同时还须实现实时刷新数据的功能。这将有助于采用FPGA的系列产品的开发,特别是需要用到LCD而采用FPGA的产品的开发。不但缩短了FPGA的开发周期,也使更多采用FPGA设计的产品上出现LCD,增加了人机之间的交互性。
1.1.2 设计目标
此设计通过fpgalcd发送图片信息,然后直接在LCD显示矩形动画,矩形的宽从2变化到600,矩形的高从2变化到400
1.1.3信号列表
  
信号名
  
接口方向
定义
clk_50m
输入
rst_n
输入
低电平复位信号
lcd_hsync
输出
行同步信号
lcd_vsync
输出
场同步信号
lcd_de
输出
行和场同时显示时序段
  
有效显示数据段信号
lcd_rgb
输出
显示颜色RGB
  
[23:16]:表示的是R[7:0]
  
[15:8]:表示的是G[7:0]
  
[7:0]:表示的是B[7:0]
lcd_dclk
输出
像素时钟信号


1.1.4 设计思路
设计行显示时序段和场显示时序段,来确定矩形边框的宽度,根据各种颜色的数值来确定lcd显示屏显示出的边框颜色
行时钟计数器cnt_hys:用来计算行同步信号的帧长,加一条件是1,结束条件为数到1056个像素就结束
场时钟计数cnt_vys:用来计算场同步信号的帧长,加一条件是场信号每数到1056个像素(即为一行结束的时刻),结束条件为数到525行就结束
1.1.5参考代码
  1. module mdyLcdDispDynaRect(
  2.     clk_50m     ,  
  3.     rst_n       ,

  4.     lcd_hsync   ,
  5.     lcd_vsync   ,
  6.     lcd_de      ,


  7.     lcd_rgb     ,
  8.     lcd_dclk   
  9.       
  10. );

  11.     input               clk_50m     ;  
  12.     input               rst_n       ;
  13.     output              lcd_hsync   ;
  14.     output              lcd_vsync   ;
  15.     output              lcd_de      ;

  16.     output  [23:0]      lcd_rgb     ;
  17.     output              lcd_dclk    ;
  18.       

  19.     reg      [30:0]        h        ;
  20.         reg      [30:0]        v        ;
  21.          
  22.     reg                 lcd_hsync   ;
  23.     reg                 lcd_vsync   ;

  24.     reg     [23:0]      lcd_rgb     ;


  25.     parameter     LINE_PR   =  1056 ;      
  26.     parameter     FRAME_PER =   525 ;           


  27.     parameter     H_SYNC    =    20 ;      
  28.     parameter     V_SYNC    =    10 ;              

  29.     parameter     HDE_START =    46 ;
  30.     parameter     HDE_END   =   846 ;
  31.     parameter     VDE_START =    23 ;
  32.     parameter     VDE_END   =   503 ;

  33.    

  34.     reg    [12:0]     cnt_hsy       ;
  35.     reg    [12:0]     cnt_vsy       ;
  36.     reg               hsync_de      ;
  37.     reg               vsync_de      ;

  38.     wire              display_area  ;
  39.     wire              e_area        ;
  40.     wire              add_cnt_hsy   ;
  41.     wire              end_cnt_hsy   ;
  42.     wire              add_cnt_vsy   ;
  43.     wire              end_cnt_vsy   ;
  44.     reg [ 7:0]        cnt0          ;
  45.     wire              add_cnt0      ;
  46.     wire              end_cnt0      ;
  47.     reg  [15:0]       cnt1          ;
  48.     wire              add_cnt1      ;
  49.     wire              end_cnt1      ;


  50.     assign clk       = clk_50m              ;
  51.     assign lcd_dclk  = ~ clk_50m            ;
  52.     assign lcd_de    = hsync_de & vsync_de  ;
  53.    
  54.    


  55.     always @ (posedge clk or negedge rst_n)begin
  56.             if(!rst_n)begin
  57.                 cnt_hsy <= 0;
  58.             end
  59.             else if(add_cnt_hsy)begin
  60.                 if(end_cnt_hsy)
  61.                     cnt_hsy <= 0;
  62.                 else
  63.                     cnt_hsy <= cnt_hsy + 1;
  64.             end
  65.     end
  66.    
  67.     assign add_cnt_hsy = 1;
  68.     assign end_cnt_hsy = add_cnt_hsy && cnt_hsy == LINE_PR -1;
  69.    

  70.     always @ (posedge clk or negedge rst_n)begin
  71.         if(!rst_n)begin
  72.             cnt_vsy <= 0;
  73.         end
  74.         else if(add_cnt_vsy)begin
  75.             if(end_cnt_vsy)
  76.                 cnt_vsy <= 0;
  77.             else
  78.                 cnt_vsy <= cnt_vsy + 1;
  79.         end
  80.     end
  81.    
  82.     assign add_cnt_vsy = end_cnt_hsy;
  83.     assign end_cnt_vsy = add_cnt_vsy && cnt_vsy == FRAME_PER - 1;
  84.          

  85.     always @ (posedge clk or negedge rst_n)begin
  86.         if(!rst_n)begin
  87.             lcd_hsync <= 1'b0 ;
  88.         end
  89.         else if(end_cnt_hsy)begin
  90.             lcd_hsync <= 1'b0;
  91.         end
  92.         else if(add_cnt_hsy && cnt_hsy == H_SYNC-1 )begin
  93.             lcd_hsync <= 1'b1;
  94.         end
  95.     end

  96.     always @ (posedge clk or negedge rst_n)begin
  97.         if(!rst_n)begin
  98.             hsync_de <= 1'b0;
  99.         end
  100.         else if(add_cnt_hsy && cnt_hsy == HDE_START-1)begin
  101.             hsync_de <= 1'b1;
  102.         end
  103.         else if(add_cnt_hsy && cnt_hsy == HDE_END-1)begin
  104.             hsync_de <= 1'b0;
  105.         end
  106.     end

  107.          
  108.     always @ (posedge clk or negedge rst_n)begin
  109.         if(!rst_n)begin
  110.             lcd_vsync <= 1'b0 ;
  111.         end
  112.                   else if(add_cnt_vsy && cnt_vsy == V_SYNC-1 )begin
  113.             lcd_vsync <= 1'b1;
  114.         end
  115.         else if(end_cnt_vsy)begin
  116.             lcd_vsync <= 1'b0;
  117.         end

  118.     end

  119.          
  120.     always @ (posedge clk or negedge rst_n)begin
  121.         if(!rst_n)begin
  122.             vsync_de <= 1'b0;
  123.         end
  124.         else if(add_cnt_vsy && cnt_vsy == VDE_START-1)begin
  125.             vsync_de <= 1'b1;
  126.         end
  127.         else if(add_cnt_vsy && cnt_vsy ==VDE_END-1)begin
  128.             vsync_de <= 1'b0;
  129.         end
  130.     end


  131.     assign   display_area = hsync_de && vsync_de;


  132.     assign   blue_area = (cnt_hsy >= HDE_START + 400-h) && (cnt_hsy<HDE_START+400+h) &&
  133.                          (cnt_vsy >= VDE_START + 240-v) && (cnt_vsy<VDE_START+240+v) ;

  134.                      

  135.         always  @(posedge clk or negedge rst_n)begin
  136.         if(rst_n==1'b0)begin
  137.             h<=1;
  138.         end
  139.         else if(end_cnt_vsy && h<300)begin
  140.             h<=h+2;
  141.         end
  142.     end

  143.     always  @(posedge clk or negedge rst_n)begin
  144.         if(rst_n==1'b0)begin
  145.             v<=1;
  146.         end
  147.         else if(end_cnt_vsy && v<200)begin
  148.             v<=v+1;
  149.         end
  150.     end


  151.     always @ (posedge clk or negedge rst_n)begin
  152.         if(!rst_n)begin
  153.                                 lcd_rgb <= 0;
  154.         end
  155.         else if(display_area)begin
  156.             if(blue_area)begin
  157.                 lcd_rgb <= 24'h00_00_ff ;
  158.             end
  159.             else begin
  160.                 lcd_rgb <= 24'hff_ff_ff ;
  161.             end
  162.         end
  163.         else begin
  164.             lcd_rgb <= 0;
  165.         end
  166.     end



  167. endmodule
复制代码


1.2 效果和总结

本案例我们设计了蓝色的矩形,蓝色矩形的场信号是从2行变到400行、行信号是从2个像素变到600个像素;
在这个设计案例中,至简设计法和明德扬计数器模板发挥了至关重要的作用,使我能够快速准确完成设计。希望有兴趣的同学可以运用至简设计法和明德扬模板尝试一下拓展设计哦。

【设计教程下载

mdyLcdDispDynaRect_project.zip (19.92 KB, 下载次数: 0)

相关经验

评论

高级模式
您需要登录后才可以回帖 登录 | 注册

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容图片侵权或者其他问题,请联系本站作侵删。 侵权投诉
发经验
关闭

站长推荐 上一条 /9 下一条

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