配套FPGA开发板(含该设计的工程代码):https://item.taobao.com/item.htm?spm=a1z10.1-c.w4004-4676525296.4.6e8950ed57YPhv&id=17848039135
整体设计
顶层设计RTL图:分为四个模块:
-
PS2按键输入、
-
VGA显示字符、
-
LCD1602显示、
-
数码管显示键值;
FPGA型号
时钟
使用50M晶振
数码管原理图
共阳数码管
显示原理
本设计采用共阳数码管,数码管的段选信号为8bit,数码管的段选对应实物图如下:
一个数码管有八段:A,B,C,D,E,F ,G,H,DP,即由八个发光二极管组成,; 因为发光二极管导通的方向是一定的(导通电压一般取为1.7V),这八个发光二极管的公共端有两种: +5V(即为共阳极数码管)、接地(即为共阴极数码管),其中共阳极每个段均有0导通,而共阴极则1导通发光,所以共阳极数码管和共阴极数码管显然是不同的,段选码表如下图所示:
LCD1602液晶
显示原理
1602常用与显示数字和字母,显示容量为16*2个字符,内部有80个字节的RAM缓冲区,当要向1602送数显示时,要先发送显示地址指针80H+地址码。
内部地址码分布:
1602有16个管脚,其中用于编程操作的有RS(数据命令),RW(读写),E(使能端),D0-D7(并行数据端口)。
由于只要向1602写数据,因此给出写时序图和其时序图上的时序参数:
(其指令说明请详细查看1602数据手册)
Verilog的编程只要遵循时序图描写出时序图那样的信号和满足其时序参数就可以实现FPGA控制1602显示,并且可用状态机实现。
其中由于是往1602写数据因此RW可一直置0电平,使能信号E可以做成时钟信号用于控制数据的传输。
VGA显示
原理图
VGA显示原理
VGA标准
VGA(Video Graphics Array)即视频图形阵列,是IBM 在1987年随PS/2(PS/2 原是"Personal System 2"的意思,"个人系统2",是IBM 公司在1987年推出的一种个人电脑)机推出的。PS/2电脑上使用的键盘鼠标接口就是现在的PS/2接口。因为标准不开放,PS/2电脑在市场中失败了。只有PS/2接口一直沿用到今天)一起推出的使用模拟信号的一种视频传输标准,在当时具有分辨率高、显示速率快、颜色丰富等优点,在彩色显示器领域得到了广泛的应用。这个标准对于现今的个人电脑市场已经十分过时。即使如此,VGA仍然是最多制造商所共同支持的一个标准,个人电脑在加载自己的独特驱动程序之前,都必须支持VGA的标准。例如,微软Windows系列产品的开机画面仍然使用VGA显示模式,这也说明其在显示标准中的重要性和兼容性。
在VGA显示驱动中最重要的就是行同步信号、场同步信号、RGB信号。
由于VGA的显示原理是从左到右,由上至下,如下图所示:
该显示模式就是采用对整个显示屏进行扫描的方法进行的,所以要驱动显示屏,最关键的就是行同步信号hsync和场同步信号vsync的产生,同时,配合这两个扫描信号,往RGB信号线上送显示数据。而这两个扫描信号的产生则取决于所选择的VGA显示标准。
VGA显示标准
进行VGA显示首先是确定VGA的显示的标准,关键根据VGA显示标准确定行同步信号hsync和vsync两个信号和显示标准之间的关系,同时根据hsync和vsync确定有效的显示区域。
(以800*600@60HZ为例)hsync是用来控制"列像素显示",而一个hsync可以分为4个段,也就是a(同步段) ,b(后沿段),c(有效段),d(前沿段)。hsyn的a是拉低的128个列像素,b是拉高的88个列像素,至于c是拉高的800个列像素,而最后的d是拉高的40个列像素。一列总共有1056个列像素。
(以800*600@60HZ为例)vsync是用来控制"行扫描"。而一个vsync同样可以分为4个段,也是o(同步段) ,p(后沿段),q(有效段),r(前沿段)。vsync的o是拉低的4个行像素,p是拉高的23个行像素,至于q是拉高的600个行像素,而最后的r 是拉高的1个行像素。一行总共有628个行像素。
通过VGA的行同步和场同步时序图,驱动显示屏进行显示的时序段是行有效段和场有效段,所以在产生行同步信号和场同步信号的时候,要根据这个显示模式产生显示的有效信号,在这个显示信号有效的时候进行RGB的数据输出。所以在设计VGA驱动模块的时候,需要一个行、场地址产生模块,通过对驱动的时钟进行计数,来控制行同步信号和场同步信号,并根据这两个地址信号来确定显示屏的坐标(vsync,hsync),在知道坐标之后就可以往显示屏上的任意位置进行显示。
在确定了显示区域之后就是要确定要显示的位置,位置的确定要通过hsync和vsync进行确定,比如采用显示的标准为640*480@60,其表明的意思是显示高度为480个像素和640个像素点的宽度,一秒钟刷新的频率最大为60帧个画面,显示一个像素点的时间为1/25.175MHz,可以采用向下兼容时钟的方法,用25MHz的时钟进行驱动显示一个像素点,所以一个像素点显示的时间就是为4ns,640*480个像素点的显示时间就是为640*480*4ns=1,228,800ns,因此像素点的显示时钟就是25MHz,hsync和vsync的驱动时钟就是25MHz,VGA的显示顺序:
采用640*480的显示标准进行显示图片,则图片要存在ROM中。假设要显示64*64的图片的话(逐行式扫描),就要用一个位宽为64,深度为64的ROM来进行存储。用场同步信号来对ROM进行寻址,在读到数据之后用行同步信号对读出的数据进行寻位(一位数据确定对应的像素点是亮还是灭)。(该过程可以相反,如果采用的是逐列式扫描)
ADV7123驱动原理
ADV7123芯片原理
ADV7123最高可以支持100Hz的刷新频率和1600*1200的像素分辨率,内含3路最高达到240MS/s的 10位视频D/A转换器,时钟频率为50M。
产品简介
● 240MHz的最大样速度
●三路10位D/A转换器
● SFDR
当时钟频率为50MHZ;输出为1MHZ时,–70dB
当时钟频率为140MHZ;输出为40HMZ时,-53dB
●与RS-343A/RS-170接口输出兼容
● DA转换器的输出电流范围为:2mA到26mA
● TTL兼容输入
●单电源+5V/+3.3V工作
●低功耗(3V时最小值为30mW)
引脚说明:
BLANK:消隐信号,低电平有效;
SYNC:复合同步信号,低电平有效,在使用中将该信号接地;
R、G、B: 数字信号,控制3路DAC的输出。
PSAVE: 上电有效,高电平有效,一般接VCC;
CLOCK: 工作时钟,用于控制数据和内部DAC转换;
IOR、IOG、IOB:3路RGB数字信号转换后的输出(与另外相反的三路输出形成差分输出);
驱动时序
RGB数据输入在上升沿有效,所以VGA的驱动控制模块的时钟必须和ADV7123的时钟一致。模拟输出在时钟上升沿之后的t6时间输出。
对于消隐信号BLANK则在行同步信号和场同步信号有效段以外的时序内有效。
ADV7123的原理图
VGA显示方案设计
程序结构
设计原理
该设计分为3个模块,实验中采用的VGA显示模式是640*480@60Hz,所以需要的时钟频率为25M,由于外部时钟为50M,所以需要对外部的时钟进行二分频,所以"VGA分频模块"就是负责这个简单的工作。
上面已经提及,VGA驱动最重要的就是产生行同步信号、场同步信号、RGB数据信号。
VGA的显示模式就是扫描显示,行扫描和场扫描,通过行扫描和场扫描确定显示的位置,并同时产生行、场同步信号,同时,根据行、场扫描的位置进行显示预先要显示的内容。
所以这两个工作分为两个模块进行完成,其中VGA时序同步模块"VGA时序同步模块"负责产生行同步信号和场同步信号,还由产生RGB数据有效信号,用于使能RGB信号输出有效,RGB数据有效信号的确定是根据行信号和场信号共同确定的。
对于"VGA控制模块"则负责根据"VGA时序同步模块"产生的扫描位置坐标、RGB数据有效信号来进行输出RGB数据信号。
由于要显示的内容事先存储在ROM中,所以当扫描到要显示的位置时便将地址信号送到ROM中进行读取数据,然后将读取的数据送到RGB数据信号上。
顶层设计
FPGA一贯采用由上至下的设计方法,从顶层设计中也可以看出我们设计的初衷,VGA_sync模块负责产生行同步信号hsync_sig和场同步信号vsync_sig,同时将行坐标cloumn_addr和场坐标row_addr传送至VGA_control模块,用ready信号标志显示的有效区。VGA_sync模块产生时序信号,VGA_control模块用于产生RGB数据信号。
VGA控制模块
"VGA控制模块"则负责根据"VGA时序同步模块"产生的扫描位置坐标cloumn_addr和row_addr、RGB数据有效信号ready来进行输出RGB数据信号adv7123_r、adv7123_g、adv7123_b。
将RGB数据信号进行缓存一级再进行输出。
display信号为通过判断行坐标和场坐标,进行产生显示信号,该信号标志是否扫描到要显示的区域。程序中的判断范围为:(80,100)~(400,540)的长方形区域,即该区域就是要显示的图像或者字符的区域,row_addr表示纵向,cloumn_addr表示横向。
由于要显示的数据存储在ROM中,所以要产生寻址ROM的地址信号,这里就涉及到一个问题,就是ROM中的数据表示什么意思?
一个中文占用64个像素点,由于实验中要显示三个中文,所以要占用192个像素,总共的像素点为64*192=12288个像素点,每个像素点就是一个bit,这里采用一个宽度为64bit,深度为256的ROM来进行存储这三个中文字符。如下:
要显示1个英文或者数字字符,所以纵向的像素点长度为32,横向的像素点长度为64。
这里确定的显示区域为(224,208)~(256,272),刚好满足了这个长度为32,宽度为64的长方体。
在明白了如何将ROM中的数据显示到对应的区域之后剩下的问题就是如何将ROM 中的数据读取出来。
这里采用cloumn_addr来产生寻址ROM的地址信号,至于为什么要减去11‘d224,是因为我们要显示的起始地址为224,所以要减去11‘d224,然后再对ROM进行寻址,这样就能够将ROM中的第一个数据显示到起始地址上。
由于从ROM中读出的数据是一个64bit的数据所以要将64bit的数据分成1bit的形式,1bit则对应一个像素点。cloumn_addr决定了纵向坐标,row_addr决定了横向坐标,所以用row_addr来取出64bit中的每一bit,显示在对应的位置上。至于要减去11‘d208,是因为要显示的横向起始地址为11‘d208,所以要减去11‘d208,然后取出对应的bit。
位图的显示是由三基色共同控制而形成的,一般的显示的格式有RGB565。该实验中ROM存储的数据是一个像素点1bit的,谈不上位图,该bit表明的是显示与不显示,而RGB565一个像素点的数据是16bit。red、green、blue读出ROM中每1bit的数据,然后控制adv7123_r_w、adv7123_g_w、adv7123_b_w的数值,然后用frame帧信号作为触发信号,在每次显示完一帧(1秒60帧)便改变显示字符的颜色。
VGA时序同步模块
VGA_sync模块最关键的就是产生hsync_sig行同步信号和vsync_sig场同步信号、
VGA_control模块接口信号、ADV7123接口信号。
该实验采用的显示模式为640*480@60Hz,所以下面的显示模式的参数将决定了如何去产生这写接口信号和时序信号。如果往后要改变显示模式,这个设计过程是必须掌握的!!
下面根据各个程序块进行说明如何通过这些参数来产生想要的信号。
行计数信号count_h在每个时钟的上升沿加一,当为799时清零,表明已经扫描好了显示屏上的一行,这时场计数信号count_v加一,当场计数信号为524时进行清零,这时表明已经扫描完整个显示屏,也就是扫描完一帧,这时帧计数信号frame_cnt加一。
count_h、count_v就是对显示屏扫描的地址。
这里回顾下行同步信号和场同步信号的时序图:
hsync_sig在时段a时为0,所以:
assign hsync_sig = (count_h <= 11‘d95) ? 1‘b0 : 1‘b1;//设置HSY时序
vsync_sig在时段0为0,所以:
assign vsync_sig = (count_v <= 11‘d1) ? 1‘b0 : 1‘b1;//设置VSY时序
ready标志显示的有效区,就是行同步信号和场同步信号的有效段,如下图;
有效显示区域就是绿色线圈起的区域,也就是下面红色圈的代码模块:
783 = 800 -16(d段像素点) - 1;
514 =525 – 10(r段像素点)- 1;
VGA分频模块
分频模块采用一个D触发器进行二分频,这种是最简单的分频方法,如果一个时钟信号,经过n级D触发器之后,最后的时钟频率就是原始时钟的2n分之一。
字模显示
由于要显示的字符需要进行存储到ROM中,所以工程构造了36个rom用来存储要显示在电脑显示器的字符。36个字符为10个数字和26个英文字母。
PS2接口
原理
PS/2是在较早电脑上常见的接口之一,用于鼠标、键盘等设备。一般情况下,PS/2接口的鼠标为绿色,键盘为紫色。PS/2 原是"Personal System 2"的意思,"个人系统2",是IBM公司在上个世纪80年代推出的一种个人电脑。以前完全开放的PC标准让IBM觉得利益受了损失。所以IBM设计了PS/2这种电脑,目的是重新定义PC标准,不再采用开放标准的方式。在这种电脑上IBM使用了新型MCA总线,新的OS/2操作系统。PS/2电脑上使用的键盘鼠标接口就是现在的PS/2接口。因为标准不开放,PS/2电脑在市场中失败了。只有PS/2接口一直沿用到今天。
PS/2接口是输入装置接口,而不是传输接口。所以PS2口根本没有传输速率的概念,只有扫描速率。在Windows环境下,ps/2鼠标的采样率默认为60次/秒,USB鼠标的采样率为120次/秒。较高的采样率理论上可以提高鼠标的移动精度。 PS/2接口设备不支持热插拔,强行带电插拔有可能烧毁主板。PS/2可以与USB接口互转,即PS/2接口设备可以转成USB,USB接口设备也可以转成PS/2。 早期,在PS/2键盘中,包含了一个嵌入式的微控制器(如InDl,8048系列),以用来执行各项的工作并减少整个系统工作中的负担。微控制器所要作的工作就是监测所有的按键,以及当按键被按下或放开时,就回报给主机。
PS/2标准接口
如上图所示,PS/2标准使用了6个接口,各个接口的定义如下:
DATA :数据信号
N.C:不连接
GND: 数字地
VCC: +5V电源
CLK:时钟信号
N.C:不连接
数据帧格式如下图所示,起始位为低电平,停止位为高电平,应答位仅在主机对设备的通信中使用。如果数据位中1的个数为偶数,检验位就为1;如果数据位中1的个数为奇数,检验位就为0;总之,数据位中1的各个加上检验位中1的个数总为奇数,因此总进行奇校验。这一点与串口通讯有点类似。PC通过PS/2接口与从设备通信时,总在时钟的下降沿读数据。
PS/2的数据帧格式
键盘编码返回值
键盘的返回值并不是和一般的ASCII码相对应。键盘的处理器如果发现有按键按下、释放或按住,将发送扫描码的信息包到计算机。扫描码有两种不同类型的通码和断码,当一个按键按下或按住,就发送通码;当一个键被释放,就发送断码。每个按键被分配了唯一的通码和断码,这样主机通过查找唯一的扫描码就可以测定是哪个键。每个键一整套的通断码就组成了扫描码集,有三套标准的扫描码集,分别是第一套、第二套和第三套。所有现代的键盘默认使用第二套扫描码。
虽然多数第二套通码都只有一个字节宽,但也有少数扩展按键的通码是2字节或4字节宽,这类的通码第1个字节总是为8‘be0.
正如有键按下,通码就被发送计算机一样,只要键一释放,断码就会被发送。每个键都有它自己唯一的通码,也都有唯一的断码。在通码和断码之间存在着必然的联系。多数第二套断码有2字节长,它们的第1个字节是8‘hf0;第2个字节是这个键的通码。扩展按键的断码通常有3个字节,它们前2个字节是8‘he0、8‘hf0,最后1个字节是这个按键的通码。
下面举例进行。通码和断码是以什么样的序列发送到计算机,从而使得字符G出现在串口调试助手字母显示框的。因为这个一个大写字母,需要一次按下Shift键,再按下G键,释放G键,再释放Shift键。与这些时间相关的扫描码如下:Shift键的通码"8‘h12"。G键的通码"8‘h34",G键的断码"8‘hf0 8‘h34",Shift键的断码"8‘hf0 8‘h12".因此发送到计算机的数据应该是:8‘h12 8‘h34 8‘hf0 8‘h34 8‘hf0 8‘h12。
LED
复位按键
使用KEY0作为复位按键,低电平复位;