1. 概述
本设计采用FPGA技术,将CMOS摄像头(LVDS接口)的视频数据经过采集、存储、帧率转换及格式转换,最终通过USB2.0接口显示在电脑屏幕上。
2. 硬件系统框图
CMOS采用smartsens的全局曝光芯片SC130GS,FPGA采用ALTERA公司的CYCLONE IV,FLASH采用EPCS64,DDR2采用Hynix公司的1Gb内存条,USB2.0采用Cypress公司的68013芯片。
3. FPGA逻辑框图
FPGA各部分逻辑模块如下图所示:
LVDS Decode,解码CMOS摄像头视频数据;
I2C Master,配置CMOS芯片;
DDR2 Control,配置与控制DDR2芯片组,实现读写仲裁;
FIFO Write,将采集到的视频数据跨时钟域地写进DDR2中;
FIFO Read,将DDR2中的数据跨时钟域地读出给后续图像处理模块;
Frame Buffer,负责FIFO Write和FIFO Read的调度,实现帧率转换;
USB Control,接受USB PHY的请求,通过FIFO Read向DDR2索取数据,并自定义打包发送给USB PHY芯片。
4. 全局曝光
全局曝光是针对逐行曝光的改进,在逐行曝光下,sensor是按照行为单位进行逐行曝光,这样当被摄物体和sensor存在高速的相对运动时,图像会发生形状和颜色的变形,如下图所示:
而全局曝光则是以帧为单位进行曝光,可以拍摄到高速运动的物体且没有变形。
5. LVDS解码
SC130GS提供差分串行接口(LVDS),支持1/2/4个Data lane来传输图像8/10/12 bit数据。这里以4个data lane,同步信号内嵌的模式为例,介绍其传输时序。
6. CMOS配置
CMOS sensor支持最高130万像素,240帧的视频输出。
SpiWriteRegister(0x01,0x03,0x01);// soft reset SpiWriteRegister(0x01,0x00,0x00);SpiWriteRegister(0x30,0x34,0x01);SpiWriteRegister(0x30,0x35,0xc2); SpiWriteRegister(0x33,0x0b,0x4c);SpiWriteRegister(0x36,0x64,0x09);SpiWriteRegister(0x36,0x38,0x82); SpiWriteRegister(0x3d,0x08,0x00);SpiWriteRegister(0x36,0x40,0x03);SpiWriteRegister(0x36,0x28,0x07); SpiWriteRegister(0x32,0x05,0x93); //rnc SpiWriteRegister(0x36,0x20,0x42);SpiWriteRegister(0x36,0x23,0x06);SpiWriteRegister(0x36,0x27,0x02); SpiWriteRegister(0x36,0x21,0x28);SpiWriteRegister(0x36,0x3b,0x00);SpiWriteRegister(0x36,0x33,0x24); SpiWriteRegister(0x36,0x34,0xff); //fpn optimize SpiWriteRegister(0x34,0x16,0x10);SpiWriteRegister(0x3e,0x03,0x0b);SpiWriteRegister(0x3e,0x08,0x03); SpiWriteRegister(0x3e,0x09,0x20);SpiWriteRegister(0x3e,0x01,0x23); SpiWriteRegister(0x3e,0x14,0xb0);SpiWriteRegister(0x33,0x0b,0x40);SpiWriteRegister(0x3e,0x08,0x3f); SpiWriteRegister(0x36,0x3b,0x80);SpiWriteRegister(0x36,0x23,0x07);SpiWriteRegister(0x50,0x00,0x01); SpiWriteRegister(0x3e,0x01,0x00);SpiWriteRegister(0x3e,0x02,0x30);SpiWriteRegister(0x32,0x0c,0x05); SpiWriteRegister(0x32,0x0d,0x46);SpiWriteRegister(0x32,0x0e,0x02); SpiWriteRegister(0x32,0x0f,0x58);SpiWriteRegister(0x36,0x38,0x85);SpiWriteRegister(0x33,0x06,0x50); SpiWriteRegister(0x33,0x0b,0x68);SpiWriteRegister(0x33,0x08,0x10);SpiWriteRegister(0x3e,0x01,0x00); SpiWriteRegister(0x36,0x3b,0x00);SpiWriteRegister(0x36,0x63,0xf8);SpiWriteRegister(0x36,0x64,0x0a); SpiWriteRegister(0x36,0x33,0x27);SpiWriteRegister(0x30,0x3a,0x3a); SpiWriteRegister(0x30,0x3a,0x3a);SpiWriteRegister(0x30,0x3a,0x3a);SpiWriteRegister(0x30,0x3a,0x3a); SpiWriteRegister(0x36,0x3b,0x00);SpiWriteRegister(0x34,0x16,0x38);SpiWriteRegister(0x3e,0x08,0x23); SpiWriteRegister(0x3c,0x00,0x41); //FIFO RESET for mipi SpiWriteRegister(0x30,0x19,0x00); SpiWriteRegister(0x30,0x31,0x0a); // 10bit SpiWriteRegister(0x30,0x00,0x00);SpiWriteRegister(0x30,0x01,0x00);SpiWriteRegister(0x30,0x39,0x20); SpiWriteRegister(0x30,0x3a,0x31);SpiWriteRegister(0x30,0x3b,0x02);SpiWriteRegister(0x30,0x3c,0x08); SpiWriteRegister(0x4b,0x00,0xa2); //must SpiWriteRegister(0x30,0x22,0x19); //must SpiWriteRegister(0x30,0x3f,0x01); //must SpiWriteRegister(0x30,0x30,0x04); //must SpiWriteRegister(0x30,0x2b,0xa0); //must SpiWriteRegister(0x36,0x20,0x43);SpiWriteRegister(0x36,0x21,0x18);SpiWriteRegister(0x45,0x01,0xc0); SpiWriteRegister(0x45,0x02,0x16); //br recieve inv off SpiWriteRegister(0x36,0x23,0x07);SpiWriteRegister(0x50,0x00,0x01);SpiWriteRegister(0x36,0x20,0x43); SpiWriteRegister(0x33,0x00,0x30);SpiWriteRegister(0x3e,0x01,0x14);SpiWriteRegister(0x36,0x3b,0x80); SpiWriteRegister(0x36,0x64,0x0a);SpiWriteRegister(0x3e,0x08,0x23); SpiWriteRegister(0x34,0x16,0x00);SpiWriteRegister(0x36,0x33,0x20); SpiWriteRegister(0x36,0x33,0x23);SpiWriteRegister(0x32,0x11,0x0c);SpiWriteRegister(0x3e,0x0f,0x05); SpiWriteRegister(0x36,0x3b,0x08); //fpn SpiWriteRegister(0x36,0x33,0x22); //nvdd SpiWriteRegister(0x33,0x02,0x0c);//rst go low SpiWriteRegister(0x33,0x83,0x0a);// pbias en rise edge SpiWriteRegister(0x36,0x23,0x04); SpiWriteRegister(0x33,0x82,0x0f); //sa fall edge SpiWriteRegister(0x3e,0x0f,0x84); //gain SpiWriteRegister(0x3e,0x0e,0x03); //gain SpiWriteRegister(0x3e,0x08,0x27);SpiWriteRegister(0x3e,0x08,0x23);SpiWriteRegister(0x36,0x64,0x05); SpiWriteRegister(0x33,0x0b,0x68); SpiWriteRegister(0x36,0x38,0x84);SpiWriteRegister(0x5b,0x00,0x02);SpiWriteRegister(0x5b,0x01,0x03); SpiWriteRegister(0x5b,0x02,0x01);SpiWriteRegister(0x5b,0x03,0x01);SpiWriteRegister(0x36,0x3b,0x02); SpiWriteRegister(0x36,0x32,0x54);SpiWriteRegister(0x36,0x33,0x32);SpiWriteRegister(0x34,0x16,0x0e); SpiWriteRegister(0x36,0x64,0x0e);SpiWriteRegister(0x36,0x63,0x88);SpiWriteRegister(0x33,0x0b,0x50); SpiWriteRegister(0x36,0x22,0x06); //blksun SpiWriteRegister(0x36,0x30,0xb3);SpiWriteRegister(0x34,0x16,0x11);SpiWriteRegister(0x01,0x00,0x01);
7. USB2.0 PHY
Cypress公司的EZ-USB FX2是世界上第一款集成USB2.0的微处理器,它集成了USB2.0收发器、SIE(串行接口引擎)、增强的8051微控制器和可编程的外围接口。
8. USB Slave FIFO传输
当有一个与芯片相连主控只需要利用FX2做为一个USB2.0接口而实现与主机的高速通讯,而它本身又能够提供满足Slave FIFO要求的传输时序时,可采用Slave FIFO传输方式。
这种方式下,内嵌的8051固件只负责配置Slave FIFO相关的寄存器以及控制FX2何时工作在Slave FIFO模式下。
在Slave FIFO模式下,主控逻辑与FX2的连接如下图所示:
IFCLK: FX2 输出的时钟,可做为通讯的同步时钟
FLAGA/FLAGB/FLAGC/FLAGD: FX2 输出的FIFO状态信息,如满,空等
SLCS:FIFO的片选信号,外部逻辑控制,当 SLCS 输出高时,不可进行数据传输
SLOE:FIFO输出使能,外部逻辑控制,当 SLOE 无效时,数据线不输出有效数据
SLRD:FIFO 读信号,外部逻辑控制,同步读时,FIFO指针在SLRD 有效时的每个IFCLK的上升沿递增,异步读时, FIFO 读指针在 SLRD 的每个有效—无效的跳变沿时递增
SLWR:FIFO 写信号,外部逻辑控制,同步写时,在 SLWR 有效时的每个 IFCLK 的上升沿时数据被写入, FIFO指针递增,异步写时,在SLWR的每个有效—无效的跳变沿时数据被写入,FIFO写指针递增
PKTEND:包结束信号,外部逻辑控制,在正常情况下,外部逻辑向 FX2 的 FIFO 中写数,当写入FIFO端点的字节数等于FX2固件设定的包大小时,数据将自动被打成一包进行传输,但有时外部逻辑可能需要传输一个字节数小于 FX2 固件设定的包大小的包,这时它只需在写入一定数目的字节后,声明此信号,此时 FX2 硬件不管外部逻辑写入了多少字节,都自动将之打成一包进行传输
FD[15:0]:数据线;
FIFOADR[1:0]:选择四个 FIFO 端点的地址线,外部逻辑控制
9. 上位机DEMO软件
在Windows下可以使用VC++开发应用软件,在设计68013上位机程序的过程中,需要用到CPYRESS官方提供的API函数和驱动程序。
开发包地址如下:
http://www.cypress.com/documentation/software-and-drivers/suiteusb-34-usb-development-tools-visual-studio
支持的操作系统:
Windows 2000(w2K)
Windows XP (wxp)
Windows Vista (wlh)
Windows 7
支持的CPU类型:
x86(32bit-i386)
x64(64bit-amd64)
10. 最终结果
下图为用三星手机拍摄的风扇的图片,已经完全看不到扇叶的形状。
下图为设计的板卡拍摄的图片,从图中可以看出扇叶的形状,尽管风扇在高速旋转。
本文出自 “shugenyin的博客” 博客,请务必保留此出处http://shugenyin.blog.51cto.com/4259554/1898160
FPGA设计——CMOS摄像与USB2.0显示(LVDS版)
原文:http://shugenyin.blog.51cto.com/4259554/1898160