【SCCB接口协议简介(适用于OV系列摄像头)】

SCCB总线简介

SCCB协议与IIC协议十分相似,不过IIC是PHILIPS的专利,所以OmnVision在IIC的基础上做了点小改动。SCCB最主要是阉割了IIC的连续读写的功能,即每读写完一个字节就主机必须发送一个NA信号。

SCCB简介
  SCCB是欧姆尼图像技术公司(OmniVision)开发的一种总线,应用于OV系列图像传感器上,所以一般使用OV的图像传感器都离不开SCCB总线协议。
 可以通俗地讲SCCB有两种工作模式,一主多从,一主一从模式。
一主机多从机 也即3线操作:(通过控制使能端SCCB_E控制选中的从机)
在这里插入图片描述
一主一从 也即2线操作:(默认SCCB_E被拉低)

在这里插入图片描述

SCCB时序
SCCB_E(相当于片选信号)为低电平时传输有效,SIO_C为高电平时,SIO_D读取数据(SIO_C为低电平时SIO_D改变)
在这里插入图片描述
开始信号
在这里插入图片描述

开始传输开始于SCCB_E下降沿。在SCCB_E下降沿前,主机必须将SIO_D置1,这样可以避免读取传送之前产生的未知总线状态。
在SCCB_E下降沿之前,SIO_D必须有tPRC时长的高电平,tPRC至少要15ns
tPRA是SCCB_E下降沿之后SIO_D保持高电平的时间,tPRA至少要1.25us
注意:此图为3线图时序
2线操作的代码实现

void SCCB_Start(void)
{
	SCCB_SDA_OUT();		//数据线为输出模式
	SCCB_SDA=1;			//数据线高电平
	SCCB_SCL=1;			//在时钟高的时候数据线由高至低
	delay_us(50);
	SCCB_SDA=0;        //在时钟高的时候数据线由高至低
	delay_us(50);
	SCCB_SCL=0;			//数据线恢复低电平,单操作函数必要
	delay_us(50);
}

结束信号
在这里插入图片描述
SCCB_E上升沿时表示结束传输,两个时间规定为tPSA和tPSC
tPSC为SCCB_E上升沿之后SIO_D维持高电平的时间,tPSC至少15ns
tPSA为SCCB_E之前SIO_D高电平的时间,tPSA至少0ns
注意:此图为3线图时序
2线操作的代码实现

void SCCB_Stop(void)
{
	SCCB_SDA_OUT();		//数据线为输出模式
	SCCB_SDA=0;			//数据线低电平
	delay_us(50);
	SCCB_SCL=1;
	delay_us(50);
	SCCB_SDA=1;
	delay_us(50);
}

产生NA时序(用于读数据)
在这里插入图片描述

//SCCB_D先拉高,再把SCCB_C拉高,后把SCCB_C拉低,最后把SCCB_D拉低
void SCCB_NA(void)
{
	SCCB_SDA_OUT();
	delay_us(50);
	SCCB_SDA=1;	
	SCCB_SCL=1;	
	delay_us(50);
	SCCB_SCL=0;	
	delay_us(50);
	SCCB_SDA=0;	
	delay_us(50);
}

读时序
在这里插入图片描述

u8 SCCB_RD_Byte(void)
{
	u8 temp=0,j;    
	SCCB_SDA_IN();		//设置SDA为输入  
	for(j=8;j>0;j--) 	//循环8次接收数据
	{		     	  
		delay_us(50);
		SCCB_SCL=1;
		temp=temp<<1;
		if(SCCB_READ_SDA)temp++;   
		delay_us(50);
		SCCB_SCL=0;
	}	
	SCCB_SDA_OUT();		//设置SDA为输出    
	return temp;
} 

写时序
在这里插入图片描述

u8 SCCB_WR_Byte(u8 dat)
{
	u8 j,res;	 
	for(j=0;j<8;j++) //循环8次发送数据
	{
		if(dat&0x80)SCCB_SDA=1;	
		else SCCB_SDA=0;
		dat<<=1;
		delay_us(50);
		SCCB_SCL=1;	
		delay_us(50);
		SCCB_SCL=0;		   
	}			 
	SCCB_SDA_IN();		//设置SDA为输入 
	delay_us(50);
	SCCB_SCL=1;			//接收第九位,以判断是否发送成功
	delay_us(50);
	if(SCCB_READ_SDA)res=1;  //SDA=1发送失败,返回1
	else res=0;         //SDA=0发送成功,返回0
	SCCB_SCL=0;		 
	SCCB_SDA_OUT();		//设置SDA为输出    
	return res;  
}	

传输规则

一个基本传输单元称作一个
一个相包含总共9比特,前8比特为数据,第9比特为 Don’t-Care bit (不关心比特),该第9比特的数据取决于传输任务是读还是写如果是写操作则don’t care,如果为读操作为NA。一个传输任务的最大相个数是3。
总结如下:
每一个单元组成:8位数据+don’t care/NA
如果是主机发送数据,即进行写操作,第九位就为don’t care(不关心比特)
如果是从机发送数据,即为读操作,第九位就为NA.

相1:主机向从机发送从机的ID号,SCCB协议支持一个主机和多个从机,因此这一个相目的是区分不同的从机,但如果我们只连接了一个从机时,也必须执行这样一个流程。实际上ID Address有8bit,其中bit7-bit1为从机的ID号,大小为0-127,一共能区分128个从机。OV2640的ID号为0x60。而bit0是用来区分对从机是写数据还是读数据,bit0=0代表写数据,bit0=1代表读数据,由于我们要向从机写数据,因此bit0应为0(0x60=01100000写入数据)。而相1中紧跟在ID Address这8位数据后的第九位是一个Don’t care bit(图中打X的位)。对于OV2640来说,从机在接收到主机送来的8bit数据后,将在SCL=1的期间,在SDA引脚输出低电平。在这期间,主机就可以读取SDA上的电平并进行判断,如果读取到低电平,表示从机已经顺利接收到了相1中的前8bit数据。说明数据传输成功,否则说明传输失败。

相2:主机向从机发送将要写入数据的寄存器的编号,寄存器的编号在OV传感器的数据手册上都能找到。寄存器的编号是一个8bit的数据。同样地,相2的第9bit也是一个Don’t care bit(图中打X的位),对该位的说明与相1相同
相3:前面两个相指定了数据传输的从机ID以及要写入数据的寄存器的编号,这时候在第三个相就可以向前面指定的寄存器写入数据了。bit7-bit0是我们希望写入寄存器的数据。而第9bit也是一个Don’t care bit(图中打X的位),对该位的说明与相1相同。
虽然每个相写入的数据不同,但其时序都是相同的,并且第九bit都是Don’t care bit。因此可以把每个相的写入编写成一个函数,如下:

u8 SCCB_WR_Byte(u8 dat)//写1个相
{
	u8 j,res;	 
	for(j=0;j<8;j++) //循环发送bit7-bit0
	{
		if(dat&0x80)SCCB_SDA=1;	
		else SCCB_SDA=0;
		dat<<=1;
		delay_us(50);
		SCCB_SCL=1;	
		delay_us(50);
		SCCB_SCL=0;		   
	}			 
	SCCB_SDA_IN();		//设置SDA为输入
	delay_us(50);
	SCCB_SCL=1;			//将SCL置1,此时如果数据已被从机接收,从机将把SDA置0
	delay_us(50);
	if(SCCB_READ_SDA)res=1;  //SDA置1,说明从机没有成功接收数据
	else res=0;         //发送成功
	SCCB_SCL=0;		 
	SCCB_SDA_OUT();		//设置SDA为输出,为下一个相的输出作准备  
	return res;  
}	

写寄存器值
在这里插入图片描述
写寄存器分三个阶段:写器件地址,写寄存器地址,写数据(以OV2640为例则)
在这里插入图片描述
表12和表13提供了OV2640中包含的设备控制寄存器的列表和描述。对于所有寄存器,启用/禁用位,启用=1和禁用=0。设备从地址是60用于写,61用于读。

u8 SCCB_WR_Reg(u8 reg,u8 data)
{
	u8 res=0;
	SCCB_Start(); 					//启动SCCB传输
	if(SCCB_WR_Byte(SCCB_ID))res=1;	//写器件ID	  
	delay_us(100);
  	if(SCCB_WR_Byte(reg))res=1;		//写寄存器地址	  
	delay_us(100);
  	if(SCCB_WR_Byte(data))res=1; 	//写数据	 
  	SCCB_Stop();	  
  	return	res;
}	

读寄存器值

读寄存器分两次两个阶段

第一个阶段:写器件地址,写要读的寄存器地址
第二个阶段:写器件地址+1(表示读命令),读取数据,最后在发送NA信号

u8 SCCB_RD_Reg(u8 reg)
{
	u8 val=0;
	SCCB_Start();				//启动SCCB传输
	SCCB_WR_Byte(SCCB_ID);		//写器件ID
	delay_us(100);
	SCCB_WR_Byte(reg);			//写寄存器地址
	delay_us(100);
	SCCB_Stop();
	delay_us(100);
	SCCB_Start();				//设置完寄存器后才是读
	SCCB_WR_Byte(SCCB_ID|0x01);	//发送读命令
	delay_us(100);
	val=SCCB_RD_Byte();			//读取命令
	SCCB_NA();					//发送NA信号
	SCCB_Stop();
	return(val);
}

  • 21
    点赞
  • 130
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值