原创 简单VGA的FPGA实现(上)

2016-1-19 23:50 1321 9 9

最近打算用FPGA读取OV7670摄像头然后通过用VGA显示在电脑显示器上。但是要实现该功能工作量实在有点大,不过一步一步来总会做出来的。

先来了解一下VGA。

我们先来看一下VGA的接口定义。

20160115121625656.jpg

除了电源线以及地线,VGA最重要的有5个端口:RED、GREEN、BLUE、H_SYNC、V_SYNC。这5个端口的作用如下:

RED:提供像素红色分量的模拟电压。(0——0.7V)

GREEN:提供像素绿分量的模拟电压。(0——0.7V)

BLUE:提供像素蓝色分量的模拟电压。(0——0.7V)

H_SYNC:水平同步(行同步)

V_SYNC:垂直同步(场同步)

 

在介绍这几个引脚的功能之前,先让我们做以下实验。

假设现在主机持续地发送同一个8bit的数据(0bXXXX_XXXX)给从机,主从机都知道该数据的长度为8bit,但是主机跟从机只有一个数据端口PA连接(已共地)。

20160115114648354.jpg

主机在某个内部工作时钟的上升沿开始发送数据的LSB,然后依次在下一个时钟上升沿发送下一位,直到发送完8bit,然后等待一固定时间,再重复上述步骤。

PA端口的电平变化如下图所示(矩形表示根据数据具体变化的电平)

20160115114807201.jpg

此时,从机能否识别出主机发送的数据?不能,因为不同数据会导致PA端口的电平出现不同的变化,从机无法根据PA端口的电平来反推主机发送过来的数据。

好,那我们再加一根线PB,该线加了下拉电阻。

20160115114841476.jpg

在主机准备开始发送数据时,主机将其电平拉高,发送完了再放低。这样一来,从机就可以通过读取该线的电平来判断主机数据的发送状态:上升沿--->主机开始发送数据,高电平--->主机发送数据中,下降沿--->主机发送数据完毕。

20160115115007891.jpg

由于主机发送一个8Bit的数据的时间是一定的,设为Ts;而从机又可以通过PB端口知道Ts的开始时刻以及持续时间。那么,从机就可以在PB的上升沿采集PA的数据作为8Bit数据的第一位,然后依次等待Ts/8的时间后,再采集下一位,直到采集完8bit的数据。这样,从机就可以得到主机发送过来的一个完整的数据了。

然后出于对线路以及其他一些方面的考虑,主机需要在正式开始发送之前,先预先通知一下从机,告诉从机,你在接收到通知时开始计时,经过时间Ta后,我们就正式开始发送数据;我们发送完数据后可能还需要处理一下别的事情,需要时间Tb,等我们处理完了,再通知你。该改变如下图所示。

20160115115054785.jpg

则此时从机的读取顺序则改变为:在PB的上升沿开始等待Ta,时间一到就开始采集PA的数据作为8Bit数据的第一位,然后依次等待Ts/8的时间后,再采集下一位,直到采集完8bit的数据,然后再等待PB的下一个上升沿,开始下一轮的读取。

经过建立以上的连接与时序,主机就可以把数据源源不绝地发送从机。但此时的数据就是一串的,没有开头也没有结尾,主机可以持续地把一个一维数组的元素发送给从机,但是从机却无法知道哪个数据是这个数组的开始元素、这个数组的大小,所以也就无法把该数组从接收到的数据串中截取出来。

那没办法,我们只好在主机从机之间再接一根线,也接了下拉电阻。

20160115115233213.jpg

主机在准备开始发送数组前就把PC拉高,正在发送数组成员时持续拉高,发送完毕后就放低。然后还是考虑到其他一些因素,PC需要提前拉高以及推后放低。如此一来,得到下面的图。

20160115115326309.jpg

至此为止,主机已经可以把一个元素为8bit的数据的任意长度的一维数组发送给从机了。

那假如是9bit,10bit的呢?一样的道理,只要主机从机约定好就可以了。

接下来,我们把从机接收到的一维数组处理一下,转化成矩阵。

假设从机收到的数组的元素为n bit的数据,数组长度为m。那我们建立一个m行n列的矩阵,先取出数组的第一个元素,取其MSB的值放在矩阵(0,0)处,取下一bit放在矩阵(0,2)处,依次填充,该元素的LSB放在矩阵(0,n-1)处;再取出第二个元素,取其MSB的值放在矩阵(1,0)处,取下一bit放在矩阵(1,2)处,依次填充,该元素的LSB放在矩阵(1,n-1)处;依次类推,用数组填充好矩阵。于是,我们得到了一个矩阵。

假如我们再把数据线PA扩充成三根:PA0、PA1、PA2,那么,依照之前的时序,主机就可以同时发送三个元素数量相同、元素位宽相同的数组。而利用这三组数组,我们就可以把原先矩阵元素的位宽由1拓展为3。

20160115115434421.jpg

假如我们再把数据线改成模拟量传输,那么,我们得到的矩阵元素就可以为(a,b,c),其中a,b,c为ADC得到的数据。

OK,回到VGA。VGA的工作原理与此类似,对应的VGA引脚的时序也可以大概如此表示。

20160115115649118.jpg

因为一张图片可以对应一个矩阵,矩阵的行、列与图片的高、宽相对应,而单个像素与矩阵的单个元素对应。而一个像素的值由r,g,b三个分量组成,对应组成矩阵单个元素的数组中的(r,g,b)成员。

VGA就是这样传输了一张图片的。

上篇先介绍到这里,具体的FPGA实现在下篇再详细解释。

最后,附上一篇我觉得对FPGA解释的比较清晰的文章。

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
9
关闭 站长推荐上一条 /3 下一条