您的位置 首页 FPGA

s3c2440的摄像接口摄影使用

s3c2440提供了一个摄像接口,使开发人员很容易地实现摄像、照相等功能。摄像接口包括8位来自摄像头的输入数据信号,一个输出主时钟信

s3c2440 供给了一个摄像接口,使开发人员很容易地完成摄像、照相等功用。摄像接口包含 8 位来自摄像头的输入数据信号,一个输出主时钟信号,三个来自摄像头的输入同步时钟信号和一个输出复位信号。摄像接口的主时钟信号由 USB PLL 发生,它的频率为 96MHz ,再经过分频处理后输出给摄像头,摄像头再依据该时钟信号发生三个同步时钟信号(像素时钟、帧同步时钟和行同步时钟),反过来再输入回 s3c2440 。

s3c2440 只是供给了一个摄像接口,因而要完成其功用,还需求摄像头。在这里,咱们运用 OV9650 。 OV9650 内部有很多的寄存器需求装备,这就需求别的的数据接口。 OV9650 的数据接口称为 SCCB (串行摄像操控总线),它由两条数据线组成:一个是用于传输时钟信号的 SIO_C ,另一个是用于传输数据信号的 SIO_D 。 SCCB 的传输协议与 IIC 的极端类似,只不过 IIC 在每传输完一个字节后,接纳数据的一方要发送一位的承认数据,而 SCCB 一非必须传输 9 位数据,前 8 位为有用数据,而第 9 位数据在写周期中是 Don’t-Care 位(即不用关怀位),在读周期中是 NA 位。 SCCB 界说数据传输的根本单元为相( phase ),即一个相传输一个字节数据。 SCCB 只包含三种传输周期,即 3 相写传输周期(三个相顺次为设备从地址,内存地址,所写数据), 2 相写传输周期(两个相顺次为设备从地址,内存地址)和 2 相读传输周期(两个相顺次为设备从地址,所读数据)。当需求写操作时,使用 3 相写传输周期,当需求读操作时,顺次使用 2 相写传输周期和 2 相读传输周期。因而 SCCB 一次只能读或写一个字节。下面咱们就用 s3c2440 的 IIC 总线接口别离与 OV9650 的 SIO_C 和 SIO_D 相连接来完成 SCCB 的功用。详细的读、写函数为:

// 装备 IIC 接口

rGPEUP = 0xc000;// 上拉无效

rGPECON = 0xa0000000;//GPE15 : IICSDA , GPE14 : IICSCL

//IIC 中止

void __irq IicISR(void)

{

rSRCPND |= 0x1<<27;

rINTPND |= 0x1<<27;

flag = 0;

}

// 写操作

// 输入参数别离为要写入的内存地址和数据

void Wr_SCCB(unsigned char wordAddr, unsigned char data)

{

//3 相写传输周期

// 写 OV9650 设备从地址字节

flag =1;

rIICDS =0x60;//OV9650 设备从地址为 0x60

rIICSTAT = 0xf0;

rIICCON &= ~0x10;

while(flag == 1)

delay(100);

// 写 OV9650 内存地址字节

flag = 1;

rIICDS = wordAddr;

rIICCON &= ~0x10;

while(flag)

delay(100);

// 写详细的数据字节

flag = 1;

rIICDS = data;

rIICCON &= ~0x10;

while(flag)

delay(100);

rIICSTAT = 0xd0;// 中止位

rIICCON = 0xe3;// 为下一次数据传输做准备

delay(100);

}

// 读操作

// 参数别离为要读取的内存地址和数据

void Rd_SCCB (unsigned char wordAddr,unsigned char *data)

{

unsigned char temp;

//2 相写传输周期

// 写入 OV9650 设备从地址字节

flag =1;

rIICDS = 0x60;

rIICSTAT = 0xf0;

rIICCON &= ~0x10;

while(flag)

delay(100);

// 写入内存地址字节

flag = 1;

rIICDS = wordAddr;

rIICCON &= ~0x10;

while(flag)

delay(100);

rIICSTAT = 0xd0;// 中止位

rIICCON = 0xe3;// 为下一次数据传输做准备

delay(100);

//2 相读传输周期

// 写入 OV9650 设备从地址字节

flag = 1;

rIICDS = 0x60;

rIICSTAT = 0xb0;

rIICCON &= ~0x10;

while (flag)

delay(100);

// 读取一个无用字节

flag = 1;

temp = rIICDS;

rIICCON &= ~((1<<7)|(1<<4));

while(flag)

delay(100);

// 读取数据

flag = 1;

*data= rIICDS;

rIICCON &= ~((1<<7)|(1<<4));

while(flag)

delay(100);

rIICSTAT = 0x90;// 中止位

rIICCON = 0xe3;// 为下一次传输做准备

delay(100);

}

当然咱们也可以用两个通用 IO 口来模仿 SCCB 总线,下面咱们给出详细的程序,其间 GPE15 为 SIO_D , GPE14 为 SIO_C 。

#define CLOCK_LOW()(rGPEDAT&=(~(1<<14)))// 时钟信号低

#define CLOCK_HIGH()(rGPEDAT|=(1<<14))// 时钟信号高

#define DATA_LOW()(rGPEDAT&=(~(1<<15)))// 数据信号低

#define DATA_HIGH()(rGPEDAT|=(1<<15))// 数据信号高

// 装备 IO

rGPEUP = 0xc000;// 上拉无效

rGPECON = 5<<28;//GPE15 为 SIO_D , GPE14 为 SIO_C ,都为输出

void delay(int a)

{

int k;

for(k=0;k

;

}

// 发动 SCCB

void __inline SCCB_start(void)

{

CLOCK_HIGH();

DATA_HIGH();

delay(10);

DATA_LOW();

delay(10);

CLOCK_LOW();

delay(10);

}

// 完毕 SCCB

void __inline SCCB_end(void)

{

DATA_LOW();

delay(10);

CLOCK_HIGH();

delay(10);

DATA_HIGH();

delay(10);

}

//SCCB 发送一个字节

void __inline SCCB_sendbyte(unsigned char data)

{

int i=0;

// 并行数据转串行输出,串行数据输出的次序为先高位再低位

for(i=0;i<8;i++)

{

if(data & 0x80)

DATA_HIGH();

else

DATA_LOW();

delay(10);

CLOCK_HIGH();

delay(10);

CLOCK_LOW();

delay(10);

DATA_LOW();

delay(10);

data <<= 1;

}

// 第 9 位, Don’t Care

DATA_HIGH();

delay(10);

CLOCK_HIGH();

delay(10);

CLOCK_LOW();

delay(10);

}

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/fangan/fpga/257985.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部