1. /*!
  2. * COPYRIGHT NOTICE
  3. * Copyright (c) 2013,山外科技
  4. * All rights reserved.
  5. * 技术讨论:山外论坛 http://www.vcan123.com
  6. *
  7. * 除注明出处外,以下所有内容版权均属山外科技所有,未经允许,不得用于商业用途,
  8. * 修改内容时必须保留山外科技的版权声明。
  9. *
  10. * @file VCAN_SCCB.c
  11. * @brief OV摄像头配置总线SCCB函数库
  12. * @author 山外科技
  13. * @version v5.0
  14. * @date 2013-09-01
  15. */
  16.  
  17. #include "common.h"
  18. #include "MK60_gpio.h"
  19. #include "VCAN_SCCB.h"
  20.  
  21. static void SCCB_delay(uint16 i);
  22.  
  23. /*!
  24. * @brief SCCB延迟函数
  25. * @param time 延时时间
  26. * @since v5.0
  27. */
  28. static void SCCB_delay(volatile uint16 time)
  29. {
  30. while(time)
  31. {
  32. time--;
  33. }
  34. }
  35.  
  36. /*!
  37. * @brief SCCB管脚配置
  38. * @since v5.0
  39. */
  40. void SCCB_GPIO_init(void)
  41. {
  42. gpio_init (SCCB_SCL, GPO, ); //初始化SCL
  43. gpio_init (SCCB_SDA, GPO, ); //初始化SDA
  44.  
  45. port_init_NoALT(SCCB_SCL,ODO | PULLUP);
  46. port_init_NoALT(SCCB_SDA,ODO | PULLUP);
  47. }
  48.  
  49. /*!
  50. * @brief SCCB起始信号
  51. * @since v5.0
  52. */
  53. static uint8 SCCB_Start(void)
  54. {
  55. SDA_H();
  56. SCL_H();
  57. SCCB_DELAY();
  58.  
  59. SDA_DDR_IN();
  60. if(!SDA_IN())
  61. {
  62. SDA_DDR_OUT();
  63. return ; /* SDA线为低电平则总线忙,退出 */
  64. }
  65. SDA_DDR_OUT();
  66. SDA_L();
  67.  
  68. SCCB_DELAY();
  69. SCL_L();
  70.  
  71. if(SDA_IN())
  72. {
  73. SDA_DDR_OUT();
  74. return ; /* SDA线为高电平则总线出错,退出 */
  75. }
  76. //SDA_DDR_OUT();
  77. //SDA_L();
  78. //SCCB_delay();
  79. return ;
  80. }
  81.  
  82. /*!
  83. * @brief SCCB停止信号
  84. * @since v5.0
  85. */
  86. static void SCCB_Stop(void)
  87. {
  88. SCL_L();
  89. //SCCB_DELAY();
  90. SDA_L();
  91. SCCB_DELAY();
  92. SCL_H();
  93. SCCB_DELAY();
  94. SDA_H();
  95. SCCB_DELAY();
  96. }
  97.  
  98. /*!
  99. * @brief SCCB应答信号
  100. * @since v5.0
  101. */
  102. static void SCCB_Ack(void)
  103. {
  104. SCL_L();
  105. SCCB_DELAY();
  106. SDA_L();
  107. SCCB_DELAY();
  108. SCL_H();
  109. SCCB_DELAY();
  110. SCL_L();
  111. SCCB_DELAY();
  112. }
  113.  
  114. /*!
  115. * @brief SCCB无应答信号
  116. * @since v5.0
  117. */
  118. static void SCCB_NoAck(void)
  119. {
  120. SCL_L();
  121. SCCB_DELAY();
  122. SDA_H();
  123. SCCB_DELAY();
  124. SCL_H();
  125. SCCB_DELAY();
  126. SCL_L();
  127. SCCB_DELAY();
  128. }
  129.  
  130. /*!
  131. * @brief SCCB 等待应答
  132. * @return 应答结果(0表示无应答,1表示有应答)
  133. * @since v5.0
  134. */
  135. static int SCCB_WaitAck(void)
  136. {
  137. SCL_L();
  138. //SDA_H();
  139. SDA_DDR_IN();
  140.  
  141. SCCB_DELAY();
  142. SCL_H();
  143.  
  144. SCCB_DELAY();
  145.  
  146. if(SDA_IN()) //应答为高电平,异常,通信失败
  147. {
  148. SDA_DDR_OUT();
  149. SCL_L();
  150. return ;
  151. }
  152. SDA_DDR_OUT();
  153. SCL_L();
  154. return ;
  155. }
  156.  
  157. /*!
  158. * @brief SCCB 发送的数据
  159. * @param SendByte 需要发送的数据
  160. * @since v5.0
  161. */
  162. static void SCCB_SendByte(uint8 SendByte)
  163. {
  164. uint8 i = ;
  165. while(i--)
  166. {
  167.  
  168. if(SendByte & 0x80) //SDA 输出数据
  169. {
  170. SDA_H();
  171. }
  172. else
  173. {
  174. SDA_L();
  175. }
  176. SendByte <<= ;
  177. SCCB_DELAY();
  178. SCL_H(); //SCL 拉高,采集信号
  179. SCCB_DELAY();
  180. SCL_L(); //SCL 时钟线拉低
  181. //SCCB_DELAY();
  182. }
  183. //SCL_L();
  184. }
  185.  
  186. /*!
  187. * @brief 接收SCCB总线的数据
  188. * @return 接收到的数据
  189. * @since v5.0
  190. */
  191. static int SCCB_ReceiveByte(void)
  192. {
  193. uint8 i = ;
  194. uint8 ReceiveByte = ;
  195.  
  196. //SDA_H();
  197. //SCCB_DELAY();
  198. SDA_DDR_IN();
  199.  
  200. while(i--)
  201. {
  202. ReceiveByte <<= ;
  203. SCL_L();
  204. SCCB_DELAY();
  205. SCL_H();
  206. SCCB_DELAY();
  207.  
  208. if(SDA_IN())
  209. {
  210. ReceiveByte |= 0x01;
  211. }
  212.  
  213. }
  214. SDA_DDR_OUT();
  215. SCL_L();
  216. return ReceiveByte;
  217. }
  218.  
  219. /*****************************************************************************************
  220. * 函数名:SCCB_WriteByte
  221. * 描述 :写一字节数据
  222. * 输入 :- WriteAddress: 待写入地址 - SendByte: 待写入数据 - DeviceAddress: 器件类型
  223. * 输出 :返回为:=1成功写入,=0失败
  224. * 注意 :无
  225. *****************************************************************************************/
  226. static int SCCB_WriteByte_one( uint16 WriteAddress , uint8 SendByte );
  227.  
  228. int SCCB_WriteByte( uint16 WriteAddress , uint8 SendByte ) //考虑到用sccb的管脚模拟,比较容易失败,因此多试几次
  229. {
  230. uint8 i = ;
  231. while( == SCCB_WriteByte_one ( WriteAddress, SendByte ) )
  232. {
  233. i++;
  234. if(i == )
  235. {
  236. return ;
  237. }
  238. }
  239. return ;
  240. }
  241.  
  242. int SCCB_WriteByte_one( uint16 WriteAddress , uint8 SendByte )
  243. {
  244. if(!SCCB_Start())
  245. {
  246. return ;
  247. }
  248. SCCB_SendByte( DEV_ADR ); /* 器件地址 */
  249. if( !SCCB_WaitAck() )
  250. {
  251. SCCB_Stop();
  252. return ;
  253. }
  254. SCCB_SendByte((uint8)(WriteAddress & 0x00FF)); /* 设置低起始地址 */
  255. SCCB_WaitAck();
  256. SCCB_SendByte(SendByte);
  257. SCCB_WaitAck();
  258. SCCB_Stop();
  259. return ;
  260. }
  261.  
  262. /******************************************************************************************************************
  263. * 函数名:SCCB_ReadByte
  264. * 描述 :读取一串数据
  265. * 输入 :- pBuffer: 存放读出数据 - length: 待读出长度 - ReadAddress: 待读出地址 - DeviceAddress: 器件类型
  266. * 输出 :返回为:=1成功读入,=0失败
  267. * 注意 :无
  268. **********************************************************************************************************************/
  269. static int SCCB_ReadByte_one(uint8 *pBuffer, uint16 length, uint8 ReadAddress);
  270.  
  271. int SCCB_ReadByte(uint8 *pBuffer, uint16 length, uint8 ReadAddress)
  272. {
  273. uint8 i = ;
  274. while( == SCCB_ReadByte_one(pBuffer, length, ReadAddress) )
  275. {
  276. i++;
  277. if(i == )
  278. {
  279. return ;
  280. }
  281. }
  282. return ;
  283. }
  284.  
  285. int SCCB_ReadByte_one(uint8 *pBuffer, uint16 length, uint8 ReadAddress)
  286. {
  287. if(!SCCB_Start())
  288. {
  289. return ;
  290. }
  291. SCCB_SendByte( DEV_ADR ); /* 器件地址 */
  292. if( !SCCB_WaitAck() )
  293. {
  294. SCCB_Stop();
  295. return ;
  296. }
  297. SCCB_SendByte( ReadAddress ); /* 设置低起始地址 */
  298. SCCB_WaitAck();
  299. SCCB_Stop();
  300.  
  301. if(!SCCB_Start())
  302. {
  303. return ;
  304. }
  305. SCCB_SendByte( DEV_ADR + ); /* 器件地址 */
  306.  
  307. if(!SCCB_WaitAck())
  308. {
  309. SCCB_Stop();
  310. return ;
  311. }
  312. while(length)
  313. {
  314. *pBuffer = SCCB_ReceiveByte();
  315. if(length == )
  316. {
  317. SCCB_NoAck();
  318. }
  319. else
  320. {
  321. SCCB_Ack();
  322. }
  323. pBuffer++;
  324. length--;
  325. }
  326. SCCB_Stop();
  327. return ;
  328. }

OV摄像头SCCB通信协议的更多相关文章

  1. OV摄像头图像采集基础知识总结

    目前FPGA用于图像采集 传输 处理 显示应用越来越多,主要原因是图像处理领域的火热以及FPGA强大的并行处理能力.本文以OV7725为例,对摄像头使用方面的基础知识做个小的总结,为后续做个铺垫. 下 ...

  2. 摄像头驱动0V7725学习笔记连载(三):0V7725 SCCB时序的实现

    上一篇博客主要是讲解了关于需要配置的重要寄存器,那么接下来就是要通过SCCB接口实现对OV7725的配置.参考<OmniVision Serial Camera Control Bus (SCC ...

  3. 摄像头驱动OV7725学习笔记连载(二):0V7725 SCCB时序的实现之寄存器配置

    上一篇博客主要介绍了OV7725的电气特性以及SCCB接口的时序和输出一帧图像的时序图以及数据的拼接.输出一帧图像与输出时钟PCLK有关. 上图是OV7725实现的整体框架,有点丑.FPGA描述SCC ...

  4. 解决OV系列摄像头寄存器读数据无法收到的问题

    最近工作中接了一款OV7725的sensor,由于平台已经接过很多的家的sensor也就没有太当回事.问题出现的很奇怪,再看了 register map后基本确定了要尽心register  R/W测试 ...

  5. 摄像头驱动OV7725学习笔记连载(一):OV7725 电器特性和时序图

    OV(豪威科技)已经被中国财团收购.这个昔日的大佬,最终走下神坛. 关于OVsensor的资料包括,OV7725的简介(OmniVsion_OV7725),OV7725的数据手册(OV7725_Dat ...

  6. 协议——SCCB与IIC的区别

    SCCB(Serial Camera Control Bus,串行摄像头控制总线)是由OV(OmniVision的简称)公司定义和发展的三线式串行总线,该总线控制着摄像头大部分的功能,包括图像数据格式 ...

  7. 人工智能"眼睛"——摄像头

    摄像头机器视觉人工智能的"眼睛",其重要性在嵌入式领域不言而喻.但是如何理解和使用摄像头却是一个非常棘手的问题.本文主要针对调试摄像头过程中遇到的问题,对摄像头的基本原理及概述进行 ...

  8. IM通信协议逆向分析、Wireshark自定义数据包格式解析插件编程学习

    相关学习资料 http://hi.baidu.com/hucyuansheng/item/bf2bfddefd1ee70ad68ed04d http://en.wikipedia.org/wiki/I ...

  9. SLAM+语音机器人DIY系列:(三)感知与大脑——4.音响麦克风与摄像头

    摘要 在我的想象中机器人首先应该能自由的走来走去,然后应该能流利的与主人对话.朝着这个理想,我准备设计一个能自由行走,并且可以与人语音对话的机器人.实现的关键是让机器人能通过传感器感知周围环境,并通过 ...

随机推荐

  1. IE兼容swiper

    swiper3能完美运用在移动端,但是运用在PC端,特别是IE浏览器上不能兼容,没有效果,要使IE兼容Swiper的话必须使用swiper2,也就是idangerous.swiper.js, 下载地址 ...

  2. C# 使用AngleSharp 爬虫图片

    AngleSharp 简介 AngleSharp是基于.NET(C#)开发的专门解析HTML源码的DLL组件.根据HTML的DOM结构操作HTML,整个DOM已传输到逻辑类结构中.这种结构可以更好的操 ...

  3. 搭建VUE项目的准备(利用vue-cli来构建项目)

    首先需要明确的是:Vue.js 不支持 IE8 及其以下 IE 版本,一般用与移动端,基础:开启最高权限的DOS命令(否则会出现意外的错误提示)   注意:个人小推荐如果我们不知道如何才能开启最高权限 ...

  4. Spring Boot 2.0(二):Spring Boot 2.0尝鲜-动态 Banner

    Spring Boot 2.0 提供了很多新特性,其中就有一个小彩蛋:动态 Banner,今天我们就先拿这个来尝尝鲜. 配置依赖 使用 Spring Boot 2.0 首先需要将项目依赖包替换为刚刚发 ...

  5. soj3129: windy和水星 -- 水星数学家 2

    注意int的范围:-2147483648-2147483647 如果输入会出现溢出,这题应该就是卡的这里.其使用long long就不用考虑这个. 加深:如果输入的数是很多位,直接当做字符串处理即可. ...

  6. 小程序中曾经遇到的坑(1)----canvas画布

    目前正在开发小程序,在开发过程中,总会遇到一些坑,而这些坑并不会有很多开发者遇到而说出来.这里先记录一条我开发过程中遇到的问题,以便后人在开发中能够更容易的解决问题!!! 首先,小程序在canvas画 ...

  7. 2_Add Two Numbers --LeetCode

    原题如下: 思路:在一个while中遍历两个链表,直到最长的链表为空,或者没有进位.每一步获取两个链表对应的结点的值a,b,然后相加a+b.如果上一步又进位,那就加a+b+1,若由于进位加1后还产生进 ...

  8. JavaScript函数的柯里化(currying)

    转载请注明出处:http://www.cnblogs.com/shamoyuu/p/currying.html 什么是js函数的currying /柯里化? 说到js的柯里化,相信很多朋友都会头大.或 ...

  9. ActiveMQ安装及启动

    最近项目组遇到MQ的问题(项目组用的IBM MQ),突然想回来看看MQ.本来就不是太熟练,闲来无事写写看看. 不多说,首先是安转ActiveMQ,官方网址:http://activemq.apache ...

  10. PHP_保留两位小数并且四舍五入_保留两位小数并且不四舍五入

    php保留两位小数并且四舍五入 $num = 123213.666666; echo sprintf("%.2f", $num); php保留两位小数并且不四舍五入 php进一法取 ...