协议——SCCB与IIC的区别
SCCB(Serial Camera Control Bus,串行摄像头控制总线)是由OV(OmniVision的简称)公司定义和发展的三线式串行总线,该总线控制着摄像头大部分的功能,包括图像数据格式、分辨率以及图像处理参数等。结构框图如下所示:
OV公司为了减少传感器引脚的封装,现在SCCB总线大多采用两线式接口总线。OV7725使用的是两线式接口总线,该接口总线包括SIO_C串行时钟输入线和SIO_D串行双向数据线,分别相当于IIC协议的SCL信号线和SDA信号线。SIO_C的最小时间为10us,即最大频率为100K。一般来说,100K-400K之间都可以。
由此可见,SCCB就是改编版的IIC,完全可以按照IIC来理解,下面仔细讲解SCCB的时序以及和IIC的不同之处。
一、SCCB起始和结束(与IIC完全一致)
起始:SIO_C为高时,SIO_D由高拉低。
停止:SIO_C为高时,SIO_D由低拉高。
二、SCCB写(与IIC完全一致)
ID Address(W)里面就已经包括进了IIC中的“读写控制位”,所以没有额外写出。
即:start + phase_1 + phase_2 + phase_3 + stop
“X”的意思是“don't care”,该位是由从机发出应答信号来响应主机表示当前ID Address、Sub-address和Write Data是否传输完成,但是从机有可能不发出应答信号,因此主机(此处指FPGA)可不用判断此处是否有应答,直接默认当前传输完成即可。“X”即IIC中的ACK应答位。
三、SCCB读
数据手册中的SCCB读只写了上图的Phase3和Phase4,实际上它是和Phase1和Phase2联系在一起的。SCCB不支持连续读,Phase4的主机应答位必须为NA(no ack),即为1,所以SCCB读其实就专指单次读,和IIC单次读几乎一样。
区别就一点:在IIC读传输协议中,写完寄存器地址后会有restart即重复开始的操作;而SCCB读传输协议中没有重复开始的概念,在写完寄存器地址后,需发起总线停止信号。
即:start_1 + phase_1 + phase_2 + stop_1 + start_2 + phase_3 + phase_4 + stop_2
四、SCCB和IIC的区别
1.SCCB的应答位称为X,表示“don't care”,而IIC应答位称为ACK。
2.SCCB只能单次读,而IIC除了单次读还支持连续读。
3.SCCB读操作中间有stop,而IIC读操作中间可以有stop也可以不需要stop,具体表现如下
SCCB读:start_1 + phase_1 + phase_2 + stop_1 + start_2 + phase_3 + phase_4 + stop_2IIC读:start_1 + phase_1 + phase_2 + + start_2 + phase_3 + phase_4 + stop_2
除去上面三点,SCCB和IIC再无区别,因此如果只需要配置寄存器(只用到写),可以直接拿IIC的时序来当做SCCB用,如果需要读,读操作中间必须有一个stop。
五、SCCB控制器Verilog代码
1 //**************************************************************************2 // *** 名称 : sccb.v3 // *** 作者 : xianyu_FPGA4 // *** 博客 : https://www.cnblogs.com/xianyufpga/5 // *** 日期 : 2019-08-106 // *** 描述 : SCCB控制器,只支持写7 //**************************************************************************8 9 module sccb10 //========================< 参数 >==========================================11 #(12 parameter DEVICE_ID = 8'b01010000 , //器件ID13 parameter CLK = 26'd50_000_000 , //本模块的时钟频率14 parameter SCL = 18'd250_000 //输出的SCL时钟频率15 )16 //========================< 端口 >==========================================17 (18 input clk , //时钟19 input rst_n , //复位,低电平有效20 //SCCB control -------------------------------------- 21 input sccb_en , //SCCB触发信号22 input addr16_en , //16位地址使能23 input addr8_en , //8位地址使能24 //SCCB input ---------------------------------------- 25 input [15:0] sccb_addr , //SCCB器件内地址26 input [ 7:0] sccb_data , //SCCB要写的数据27 //SCCB output --------------------------------------- 28 output reg sccb_done , //SCCB一次操作完成29 output reg sccb_scl , //SCCB的SCL时钟信号30 inout sccb_sda , //SCCB的SDA数据信号31 //dri_clk ------------------------------------------- 32 output reg sccb_dri_clk //驱动SCCB操作的驱动时钟,1Mhz33 );34 //========================< 状态机参数 >====================================35 localparam IDLE = 6'b00_0001 ; //空闲状态36 localparam DEVICE = 6'b00_0010 ; //写器件地址37 localparam ADDR_16 = 6'b00_0100 ; //写字地址高8位38 localparam ADDR_8 = 6'b00_1000 ; //写字地址低8位39 localparam DATA = 6'b01_0000 ; //写数据40 localparam STOP = 6'b10_0000 ; //结束41 //========================< 信号 >==========================================42 reg sda_dir ; //SCCB数据(SDA)方向控制43 reg sda_out ; //SDA输出信号44 reg state_done ; //状态结束45 reg [ 6:0] cnt ; //计数46 reg [ 7:0] state_c ; //状态机当前状态47 reg [ 7:0] state_n ; //状态机下一状态48 reg [15:0] sccb_addr_t ; //地址寄存49 reg [ 7:0] sccb_data_t ; //数据寄存50 reg [ 9:0] clk_cnt ; //分频时钟计数51 wire [ 8:0] clk_divide ; //模块驱动时钟的分频系数52 53 //==========================================================================54 //== sda控制55 //==========================================================================56 assign sccb_sda = sda_dir ? sda_out : 1'bz; //SDA数据输出或高阻57 58 //==========================================================================59 //== 生成SCL的4倍时钟来驱动后面SCCB的操作,生成1Mhz的sccb_dri_clk60 //==========================================================================61 assign clk_divide = (CLK/SCL) >> 3; // >>3即除以862 63 always @(posedge clk or negedge rst_n) begin64 if(!rst_n) begin65 sccb_dri_clk <= 1'b1;66 clk_cnt <= 10'd0;67 end68 else if(clk_cnt == clk_divide - 1'd1) begin69 clk_cnt <= 10'd0;70 sccb_dri_clk <= ~sccb_dri_clk;71 end72 else73 clk_cnt <= clk_cnt + 1'b1;74 end75 76 //==========================================================================77 //== 状态机78 //==========================================================================79 always @(posedge sccb_dri_clk or negedge rst_n) begin80 if(!rst_n)81 state_c <= IDLE;82 else83 state_c <= state_n;84 end85 86 always @(*) begin87 case(state_c)88 IDLE: begin //空闲状态89 if(sccb_en)90 state_n = DEVICE;91 else92 state_n = IDLE;93 end94 DEVICE: begin //写器件ID95 if(state_done) begin96 if(addr16_en)97 state_n = ADDR_16;98 else if(addr8_en)99 state_n = ADDR_8 ; 100 end 101 else 102 state_n = DEVICE; 103 end 104 ADDR_16: begin //写地址高8位 105 if(state_done) 106 state_n = ADDR_8; 107 else 108 state_n = ADDR_16; 109 end 110 ADDR_8: begin //写地址低8位 111 if(state_done) 112 state_n = DATA; 113 else 114 state_n = ADDR_8; 115 end 116 DATA: begin //写数据 117 if(state_done) 118 state_n = STOP; 119 else 120 state_n = DATA; 121 end 122 STOP: begin //结束 123 if(state_done) 124 state_n = IDLE; 125 else 126 state_n = STOP ; 127 end 128 default:state_n= IDLE; 129 endcase 130 end 131 132 //========================================================================== 133 //== 设计各路信号 134 //========================================================================== 135 always @(posedge sccb_dri_clk or negedge rst_n) begin 136 if(!rst_n) begin 137 sccb_scl <= 1'b1; 138 sda_out <= 1'b1; 139 sda_dir <= 1'b1; 140 sccb_done <= 1'b0; 141 cnt <= 1'b0; 142 state_done <= 1'b0; 143 sccb_addr_t <= 1'b0; 144 sccb_data_t <= 1'b0; 145 end 146 else begin 147 state_done <= 1'b0 ; 148 cnt <= cnt + 1'b1 ; 149 case(state_c) 150 //--------------------------------------------------- 空闲状态 151 IDLE: begin 152 sccb_scl <= 1'b1; 153 sda_out <= 1'b1; 154 sda_dir <= 1'b1; 155 sccb_done <= 1'b0; 156 cnt <= 7'b0; 157 if(sccb_en) begin 158 sccb_addr_t <= sccb_addr; 159 sccb_data_t <= sccb_data; 160 end 161 end 162 //--------------------------------------------------- 写器件ID 163 DEVICE: begin 164 case(cnt) 165 7'd1 : sda_out <= 1'b0; 166 7'd3 : sccb_scl <= 1'b0; 167 7'd4 : sda_out <= DEVICE_ID[7]; 168 7'd5 : sccb_scl <= 1'b1; 169 7'd7 : sccb_scl <= 1'b0; 170 7'd8 : sda_out <= DEVICE_ID[6]; 171 7'd9 : sccb_scl <= 1'b1; 172 7'd11: sccb_scl <= 1'b0; 173 7'd12: sda_out <= DEVICE_ID[5]; 174 7'd13: sccb_scl <= 1'b1; 175 7'd15: sccb_scl <= 1'b0; 176 7'd16: sda_out <= DEVICE_ID[4]; 177 7'd17: sccb_scl <= 1'b1; 178 7'd19: sccb_scl <= 1'b0; 179 7'd20: sda_out <= DEVICE_ID[3]; 180 7'd21: sccb_scl <= 1'b1; 181 7'd23: sccb_scl <= 1'b0; 182 7'd24: sda_out <= DEVICE_ID[2]; 183 7'd25: sccb_scl <= 1'b1; 184 7'd27: sccb_scl <= 1'b0; 185 7'd28: sda_out <= DEVICE_ID[1]; 186 7'd29: sccb_scl <= 1'b1; 187 7'd31: sccb_scl <= 1'b0; 188 7'd32: sda_out <= DEVICE_ID[0]; 189 7'd33: sccb_scl <= 1'b1; 190 7'd35: sccb_scl <= 1'b0; 191 7'd36: begin 192 sda_dir <= 1'b0; //从机应答 193 sda_out <= 1'b1; 194 end 195 7'd37: sccb_scl <= 1'b1; 196 7'd38: state_done <= 1'b1; //状态结束 197 7'd39: begin 198 sccb_scl <= 1'b0; 199 cnt <= 1'b0; 200 end 201 default : ; 202 endcase 203 end 204 //--------------------------------------------------- 写字地址高8位 205 ADDR_16: begin 206 case(cnt) 207 7'd0 : begin 208 sda_dir <= 1'b1 ; 209 sda_out <= sccb_addr_t[15]; 210 end 211 7'd1 : sccb_scl <= 1'b1; 212 7'd3 : sccb_scl <= 1'b0; 213 7'd4 : sda_out <= sccb_addr_t[14]; 214 7'd5 : sccb_scl <= 1'b1; 215 7'd7 : sccb_scl <= 1'b0; 216 7'd8 : sda_out <= sccb_addr_t[13]; 217 7'd9 : sccb_scl <= 1'b1; 218 7'd11: sccb_scl <= 1'b0; 219 7'd12: sda_out <= sccb_addr_t[12]; 220 7'd13: sccb_scl <= 1'b1; 221 7'd15: sccb_scl <= 1'b0; 222 7'd16: sda_out <= sccb_addr_t[11]; 223 7'd17: sccb_scl <= 1'b1; 224 7'd19: sccb_scl <= 1'b0; 225 7'd20: sda_out <= sccb_addr_t[10]; 226 7'd21: sccb_scl <= 1'b1; 227 7'd23: sccb_scl <= 1'b0; 228 7'd24: sda_out <= sccb_addr_t[9]; 229 7'd25: sccb_scl <= 1'b1; 230 7'd27: sccb_scl <= 1'b0; 231 7'd28: sda_out <= sccb_addr_t[8]; 232 7'd29: sccb_scl <= 1'b1; 233 7'd31: sccb_scl <= 1'b0; 234 7'd32: begin 235 sda_dir <= 1'b0; //从机应答 236 sda_out <= 1'b1; 237 end 238 7'd33: sccb_scl <= 1'b1; 239 7'd34: state_done <= 1'b1; //状态结束 240 7'd35: begin 241 sccb_scl <= 1'b0; 242 cnt <= 1'b0; 243 end 244 default : ; 245 endcase 246 end 247 //--------------------------------------------------- 写字地址低8位 248 ADDR_8: begin 249 case(cnt) 250 7'd0: begin 251 sda_dir <= 1'b1 ; 252 sda_out <= sccb_addr_t[7]; 253 end 254 7'd1 : sccb_scl <= 1'b1; 255 7'd3 : sccb_scl <= 1'b0; 256 7'd4 : sda_out <= sccb_addr_t[6]; 257 7'd5 : sccb_scl <= 1'b1; 258 7'd7 : sccb_scl <= 1'b0; 259 7'd8 : sda_out <= sccb_addr_t[5]; 260 7'd9 : sccb_scl <= 1'b1; 261 7'd11: sccb_scl <= 1'b0; 262 7'd12: sda_out <= sccb_addr_t[4]; 263 7'd13: sccb_scl <= 1'b1; 264 7'd15: sccb_scl <= 1'b0; 265 7'd16: sda_out <= sccb_addr_t[3]; 266 7'd17: sccb_scl <= 1'b1; 267 7'd19: sccb_scl <= 1'b0; 268 7'd20: sda_out <= sccb_addr_t[2]; 269 7'd21: sccb_scl <= 1'b1; 270 7'd23: sccb_scl <= 1'b0; 271 7'd24: sda_out <= sccb_addr_t[1]; 272 7'd25: sccb_scl <= 1'b1; 273 7'd27: sccb_scl <= 1'b0; 274 7'd28: sda_out <= sccb_addr_t[0]; 275 7'd29: sccb_scl <= 1'b1; 276 7'd31: sccb_scl <= 1'b0; 277 7'd32: begin 278 sda_dir <= 1'b0; //从机应答 279 sda_out <= 1'b1; 280 end 281 7'd33: sccb_scl <= 1'b1; 282 7'd34: state_done <= 1'b1; //状态结束 283 7'd35: begin 284 sccb_scl <= 1'b0; 285 cnt <= 1'b0; 286 end 287 default : ; 288 endcase 289 end 290 //--------------------------------------------------- 写数据 291 DATA: begin 292 case(cnt) 293 7'd0: begin 294 sda_out <= sccb_data_t[7]; 295 sda_dir <= 1'b1; 296 end 297 7'd1 : sccb_scl <= 1'b1; 298 7'd3 : sccb_scl <= 1'b0; 299 7'd4 : sda_out <= sccb_data_t[6]; 300 7'd5 : sccb_scl <= 1'b1; 301 7'd7 : sccb_scl <= 1'b0; 302 7'd8 : sda_out <= sccb_data_t[5]; 303 7'd9 : sccb_scl <= 1'b1; 304 7'd11: sccb_scl <= 1'b0; 305 7'd12: sda_out <= sccb_data_t[4]; 306 7'd13: sccb_scl <= 1'b1; 307 7'd15: sccb_scl <= 1'b0; 308 7'd16: sda_out <= sccb_data_t[3]; 309 7'd17: sccb_scl <= 1'b1; 310 7'd19: sccb_scl <= 1'b0; 311 7'd20: sda_out <= sccb_data_t[2]; 312 7'd21: sccb_scl <= 1'b1; 313 7'd23: sccb_scl <= 1'b0; 314 7'd24: sda_out <= sccb_data_t[1]; 315 7'd25: sccb_scl <= 1'b1; 316 7'd27: sccb_scl <= 1'b0; 317 7'd28: sda_out <= sccb_data_t[0]; 318 7'd29: sccb_scl <= 1'b1; 319 7'd31: sccb_scl <= 1'b0; 320 7'd32: begin 321 sda_dir <= 1'b0; //从机应答 322 sda_out <= 1'b1; 323 end 324 7'd33: sccb_scl <= 1'b1; 325 7'd34: state_done <= 1'b1; //状态结束 326 7'd35: begin 327 sccb_scl <= 1'b0; 328 cnt <= 1'b0; 329 end 330 default : ; 331 endcase 332 end 333 //--------------------------------------------------- 结束 334 STOP: begin 335 case(cnt) 336 7'd0: begin 337 sda_dir <= 1'b1; 338 sda_out <= 1'b0; 339 end 340 7'd1 : sccb_scl <= 1'b1; 341 7'd3 : sda_out <= 1'b1; 342 7'd15: state_done <= 1'b1; //状态结束 343 7'd16: begin 344 cnt <= 1'b0; 345 sccb_done <= 1'b1; //sccb配置完成 346 end 347 default : ; 348 endcase 349 end 350 endcase 351 end 352 end 353 354 355 356 endmodule
参考资料:
[1]OmniVision Serial Camera Control Bus (SCCB) Functional Specification
[2]正点原子FPGA教程
[3]开源骚客.SDRAM那些事儿
--------------------------------------------------------------------------------------
作者:咸鱼FPGA
出处:https://www.cnblogs.com/xianyufpga/
本文版权归作者所有,如需转载请保留此段声明。
协议——SCCB与IIC的区别相关推荐
- 协议--SCCB与IIC的区别
学习摘自FPGA开源工作室 SCCB(Serial Camera Control Bus,串行摄像头控制总线)是由OV(OmniVision的简称)公司定义和发展的三线式串行总线,该总线控制着摄像头大 ...
- SCCB与IIC的异同及FPGA实现的注意事项
本文主要参考了两种协议的规范文档和一个摄像头传感器(OV7725)的数据手册,文档链接如下: IIC规范:UM10204 SCCB规范:SCCBSpec_AN OV7725数据手册:OV7725 1. ...
- 模拟IIC与硬件IIC的区别!
模拟IIC与硬件IIC的区别! 一:模拟IIC与硬件IIC定义? 模拟I2C一般是用GPIO管脚,用软件控制管脚状态以模拟I2C通信波形. 硬件I2C对应芯片上的I2C外设,有相应I2C驱动电路,其所 ...
- http、TCP/IP协议与socket之间的区别
网络由下往上分为: www.2cto.com 物理层-- 数据链路层-- 网络层-- IP协议 传输层-- ...
- 光纤收发器和协议转换器之间有哪些区别?
在通信网络领域,我们经常会用到光纤收发器和协议转换器,但对此不是很了解的朋友,往往可能会将二者搞混淆.那么,关于光纤收发器与协议转换器之间有什么区别呢?接下来就跟随杭州飞畅的小编一起来看看吧! 光纤收 ...
- 协议和服务器有什么区别,服务期协议是什么,劳动合同与服务期协议有什么区别?...
一.服务期协议是什么? 服务期协议是用人单位与劳动者约定的劳动者为用人单位必须服务的期限.服务期协议不同与劳动合同,劳动合同是用人的单位与劳动者约定的劳动关系存续的存续期间的约定,劳动合同主要适用劳动 ...
- 面试篇-- Http、TCP/IP协议与Socket之间的区别
网络由下往上分为: 物理层-- 数据链路层-- 网络层-- IP协议 传输层-- TCP协议 会话层-- 表示层和应用层-- HTTP协议 1.TCP/IP连接 手机能够使用联网功能是因为手机底层实现 ...
- Zigbee无线协议 和 WiFi通信协议的区别
亿佰特物联网无线通信:Zigbee无线协议 和 WiFi通信协议的区别 物联网领域无线数据传输指的是无线数传模块将工业设备输出或者各种采集的数据进行远程传送,可以无线模拟量采集,也能无线开关量控制.无 ...
- Python进阶----网络通信基础 ,OSI七层协议() ,UDP和TCP的区别 , TCP/IP协议(三次握手,四次挥手)...
Python进阶----网络通信基础 ,OSI七层协议() ,UDP和TCP的区别 , TCP/IP协议(三次握手,四次挥手) 一丶CS/BS 架构 C/S: 客户端/服务器 定义: 这里 ...
最新文章
- centos7上安装redis6-0-5
- 用C语言写的万年历---亲手写的。好累哦
- java aio聊天_JAVA aio简单使用
- win7 找不到 计算机策略组,win7打开组策略报错:找不到资源string.Advanced_EnableSSL3Fallback...
- 修改 Joomla! 1.5 的 HTML 输出而不动核心文件 (附api文档)
- Oracle数据库启动以及说明
- Bzoj5251: [2018多省省队联测]劈配
- android uri 电话号码,android 跳转通讯录 Android跳转到通讯录获取用户名称和手机号码的实现思路...
- 什么是AWT_Swing_Scroll面板,上!!!
- 遗传算法 python_Python实现入门级遗传算法
- 大学生适合学习的软件 网站推荐
- SpringBoot 无法捕获 maximum upload size exceeded
- STL全特化 偏特化 成员特化
- 监听audio是否加载完毕
- 人工智能小白日记 语音情感分析探索之2 CNN相关及实验
- STM32F429IGT6使用SDRAM(W9825G6KH-6)
- 太原理工大学计算机院招生网,相洁-太原理工大学信息与计算机学院
- java上下文控制,Esper事件处理引擎_8_EPL 语法_2_Context 上下文_2_条件控制
- java中当前时间查询_SQL 查询当前时间
- html写的迷宫游戏,网页开发游戏,js实现游戏