0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

EMIO方式模擬SCCB時(shí)序進(jìn)行讀寫操作詳解

Hx ? 作者:工程師陳翠 ? 2018-06-29 10:32 ? 次閱讀

一、SCCB介紹

SCCB是OmniVision Serial Camera Control Bus的簡稱,即OV公司的串行攝像機(jī)控制總線。OV公司定義的SCCB是一個(gè)3線結(jié)構(gòu),但是,為了縮減Sensorpin封裝,SCCB大多采用2線方式。

開始傳輸數(shù)據(jù)

EMIO方式模擬SCCB時(shí)序進(jìn)行讀寫操作詳解

結(jié)束數(shù)據(jù)傳輸

EMIO方式模擬SCCB時(shí)序進(jìn)行讀寫操作詳解

傳輸規(guī)則

一個(gè)基本傳輸單元稱作一個(gè)相

一個(gè)相包含總共9比特,前8比特為數(shù)據(jù),第9比特為 Don‘t-Care bit 不關(guān)心比特,該第9比特的數(shù)據(jù)取決于

傳輸任務(wù)是讀還是寫。一個(gè)傳輸任務(wù)的最大相個(gè)數(shù)是3

EMIO方式模擬SCCB時(shí)序進(jìn)行讀寫操作詳解

3相寫傳輸規(guī)則

提供些傳輸,主機(jī)能將1byte數(shù)據(jù)寫至指定從機(jī)

EMIO方式模擬SCCB時(shí)序進(jìn)行讀寫操作詳解

ID Address表示指定從機(jī)的地址

Sub-address表示從機(jī)的寄存器

后面是數(shù)據(jù),1字節(jié)數(shù)據(jù)

3個(gè)相為后一位都是Don’t-Care bits

2相寫傳輸規(guī)則

EMIO方式模擬SCCB時(shí)序進(jìn)行讀寫操作詳解

2相寫傳送是在2相讀傳送前的,它的目的是指明主機(jī)要從哪個(gè)從機(jī)的哪個(gè)寄存器讀數(shù)據(jù)。

2相讀傳輸規(guī)則

EMIO方式模擬SCCB時(shí)序進(jìn)行讀寫操作詳解

在2相讀前面必須有2相寫或者3相寫,否則2相讀沒有辦法讀出哪個(gè)寄存器發(fā)的數(shù)據(jù),主機(jī)必須將NA bit置為1(否則OV攝像頭會把SIOD拉低)

“X”表示Don‘t-Care bit。意思是Master可以不關(guān)注此bit。從OV給的手冊來看,Slave也可以驅(qū)動此bit為低,然后Master來確認(rèn)響應(yīng)。當(dāng)然,Master也可以不關(guān)注。在SCCB手冊中,這部分說的比較含糊,所以,簡單來說,在SCCB中,Master不關(guān)注是否傳輸數(shù)據(jù)有錯誤發(fā)生。說實(shí)話,為了所做的設(shè)計(jì)可靠,還是應(yīng)該關(guān)注的。

二、EMIO介紹

zynq的GPIO,分為兩種,MIO(multiuse I/O)和EMIO(extendable multiuse I/O)

EMIO方式模擬SCCB時(shí)序進(jìn)行讀寫操作詳解

MIO分配在bank0和bank1直接與PS部分相連,EMIO分配在bank2和接和PL部分相連。除了bank1是22-bit之外,其他的bank都是32-bit。所以MIO有53個(gè)引腳可供我們使用,而EMIO有64個(gè)引腳可供我們使用。

使用EMIO的好處就,當(dāng)MIO不夠用時(shí),PS可以通過驅(qū)動EMIO控制PL部分的引腳,接下來就來詳細(xì)介紹下EMIO的使用。

EMIO的使用和MIO的使用其實(shí)是非常相似的。區(qū)別在于,EMIO的使用相當(dāng)于,是一個(gè)PS + PL的結(jié)合使用的例子。所以,EMIO需要分配引腳,以及編譯綜合生成bit文件。

三、例子

1、新建vivado 工程,create一個(gè)block design,添加zynq PS核

EMIO方式模擬SCCB時(shí)序進(jìn)行讀寫操作詳解

2、運(yùn)行自動連接

EMIO方式模擬SCCB時(shí)序進(jìn)行讀寫操作詳解

3、雙擊PS IP進(jìn)行配置,增加三個(gè)EMIO,其中兩個(gè)是SCCB的數(shù)據(jù)和時(shí)鐘,另外一個(gè)拿來做復(fù)位

EMIO方式模擬SCCB時(shí)序進(jìn)行讀寫操作詳解

4、把新增的EMIO連接出來,并把時(shí)鐘接好

5、增加一個(gè)clock IP,修改輸出頻率為24Mhz,把輸出管腳接出

EMIO方式模擬SCCB時(shí)序進(jìn)行讀寫操作詳解

5、create HDL wrapper,生產(chǎn)HDL頂層文件,雙擊打開,可以看到剛才接出來的EMIO管腳名為gpio_0_tri_io

EMIO方式模擬SCCB時(shí)序進(jìn)行讀寫操作詳解

6、創(chuàng)建約束文件,我的攝像頭的SIOD接到了W8,SIOC接到了V8,RESET接到AB11,XCLK接到W11

EMIO方式模擬SCCB時(shí)序進(jìn)行讀寫操作詳解

7、綜合,生成bit文件,導(dǎo)出hardware并啟動SDK,創(chuàng)建項(xiàng)目,添加如下代碼

EMIO_init.h

#ifndef EMIO_INIT_H_

#define EMIO_INIT_H_

#include“xgpiops.h”

int EMIO_SCCB_init(void);

#define SIOD_PIN 54

#define SIOC_PIN 55

#define RESET_PIN 56

#define DIRECTION_INPUT 0

#define DIRECTION_OUTPUT 1

void CLOCK_HIGH(void);

void CLOCK_LOW(void);

void DATA_HIGH(void);

void DATA_LOW(void);

void DATA_INPUT(void);

void DATA_OUTPUT(void);

int GET_DATA(void);

void SCCB_reset(void);

#endif /* EMIO_INIT_H_ */

EMIO_init.c

#include “xgpiops.h”

#include “EMIO_init.h”

static XGpioPs psGpioInstancePtr;

int EMIO_SCCB_init(void)

{

XGpioPs_Config* GpioConfigPtr;

int xStatus;

GpioConfigPtr = XGpioPs_LookupConfig(XPAR_PS7_GPIO_0_DEVICE_ID);

if(GpioConfigPtr == NULL)

return XST_FAILURE;

xStatus = XGpioPs_CfgInitialize(&psGpioInstancePtr,GpioConfigPtr,GpioConfigPtr-》BaseAddr);

if(XST_SUCCESS != xStatus)

print(“EMIO INIT FAILED \n\r”);

XGpioPs_SetDirectionPin(&psGpioInstancePtr, SIOC_PIN,DIRECTION_OUTPUT);

XGpioPs_SetDirectionPin(&psGpioInstancePtr, SIOD_PIN,DIRECTION_OUTPUT);

XGpioPs_SetDirectionPin(&psGpioInstancePtr, RESET_PIN,DIRECTION_OUTPUT);

XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, SIOC_PIN,1);

XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, SIOD_PIN,1);

XGpioPs_SetOutputEnablePin(&psGpioInstancePtr, RESET_PIN,1);//

return xStatus;

}

void SCCB_reset(void)

{

XGpioPs_WritePin(&psGpioInstancePtr,RESET_PIN, 0);

usleep(50*1000);

XGpioPs_WritePin(&psGpioInstancePtr,RESET_PIN, 1);

}

void CLOCK_HIGH(void)

{

XGpioPs_WritePin(&psGpioInstancePtr,SIOC_PIN, 1);

}

void CLOCK_LOW(void)

{

XGpioPs_WritePin(&psGpioInstancePtr,SIOC_PIN, 0);

}

int GET_DATA(void)

{

return XGpioPs_ReadPin(&psGpioInstancePtr,SIOD_PIN);

}

void DATA_INPUT(void)

{

XGpioPs_SetDirectionPin(&psGpioInstancePtr, SIOD_PIN,DIRECTION_INPUT);//

}

void DATA_OUTPUT(void)

{

XGpioPs_SetDirectionPin(&psGpioInstancePtr, SIOD_PIN,DIRECTION_OUTPUT);//

}

void DATA_HIGH(void)

{

XGpioPs_WritePin(&psGpioInstancePtr,SIOD_PIN, 1);

}

void DATA_LOW(void)

{

XGpioPs_WritePin(&psGpioInstancePtr,SIOD_PIN,0);

}

SCCB_ctrl.h

#ifndef SCCB_CTRL_H_

#define SCCB_CTRL_H_

void sccb_start(void);

void sccb_end(void);

void sccb_sendbyte( unsigned char value );

void sccb_senddata(unsigned char subaddr,unsigned char value);

int sccb_readdata(unsigned char addr, unsigned char *value);

#endif /* SCCB_CTRL_H_ */

SCCB_ctrl.c

#include “sleep.h”

#include “EMIO_init.h”

#define OV7670_WRITE_ADDR 0x42

#define OV7670_READ_ADDR 0x43

#define SCCB_DELAY usleep(10)

void sccb_start(void)

{

CLOCK_HIGH();

DATA_HIGH();

SCCB_DELAY;

DATA_LOW();

SCCB_DELAY;

CLOCK_LOW();

SCCB_DELAY;

}

void sccb_end(void)

{

DATA_LOW();

SCCB_DELAY;

CLOCK_HIGH();

SCCB_DELAY;

DATA_HIGH();

SCCB_DELAY;

}

int sccb_sendbyte( unsigned char value )

{

unsigned char tmp = value;

unsigned char i=0,ack;

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

{

if(tmp & 0x80 )

DATA_HIGH();

else

DATA_LOW();

SCCB_DELAY;

CLOCK_HIGH();

SCCB_DELAY;

CLOCK_LOW();

SCCB_DELAY;

tmp《《=1;

}

DATA_HIGH();

DATA_INPUT();

SCCB_DELAY;

CLOCK_HIGH();

ack = GET_DATA();

SCCB_DELAY;

CLOCK_LOW();

SCCB_DELAY;

DATA_OUTPUT();

if(ack==1)

{

return -1;

}

return 0;

}

unsigned char sccb_readbyte( unsigned char addr)

{

unsigned char i=0,data=0;

DATA_HIGH();

DATA_INPUT();

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

{

CLOCK_HIGH();

SCCB_DELAY;

data 《《= 1;

if(GET_DATA())

data |= 1;

SCCB_DELAY;

CLOCK_LOW();

SCCB_DELAY;

}

DATA_OUTPUT();

DATA_HIGH();

SCCB_DELAY;

CLOCK_HIGH();

SCCB_DELAY;

CLOCK_LOW();

SCCB_DELAY;

DATA_HIGH();

return data;

}

int sccb_readdata(unsigned char addr, unsigned char *value)

{

// 兩相寫

sccb_start();

if(sccb_sendbyte(OV7670_WRITE_ADDR) != 0)

{

sccb_end();

return -1;

}

if(sccb_sendbyte(addr) != 0)

{

sccb_end();

return -1;

}

sccb_end();

SCCB_DELAY;

// 兩相讀

sccb_start();

if(sccb_sendbyte(OV7670_READ_ADDR) != 0)

{

sccb_end();

return -1;

}

*value = sccb_readbyte(addr);

sccb_end();

return 0;

}

void sccb_senddata(unsigned char addr,unsigned char value)

{

sccb_start();

sccb_sendbyte(OV7670_WRITE_ADDR);

sccb_sendbyte(addr);

sccb_sendbyte(value);

sccb_end();

}

修改main函數(shù),讀取PID和VER寄存器,驗(yàn)證是否正確,實(shí)際上我讀取到的VER是0X73

int main()

{

unsigned char data;

init_platform();

print(“Hello World\n\r”);

EMIO_SCCB_init();

SCCB_reset();

usleep(500*1000);

while(1)

{

//讀取PID

data = 0;

if(sccb_readdata(0x0A,&data) != 0)

{

print(“error\n\r”);

}

else

{

if(data != 0x76)

print(“error\n\r”);

}

//讀取VER

data = 0;

if(sccb_readdata(0x0B,&data) != 0)

{

print(“error\n\r”);

}

else

{

if(data != 0x73)

print(“error\n\r”);

}

}

cleanup_platform();

return 0;

}

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報(bào)投訴
  • SCCB
    +關(guān)注

    關(guān)注

    0

    文章

    11

    瀏覽量

    11304
  • Vivado
    +關(guān)注

    關(guān)注

    19

    文章

    797

    瀏覽量

    65855
收藏 人收藏

    評論

    相關(guān)推薦

    IIC總線協(xié)議與SCCB協(xié)議的區(qū)別

    總線支持連續(xù)寫,故寫完地址之后不需要再發(fā)送起始信號;這也正是與SCCB最大的不同之處;6、無論讀寫,應(yīng)答位總線都需要釋放,至于如果不釋放會不會對時(shí)序產(chǎn)生破壞影響還不清楚,有待驗(yàn)證; (摘自百度)總結(jié)
    發(fā)表于 08-07 12:43

    ov7725的使用與OV7725 SCCB的接口時(shí)序

    ov7725介紹ov7725(OmniVsion_OV7725)是由OV(豪威科技)生產(chǎn)的一款CMOS的攝像頭,已經(jīng)被中國財(cái)團(tuán)收購。OV7725 SCCB的接口時(shí)序(OmniVision
    發(fā)表于 07-28 08:07

    如何對SCCB協(xié)議進(jìn)行讀寫操作

    ov7725是什么?ov7725攝像頭是由哪些部分組成的?如何對SCCB協(xié)議進(jìn)行讀寫操作
    發(fā)表于 10-20 07:09

    軟件模擬SPI時(shí)序實(shí)現(xiàn)25Q64讀寫操作的方法

    軟件模擬SPI時(shí)序實(shí)現(xiàn)25Q64讀寫操作單片機(jī)采用SPI/IIC通訊協(xié)議訪問外圍電子模塊如:顯示屏、EEPROM、FLASH、各種電子傳感器等等越來越多,掌握SPI/IIC通訊協(xié)議訪問
    發(fā)表于 11-30 07:35

    如何使用SPI?如何對SPI的操作時(shí)序進(jìn)行讀寫

    nRF24L01+ 2.4GHz無線收發(fā)器的主要特性有哪些?如何使用SPI?如何對SPI的操作時(shí)序進(jìn)行讀寫呢?
    發(fā)表于 12-20 06:32

    軟件模擬SPI時(shí)序是怎樣去實(shí)現(xiàn)25Q64讀寫操作

    軟件模擬SPI時(shí)序實(shí)現(xiàn)25Q64讀寫操作單片機(jī)采用SPI/IIC通訊協(xié)議訪問外圍電子模塊如:顯示屏、EEPROM、FLASH、各種電子傳感器等等越來越多,掌握SPI/IIC通訊協(xié)議訪問
    發(fā)表于 02-17 06:07

    SRAM的簡單的讀寫操作教程

    SRAM的簡單的讀寫操作教程 SRAM的讀寫時(shí)序比較簡單,作為異步時(shí)序設(shè)備,SRAM對于時(shí)鐘同步的要求不高,可以在低速下運(yùn)行,下面就介紹S
    發(fā)表于 02-08 16:52 ?140次下載

    SCCB接口時(shí)序

    SCCB的總線時(shí)序與I2C基本相同,它的響應(yīng)信號ACK被稱為一個(gè)傳輸單元的第9位,分為Dont care和NA。Dont care位由從機(jī)產(chǎn)生;NA位由主機(jī)產(chǎn)生,由于SCCB不支持多字節(jié)的讀寫
    發(fā)表于 03-26 16:00 ?168次下載
    <b class='flag-5'>SCCB</b>接口<b class='flag-5'>時(shí)序</b>

    DS18B20讀寫操作程序詳解

    DS18B20的初始化、讀寫操作以及程序詳解
    發(fā)表于 11-06 18:04 ?2.6w次閱讀

    EMIO方式模擬I2C時(shí)序對ADV7511進(jìn)行讀寫

    創(chuàng)建硬件工程,很簡單,PS接出兩個(gè)EMIO和一個(gè)74.25M時(shí)鐘
    發(fā)表于 11-18 13:50 ?3871次閱讀

    SCCB的工作模式及示例代碼資料合集免費(fèi)下載

    如果對OV7620的默認(rèn)工作模式不滿意,就可寫SCCB。 對于SCCB操作,首先必需使能IICB,這個(gè)在OV7620上需要跳線解決。網(wǎng)上很多人用普通IO口模擬
    發(fā)表于 05-13 08:00 ?3次下載
    <b class='flag-5'>SCCB</b>的工作模式及示例代碼資料合集免費(fèi)下載

    總線的操作時(shí)序操作方式詳解

    操作時(shí)序(timing):各信號有效的先后順序及配合關(guān)系
    的頭像 發(fā)表于 06-24 16:21 ?1.1w次閱讀
    總線的<b class='flag-5'>操作</b><b class='flag-5'>時(shí)序</b>和<b class='flag-5'>操作</b><b class='flag-5'>方式</b><b class='flag-5'>詳解</b>

    STM32入門開發(fā): 介紹IIC總線、讀寫AT24C02(EEPROM)(采用模擬時(shí)序)

    時(shí)序的,本文采用的是模擬時(shí)序,下篇文章就介紹配置STM32的IIC硬件時(shí)序讀寫AT24C02和AT24C08。
    發(fā)表于 11-25 20:06 ?39次下載
    STM32入門開發(fā): 介紹IIC總線、<b class='flag-5'>讀寫</b>AT24C02(EEPROM)(采用<b class='flag-5'>模擬</b><b class='flag-5'>時(shí)序</b>)

    Python對txt進(jìn)行讀寫操作

    Python對txt進(jìn)行讀寫操作
    的頭像 發(fā)表于 01-11 15:16 ?740次閱讀

    SCCB IIC接口設(shè)計(jì)

    SCCB協(xié)議是類似于IIC協(xié)議,它常用于OV系列攝像頭配置接口中。下圖為sio_c和sio_d的時(shí)序圖,具體的時(shí)序協(xié)議請看《SCCB接口時(shí)序
    的頭像 發(fā)表于 11-06 10:42 ?416次閱讀
    <b class='flag-5'>SCCB</b> IIC接口設(shè)計(jì)