正点原子 发表于 2019-5-29 21:24:45

【正点原子FPGA连载】第十八章 VGA彩条显示实验--摘自【正点原子】开拓者 FPGA 开发指南

本帖最后由 正点原子 于 2020-10-23 11:17 编辑

1)实验平台:正点原子开拓者FPGA开发板
2)平台购买地址:https://item.taobao.com/item.htm?id=579749209820
2)全套实验源码+手册+视频下载地址:http://www.openedv.com/thread-281143-1-1.html
3)本实例源码下载:
4)对正点原子FPGA感兴趣的同学可以加群讨论:712557122点击加入:
5)关注正点原子公众号,获取最新资料更新:

第十八章 VGA彩条显示实验

VGA是IBM公司在1987年推出的一种视频传输标准,它具有分辨率高、显示速率快、颜色丰富等优点,因而在彩色显示器领域得到了广泛的应用。虽然由于体积较大等原因,VGA接口已经逐渐被笔记本电脑淘汰,但是对于台式机而言,VGA仍是制造商所支持的最低显示标准。本章包括以下几个部分:1         1.1         VGA简介1.2         实验任务1.3         硬件设计1.4         程序设计1.5         下载验证
1.1      VGA简介VGA的全称是Video GraphicsArray,即视频图形阵列,是一个使用模拟信号进行视频传输的标准。早期的CRT显示器由于设计制造上的原因,只能接收模拟信号输入,因此计算机内部的显卡负责进行数模转换,而VGA接口就是显卡上输出模拟信号的接口。如今液晶显示器虽然可以直接接收数字信号,但是为了兼容显卡上的VGA接口,也大都支持VGA标准。VGA接口样式如图 18.1.1所示:


图 18.1.1 VGA接口VGA接口定义及各引脚功能说明如图 18.1.2所示,我们一般只用到其中的1(RED)、2(GREEN)、3(BLUE)、13(HSYNC)、14(VSYNC)信号。引脚1、2、3分别输出红、绿、蓝三原色模拟信号,电压变化范围为 0~0.714V,0V代表无色,0.714V代表满色;引脚13、14输出TTL电平标准的行/场同步信号。


图 18.1.2 VGA接口引脚定义在VGA视频传输标准中,视频图像被分解为红、绿、蓝三原色信号,经过数模转换之后,在行同步(HSYNC)和场同步(VSYNC)信号的同步下分别在三个独立通道传输。VGA在传输过程中的同步时序分为行时序和场时序,如图 18.1.3、图 18.1.4所示。


图 18.1.3 行同步时序
图 18.1.4 场同步时序从上面两幅图中我们可以看到VGA传输过程中的行同步时序和场同步时序非常类似,一行或一场(又称一帧)数据都分为四个部分:低电平同步脉冲、显示后沿、有效数据段以及显示前沿。行同步信号HSYNC在一个行扫描周期中完成一行图像的显示,其中在a段维持一段时间的低电平用于数据同步,其余时间拉高;在有效数据期间(c段),红绿蓝三原色数据通道上输出一行图像信号,其余时间数据无效。与之类似,场同步信号在在一个场扫描周期中完成一帧图像的显示,不同的是行扫描周期的基本单位是像素点时钟,即完成一个像素点显示所需要的时间;而场扫描周期的基本单位是完成一行图像显示所需要的时间。早期的VGA特指分辨率为640X480的显示模式,后来根据分辨率的不同,VGA又分为VGA(640x480)、SVGA(800x600)、XGA(1024x768)、SXGA(1280x1024)等。不同分辨率的VGA显示时序是类似的,仅存在参数上的差异,如图 18.1.5所示。需要注意的是,即便分辨率相同,刷新速率(每秒钟图像更新次数)不一样时,对应的VGA像素时钟及时序参数也存在差异。例如,显示模式“640*480@75”刷新速率为75hz,与相同分辨率下刷新速率为60hz的“640*480@60”模式相比,像素时钟更快,其他时序参数也不尽相同。
图 18.1.5 不同分辨率的VGA时序参数1.2      实验任务本节实验任务是使用开拓者开发板上的VGA接口在显示器上显示彩条,要求分辨率为640*480,刷新速率为60hz。1.3      硬件设计开拓者开发板上VGA接口部分的原理图如图 18.3.1所示。
图 18.3.1 VGA接口原理图从上图中可以看到,FPGA管脚输出的颜色数据位宽为16bit,数据格式为RGB565,即数据高5位表示红色,中间6位表示绿色,低5位表示蓝色。RGB565格式的数据一共可表示65536种颜色,此外常用的颜色数据格式还有RGB888,数据位宽越大,可以表示的颜色种类就越丰富。由前面的简介我们知道,VGA传输的是模拟信号,因此需要对FPGA输出的RGB565颜色数据进行数模转换。此过程可以通过专用的视频转换芯片(如ADV7123)来实现,在这里我们采用另外一种更简单的方案——利用电阻匹配网络来实现数字信号到模拟信号的转换,如图 18.3.1所示。本实验中,各端口信号的管脚分配如下表所示:
表 18.3.1 VGA彩条实验管脚分配
1.4      程序设计VGA时序包含三个要素:像素时钟、行场同步信号、以及图像数据,由此我们可以大致规划出系统结构如图 18.4.1所示。其中,时钟分频模块负责产生像素时钟,VGA驱动模块产生行场同步信号,VGA显示模块输出图像数据。
图 18.4.1 VGA彩条显示系统框图由系统框图可知,FPGA部分包括四个模块,顶层模块(vga_colorbar)、时钟分频模块(vga_pll)、VGA显示模块(vga_display)以及VGA驱动模块(vga_driver)。其中在顶层模块中完成对另外三个模块的例化。各模块端口及信号连接如图 18.4.2所示:
图 18.4.2 顶层模块原理图时钟分频模块(vga_pll)通过调用锁相环(PLL)IP核来实现。根据实验任务要求的分辨率及刷新速率,通过图 18.1.5可以得知本次实验中VGA显示用到的像素时钟为25.175Mhz,因为分辨率不是很高,我们可以设置锁相环IP核让其输出25Mhz的时钟作为像素时钟。VGA驱动模块(vga_driver)在像素时钟的驱动下,根据VGA时序的参数输出行同步(vga_hs)、场同步(vga_vs)信号(VGA时序中各部分的参数同样可以由图 18.1.5得到)。同时VGA驱动模块还需要输出像素点的纵横坐标,供VGA显示模块(vga_display)调用,以绘制彩条图案。顶层模块的代码如下:1modulevga_colorbar(2      input         sys_clk,      //系统时钟3      input         sys_rst_n,      //复位信号4      //VGA接口                        5      output          vga_hs,         //行同步信号6      output          vga_vs,         //场同步信号7      outputvga_rgb         //红绿蓝三原色输出8      );910 //wire define11 wire      vga_clk_w;             //PLL分频得到25Mhz时钟12 wire      locked_w;            //PLL输出稳定信号13 wire      rst_n_w;               //内部复位信号14 wire pixel_data_w;          //像素点数据15 wire [ 9:0]pixel_xpos_w;          //像素点横坐标16 wire [ 9:0]pixel_ypos_w;          //像素点纵坐标   17   18 //*****************************************************19 //**                   main code20 //*****************************************************21 //待PLL输出稳定之后,停止复位22 assign rst_n_w =sys_rst_n && locked_w;23   24 vga_pllu_vga_pll(               //时钟分频模块25.inclk0            (sys_clk),   26.areset            (~sys_rst_n),27   28.c0                (vga_clk_w),    //VGA时钟 25M29.locked            (locked_w)30);3132vga_driver u_vga_driver(33   .vga_clk      (vga_clk_w),   34   .sys_rst_n      (rst_n_w),   3536   .vga_hs         (vga_hs),      37   .vga_vs         (vga_vs),      38   .vga_rgb      (vga_rgb),      39   40   .pixel_data   (pixel_data_w),41   .pixel_xpos   (pixel_xpos_w),42   .pixel_ypos   (pixel_ypos_w)43   );44   45vga_display u_vga_display(46   .vga_clk      (vga_clk_w),47   .sys_rst_n      (rst_n_w),48   49   .pixel_xpos   (pixel_xpos_w),50   .pixel_ypos   (pixel_ypos_w),51   .pixel_data   (pixel_data_w)52   );   53   54 endmodule顶层模块中主要完成对其余模块的例化,需要注意的是在利用IP核进行时钟分频时,系统上电复位后PLL输出的25Mhz时钟需要经过一段时间才能到达稳定状态。在PLL输出稳定后,标志信号locked拉高(第29行)。由于VGA驱动模块及显示模块均由PLL输出的像素时钟驱动,因此在PLL输出稳定之前,其余模块应保持复位状态。如程序中第22行所示,通过将系统复位信号sys_rst_n和PLL输出稳定标志信号locked进行“与”操作,得到内部复位信号rst_n_w。将该信号作为VGA驱动模块及显示模块的复位信号,可避免由于系统复位后像素时钟不稳定造成的VGA时序错误。VGA驱动模块的代码如下所示:1modulevga_driver(2      input         vga_clk,      //VGA驱动时钟3      input         sys_rst_n,    //复位信号4      //VGA接口                        5      output          vga_hs,       //行同步信号6      output          vga_vs,       //场同步信号7      outputvga_rgb,      //红绿蓝三原色输出8      9      input   pixel_data,   //像素点数据10   output[ 9:0]pixel_xpos,   //像素点横坐标11   output[ 9:0]pixel_ypos   //像素点纵坐标   12   );                           13                                                      14 //parameter define15 parameter H_SYNC   =10'd96;    //行同步16 parameter H_BACK   =10'd48;    //行显示后沿17 parameter H_DISP   =10'd640;   //行有效数据18 parameter H_FRONT=10'd16;    //行显示前沿19 parameter H_TOTAL=10'd800;   //行扫描周期2021 parameter V_SYNC   =10'd2;   //场同步22 parameter V_BACK   =10'd33;    //场显示后沿23 parameter V_DISP   =10'd480;   //场有效数据24 parameter V_FRONT=10'd10;    //场显示前沿25 parameter V_TOTAL=10'd525;   //场扫描周期26         27 //reg define                                    28 reg cnt_h;29 reg cnt_v;3031 //wire define32 wire      vga_en;33 wire      data_req;3435 //*****************************************************36 //**                   main code37 //*****************************************************38 //VGA行场同步信号39 assign vga_hs = (cnt_h<= H_SYNC -1'b1)? 1'b0: 1'b1;40 assign vga_vs = (cnt_v<= V_SYNC -1'b1)? 1'b0: 1'b1;4142 // RGB565数据输出使能信号43 assign vga_en = (((cnt_h>= H_SYNC+H_BACK) &&(cnt_h <H_SYNC+H_BACK+H_DISP))44                  &&((cnt_v>= V_SYNC+V_BACK) &&(cnt_v <V_SYNC+V_BACK+V_DISP)))45                  ?1'b1 : 1'b0;46                  47 //RGB565数据输出               48 assign vga_rgb =vga_en ? pixel_data : 16'd0;4950 //像素点颜色数据输入请求信号               51 assign data_req =(((cnt_h >=H_SYNC+H_BACK-1'b1) && (cnt_h< H_SYNC+H_BACK+H_DISP-1'b1))52                   &&((cnt_v >=V_SYNC+V_BACK)&& (cnt_v< V_SYNC+V_BACK+V_DISP)))53                   ?1'b1 : 1'b0;5455 //像素点坐标               56 assign pixel_xpos =data_req ? (cnt_h- (H_SYNC+ H_BACK -1'b1)): 10'd0;57 assign pixel_ypos =data_req ? (cnt_v- (V_SYNC+ V_BACK -1'b1)): 10'd0;5859 //行计数器对像素时钟计数60 always @(posedge vga_clk ornegedge sys_rst_n) begin         61   if (!sys_rst_n)62         cnt_h <=10'd0;                                 63   elsebegin64         if(cnt_h <H_TOTAL - 1'b1)                                             65             cnt_h <=cnt_h + 1'b1;                              66         else67             cnt_h <=10'd0;68   end69 end7071 //场计数器对行计数72 always @(posedge vga_clk ornegedge sys_rst_n) begin         73   if (!sys_rst_n)74         cnt_v <=10'd0;                                 75   elseif(cnt_h== H_TOTAL -1'b1)begin76         if(cnt_v <V_TOTAL - 1'b1)                                             77             cnt_v <=cnt_v + 1'b1;                              78         else79             cnt_v <=10'd0;80   end81 end8283 endmodule程序中第14至25行通过变量声明定义了分辨率为640*480、刷新速率为60hz时VGA时序中的各个参数。如果需要以不同的分辨率或刷新速率显示,只需要根据图 18.1.5修改此处的参数即可。程序第59至69行通过行计数器cnt_h对像素时钟计数,计满一个行扫描周期后清零并重新开始计数。程序第71至81行通过场计数器cnt_v对行进行计数,即扫描完一行后cnt_v加1,计满一个场扫描周期后清零并重新开始计数。将行场计数器的值与VGA时序中的参数作比较,我们就可以判断行场同步信号何时处于低电平同步状态,以及何时输出RGB565格式的图像数据(38~48行)。程序50至57行输出当前像素点的纵横坐标值,由于坐标输出后下一个时钟周期才能接收到像素点的颜色数据,因此数据请求信号data_req比数据输出使能信号vga_en提前一个时钟周期。VGA显示模块的代码如下:1modulevga_display(2      input             vga_clk,                  //VGA驱动时钟3      input             sys_rst_n,               //复位信号4      5      input      [ 9:0]pixel_xpos,               //像素点横坐标6      input      [ 9:0]pixel_ypos,               //像素点纵坐标   7      outputreg pixel_data                //像素点数据8      );   9      10 parameter H_DISP = 10'd640;                  //分辨率—行11 parameter V_DISP = 10'd480;                  //分辨率—列12 localparam WHITE = 16'b11111_111111_11111;   //RGB565白色13 localparam BLACK = 16'b00000_000000_00000;   //RGB565黑色14 localparam RED   = 16'b11111_000000_00000;   //RGB565 红色15 localparam GREEN = 16'b00000_111111_00000;   //RGB565 绿色16 localparam BLUE= 16'b00000_000000_11111;   //RGB565 蓝色17   18 //*****************************************************19 //**                   main code20 //*****************************************************21 //根据当前像素点坐标指定当前像素点颜色数据,在屏幕上显示彩条22 always @(posedge vga_clk ornegedge sys_rst_n) begin         23   if (!sys_rst_n)24         pixel_data <=16'd0;                                 25   elsebegin26         if((pixel_xpos >=0) && (pixel_xpos< (H_DISP/5)*1))                                             27             pixel_data <= WHITE;                              28         elseif((pixel_xpos>= (H_DISP/5)*1) &&(pixel_xpos <(H_DISP/5)*2))29             pixel_data <= BLACK;30         elseif((pixel_xpos>= (H_DISP/5)*2) &&(pixel_xpos <(H_DISP/5)*3))31             pixel_data <= RED;32         elseif((pixel_xpos>= (H_DISP/5)*3) &&(pixel_xpos <(H_DISP/5)*4))33             pixel_data <= GREEN;34         else35             pixel_data <=BLUE;36   end37 end3839 endmoduleVGA显示模块将屏幕显示区域按照横坐标划分为五列等宽的区域,通过判断像素点的横坐标所在的区域,给像素点赋以不同的颜色值,从而实现彩条显示。图18.4.3为VGA彩条程序显示一行图像时SignalTap抓取的波形图,图中包含了一个完整的行扫描周期,其中的有效图像区域被划分为五个不同的区域,不同区域的像素点颜色各不相同。
图 18.4.3 SignalTap波形图1.5      下载验证首先我们打开VGA彩条显示工程,在工程所在的路径下打开vga_colorbar/par文件夹,在里面找到“vga_colorbar.qpf”并双击打开。注意工程所在的路径名只能由字母、数字以及下划线组成,不能出现中文、空格以及特殊字符等。工程打开后如图 18.5.1所示。
图 18.5.1 VGA彩条显示工程然后将VGA连接线一端连接显示器,另一端与开发板上的VGA接口连接。再将下载器一端连电脑,另一端与开发板上对应端口连接,最后连接电源线并打开电源开关。开拓者开发板实物图如下所示:
      
      




图 18.5.2 开拓者开发板实物图接下来我们下载程序,验证VGA彩条显示功能。工程打开后通过点击工具栏中的“Programmer”图标打开下载界面,通过“Add File”按钮选择vga_colorbar/par/output_files目录下的“vga_colorbar.sof”文件。开发板电源打开后,在程序下载界面点击“HardwareSetup”,在弹出的对话框中选择当前的硬件连接为“USB-Blaster”。然后点击“Start”将工程编译完成后得到的sof文件下载到开发板中,如图 18.5.3所示。
图 18.5.3 程序下载界面下载完成后观察显示器显示的图案如图 18.5.4所示,说明VGA彩条显示程序下载验证成功。
图 18.5.4 VGA彩条显示


MurphyZhao 发表于 2019-5-30 09:31:11

上学的时候搞过 VGA 显示,挺复杂的,前排支持{:3_57:}

HDMI 可以搞不

wuwei520 发表于 2019-6-13 17:16:03

厉害,厉害,厉害~~~
页: [1]
查看完整版本: 【正点原子FPGA连载】第十八章 VGA彩条显示实验--摘自【正点原子】开拓者 FPGA 开发指南