EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
本帖最后由 Heaven_1 于 2023-3-27 16:03 编辑
4 b% j+ ~, C; }( D2 ?* R& f# g# z( u" H% ~9 o% F; y
大侠好,欢迎来到FPGA技术江湖。本系列将带来FPGA的系统性学习,从最基本的数字电路基础开始,最详细操作步骤,最直白的言语描述,手把手的“傻瓜式”讲解,让电子、信息、通信类专业学生、初入职场小白及打算进阶提升的职业开发者都可以有系统性学习的机会。
3 t: J6 o! ?2 ^# K i5 |9 A
系统性的掌握技术开发以及相关要求,对个人就业以及职业发展都有着潜在的帮助,希望对大家有所帮助。后续会陆续更新 Xilinx 的 Vivado、ISE 及相关操作软件的开发的相关内容,学习FPGA设计方法及设计思想的同时,实操结合各类操作软件,会让你在技术学习道路上无比的顺畅,告别技术学习小BUG卡破脑壳,告别目前忽悠性的培训诱导,真正的去学习去实战应用,这种快乐试试你就会懂的。话不多说,上货。 - ^+ h, w+ [' L3 q
) j2 `5 K+ R3 V$ v" j2 h" x
图像显示系统设计
5 W. E. j7 l% r
& m( t& S/ }: B9 _' [5 m+ P
# @ P8 Z! S. v/ U/ N, k; f: g- R' }# h2 w
" M0 F9 i5 y) z, G0 q# c2 s- c
利用摄像头捕获数据、SDRAM缓存数据、VGA协议驱动屏幕显示图像构成图像实时显示系统。
0 j# j; n0 U% |' W i/ W j, x
摄像头捕获数据的速度(12MHz、6MHz、3MHz)与VGA协议驱动速度(25MHz)不同,导致摄像头捕获数据不能够直接输出给VGA,所以中间必须加入大容量的缓冲器。 ' L* L$ b8 {6 c% B
整个设计需要的时钟有:给摄像头提供24MHz的时钟,给SDR SDRAM提供的100MHz的时钟(相移270度),给SDR SDRAM控制器提供的100MHz的时钟,给VGA协议驱动提供的100MHz的时钟。
7 x% l# z- ?! g( j9 `! o1 c* o
· 时钟产生 / W( X# g8 ^% A
采用片内的PLL产生所需的时钟。
· 摄像头驱动设计
- s0 f/ q- a* E: I# Y8 u 摄像头设计共分为三部分:硬件复位(ov7670_hardware_reset)、寄存器配置(ov7670_reg_init)、数据捕获输出(ov7670_cap)。 g2 C$ y$ _5 y$ B( i& K# Z
硬件复位和寄存器配置采用24MHz的时钟进行驱动,摄像头捕获模块采用摄像头输出的pclk来进行驱动。 ; i* B, H3 D% ^" E6 i$ E- \* {
7 P3 z. n/ x% S' `8 d
硬件复位的操作为将cmos_rst_n信号拉低一段时间(大约1ms),拉高后一段时间(大约1ms)内不允许进行任何其他操作。在复位完成后,输出一个复位完成信号。
8 D, y7 A5 a4 l0 k3 g8 z$ D
8 g( ]6 j( O* i/ n( q0 Z
摄像头有很多寄存器,具体可以查看手册中所对应的信息,这里只给出一些关键寄存器的配置。
0 s* L# T4 `4 j6 O- H) u
配置寄存器的地址和配置所需的数据拼接到一起形成一个八位的数据。具体代码查看reg_config。
* ?" s: I* {. H0 m. f+ s
利用线性序列机实现SCCB协议驱动,将对应的数据配置进去。具体代码查看sccb_wr。 ' z4 `5 J# [; c& `& @ _5 B) P. C
编写控制器从reg_config中读出数据,控制sccb_wr模块将数据配置到摄像头中,配置完成后需要等待10帧的图像(摄像头输出的VS信号为帧同步信号,有一次的高脉冲表示一帧,设计时只需要等待VS信号的10个上升沿即可),才能够输出稳定的图像信息。具体代码查看ov7670_reg_config_ctrl。
$ V% Z' y' O% A, z. }
2 U/ m. R, @/ n" L
图像数据的捕获比较简单,按照摄像头手册的标准输出时序进行捕获即可。由于摄像头输出的数据为RGB565,而摄像头接口只有三位数据线,所以输出时,每两个数据对应一个像素点。具体代码查看ov7670_cap。
t) }. L% M& k) b1 \$ `7 n# E% W
· VGA协议驱动 . B4 J1 i5 F+ z0 u8 |
VGA协议与8.5节类似,但是需要在图像显示有效区去读取FIFO,然后将数据输出到VGA接口上。由于摄像头的接口是RGB565,而VGA接口为RGB232接口,故将RGB565对应的高位输出到RGB232上(再分配管脚时,低位不分配也可以)。具体代码查看vga_ctrl。 / m# Z8 S1 l! T2 N3 }
· SDR SDRAM控制器
. g; K* n) C# a, ]% Q 本系统中的图像模式为640X480,在SDRAM中存储的方式设定为SDRAM每一行存储160个像素点,利用四行的存储空间存储一行的图像信息。故而需要将SDR SDRAM控制器中的读写模块更改为页读页写模式,并且每次突发的长度为160。具体代码查看sdr_wr_ctrl和sdr_rd_ctrl。 / c( M- f/ E- Z; `" o/ G/ A/ t3 O& U
SDR SDRAM的控制器中共分为四部分:输入缓冲器(sdr_wRFifo)、输出缓冲器(sdr_rdfifo)、SDR SDRAM驱动(sdr_drive)和读写控制器(sdr_mem_ctrl)。 / X* ~$ E: }, w R1 e& w
输入缓冲器为一个FIFO,捕获到摄像头数据输入到此FIFO中,然后写入到SDRAM中。
* k4 Z4 S% D7 Y6 j
输出缓冲器为一个FIFO,SDRAM的数据输入到此FIFO中,然后被VGA模块读出输出给VGA接口。
9 @5 o7 E; g* H! e0 J& y
SDR SDRAM驱动为控制接口模块,完成对SDRAM的写入和读出。
2 C( f( n I! q
读写控制器为控制上述三个模块进行协调工作的模块:当输入缓冲器中的数量大于160时,读出160个写入SDRAM中;当输出缓冲器中的数量小于160时,从SDRAM中读出160个写入到输出缓冲器中。每次控制读写命令发出后,等待100个时钟周期(等待SDRAM控制器读写进行)。在进行写入和读出时,为了防止图像撕裂(写入速度比读出速度要慢,读出数据时,就会发生前半帧为新数据,后半帧为旧数据,造成一种图像撕裂的感觉),采用两个bank进行缓冲(当输出地址在最后一行时,需要判断输入地址的位置,当输入地址在另外一个bank的下半部分或者已经在本bank时,读地址切换到另外一个bank。写地址正常切换即可)。 / m/ l) X' P' `
6 ~; y9 N& D% N8 s- L' l
部分参考代码如下:
) b/ z% d/ h5 z5 F: i* J+ i
顶层代码: 9 \. [6 U# D; c: B/ I( `
2 i% e4 Z/ N) }' H1 s- N
vga_ctrl模块代码:
' z+ X3 `! w* x/ s
C" d- w) S' J3 H8 L/ z R
ov7670_drive模块代码: + V/ \0 h6 t, k5 H0 \1 D
& u: J: R6 |3 f
fifo_sdr_ctrl模块代码:
0 w7 [! `% g( Z5 Z$ L& v. S
6 |7 r: g+ c3 Q% ^5 @' a
具体设计参考代码_15_ov7670_sdram_vga640x480,代码获取方式可以加QQ交流群咨询。 " B7 |5 J$ r4 \# K# C* o
综合下板后,开发板即可将摄像头捕获到的图像,显示到VGA屏幕上。
1 }. T2 `, d2 g8 }
) ^' }$ h2 w: u/ m& P+ s
|