fpga控制led闪烁实验心得:正点原子开拓者FPGA开发板资料连载第十八章
fpga控制led闪烁实验心得:正点原子开拓者FPGA开发板资料连载第十八章18.1 VGA简介本章包括以下几个部分:VGA是IBM公司在1987年推出的一种视频传输标准,它具有分辨率高、显示速率快、颜色丰富等优点,因而在彩色显示器领域得到了广泛的应用。虽然由于体积较大等原因,VGA接口已经逐渐被笔记本电脑淘汰,但是对于台式机而言,VGA仍是制造商所支持的最低显示标准。
1)实验平台:正点原子开拓者FPGA 开发板
2)摘自《开拓者FPGA开发指南》关注官方微信号公众号,获取更多资料:正点原子
3)全套实验源码 手册 视频下载地址:http://www.openedv.com/thread-13912-1-1.html
第十八章 VGA彩条显示实验
VGA是IBM公司在1987年推出的一种视频传输标准,它具有分辨率高、显示速率快、颜色丰
富等优点,因而在彩色显示器领域得到了广泛的应用。虽然由于体积较大等原因,VGA接口已
经逐渐被笔记本电脑淘汰,但是对于台式机而言,VGA仍是制造商所支持的最低显示标准。
本章包括以下几个部分:
18.1 VGA简介
18.2 实验任务
18.3 硬件设计
18.4 程序设计
18.5 下载验证
VGA简介
VGA的全称是Video Graphics Array,即视频图形阵列,是一个使用模拟信号进行视频传
输的标准。早期的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时序参数
实验任务
本节实验任务是使用开拓者开发板上的VGA接口在显示器上显示彩条,要求分辨率为
640*480,刷新速率为60hz。
硬件设计
开拓者开发板上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彩条实验管脚分配
程序设计
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)调用,以绘制彩条图案。
顶层模块的代码如下:
1 module vga_colorbar(
2 input sys_clk //系统时钟
3 input sys_rst_n //复位信号
4 //VGA接口
5 output vga_hs //行同步信号
6 output vga_vs //场同步信号
7 output [15:0] vga_rgb //红绿蓝三原色输出
8 );
9
10 //wire define
11 wire vga_clk_w; //PLL分频得到25Mhz时钟
12 wire locked_w; //PLL输出稳定信号
13 wire rst_n_w; //内部复位信号
14 wire [15:0] pixel_data_w; //像素点数据
15 wire [ 9:0] pixel_xpos_w; //像素点横坐标
16 wire [ 9:0] pixel_ypos_w; //像素点纵坐标
17
18 //*****************************************************
19 //** main code
20 //*****************************************************
21 //待PLL输出稳定之后,停止复位
22 assign rst_n_w = sys_rst_n && locked_w;
23
24 vga_pll u_vga_pll( //时钟分频模块
25 .inclk0 (sys_clk)
26 .areset (~sys_rst_n)
27
28 .c0 (vga_clk_w) //VGA时钟 25M
29 .locked (locked_w)
30 );
31
32 vga_driver u_vga_driver(
33 .vga_clk (vga_clk_w)
34 .sys_rst_n (rst_n_w)
35
36 .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
45 vga_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驱动模块的代码如下所示:
1 module vga_driver(
2 input vga_clk //VGA驱动时钟
3 input sys_rst_n //复位信号
4 //VGA接口
5 output vga_hs //行同步信号
6 output vga_vs //场同步信号
7 output [15:0] vga_rgb //红绿蓝三原色输出
8
9 input [15:0] pixel_data //像素点数据
10 output [ 9:0] pixel_xpos //像素点横坐标
11 output [ 9:0] pixel_ypos //像素点纵坐标
12 );
13
14 //parameter define
15 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; //行扫描周期
20
21 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 [9:0] cnt_h;
29 reg [9:0] cnt_v;
30
31 //wire define
32 wire vga_en;
33 wire data_req;
34
35 //*****************************************************
36 //** main code
37 //*****************************************************
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;
41
42 // 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;
49
50 //像素点颜色数据输入请求信号
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;
54
55 //像素点坐标
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;
58
59 //行计数器对像素时钟计数
60 always @(posedge vga_clk or negedge sys_rst_n) begin
61 if (!sys_rst_n)
62 cnt_h <= 10'd0;
63 else begin
64 if(cnt_h < H_TOTAL - 1'b1)
65 cnt_h <= cnt_h 1'b1;
66 else
67 cnt_h <= 10'd0;
68 end
69 end
70
71 //场计数器对行计数
72 always @(posedge vga_clk or negedge sys_rst_n) begin
73 if (!sys_rst_n)
74 cnt_v <= 10'd0;
75 else if(cnt_h == H_TOTAL - 1'b1) begin
76 if(cnt_v < V_TOTAL - 1'b1)
77 cnt_v <= cnt_v 1'b1;
78 else
79 cnt_v <= 10'd0;
80 end
81 end
82
83 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显示模块的代码如下:
1 module vga_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 output reg [15:0] 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 code
20 //*****************************************************
21 //根据当前像素点坐标指定当前像素点颜色数据,在屏幕上显示彩条
22 always @(posedge vga_clk or negedge sys_rst_n) begin
23 if (!sys_rst_n)
24 pixel_data <= 16'd0;
25 else begin
26 if((pixel_xpos >= 0) && (pixel_xpos < (H_DISP/5)*1))
27 pixel_data <= WHITE;
28 else if((pixel_xpos >= (H_DISP/5)*1) && (pixel_xpos < (H_DISP/5)*2))
29 pixel_data <= BLACK;
30 else if((pixel_xpos >= (H_DISP/5)*2) && (pixel_xpos < (H_DISP/5)*3))
31 pixel_data <= RED;
32 else if((pixel_xpos >= (H_DISP/5)*3) && (pixel_xpos < (H_DISP/5)*4))
33 pixel_data <= GREEN;
34 else
35 pixel_data <= BLUE;
36 end
37 end
38
39 endmodule
VGA显示模块将屏幕显示区域按照横坐标划分为五列等宽的区域,通过判断像素点的横坐
标所在的区域,给像素点赋以不同的颜色值,从而实现彩条显示。
图 18.4.3为VGA彩条程序显示一行图像时SignalTap抓取的波形图,图中包含了一个完整
的行扫描周期,其中的有效图像区域被划分为五个不同的区域,不同区域的像素点颜色各不相
同。
图 18.4.3 SignalTap波形图
下载验证
首先我们打开VGA彩条显示工程,在工程所在的路径下打开vga_colorbar/par文件夹,在
里面找到“vga_colorbar.qpf”并双击打开。注意工程所在的路径名只能由字母、数字以及下
划线组成,不能出现中文、空格以及特殊字符等。工程打开后如图 18.5.1所示。
图 18.5.1 VGA彩条显示工程
然后将VGA连接线一端连接显示器,另一端与开发板上的VGA接口连接。再将下载器一端连
电脑,另一端与开发板上对应端口连接,最后连接电源线并打开电源开关。
图 18.5.2 开拓者VGA接口
接下来我们下载程序,验证VGA彩条显示功能。
工程打开后通过点击工具栏中的“Programmer”图标打开下载界面,通过“Add File”按
钮选择vga_colorbar/par/output_files目录下的“vga_colorbar.sof”文件。开发板电源打
开后,在程序下载界面点击“Hardware Setup”,在弹出的对话框中选择当前的硬件连接为
“USB-Blaster[USB-0]”。然后点击“Start”将工程编译完成后得到的sof文件下载到开发板
中,如图 18.5.3所示。
图 18.5.3 程序下载界面
下载完成后观察显示器显示的图案如图 18.5.4所示,说明VGA彩条显示程序下载验证成功
图 18.5.4 VGA彩条显示