/*!
* COPYRIGHT NOTICE
* Copyright (c) 2013,山外科技
* All rights reserved.
* 技术讨论:山外论坛 http://www.vcan123.com
*
* 除注明出处外,以下所有内容版权均属山外科技所有,未经允许,不得用于商业用途,
* 修改内容时必须保留山外科技的版权声明。
*
* @file VCAN_SCCB.c
* @brief OV摄像头配置总线SCCB函数库
* @author 山外科技
* @version v5.0
* @date 2013-09-01
*/ #include "common.h"
#include "MK60_gpio.h"
#include "VCAN_SCCB.h" static void SCCB_delay(uint16 i); /*!
* @brief SCCB延迟函数
* @param time 延时时间
* @since v5.0
*/
static void SCCB_delay(volatile uint16 time)
{
while(time)
{
time--;
}
} /*!
* @brief SCCB管脚配置
* @since v5.0
*/
void SCCB_GPIO_init(void)
{
gpio_init (SCCB_SCL, GPO, ); //初始化SCL
gpio_init (SCCB_SDA, GPO, ); //初始化SDA port_init_NoALT(SCCB_SCL,ODO | PULLUP);
port_init_NoALT(SCCB_SDA,ODO | PULLUP);
} /*!
* @brief SCCB起始信号
* @since v5.0
*/
static uint8 SCCB_Start(void)
{
SDA_H();
SCL_H();
SCCB_DELAY(); SDA_DDR_IN();
if(!SDA_IN())
{
SDA_DDR_OUT();
return ; /* SDA线为低电平则总线忙,退出 */
}
SDA_DDR_OUT();
SDA_L(); SCCB_DELAY();
SCL_L(); if(SDA_IN())
{
SDA_DDR_OUT();
return ; /* SDA线为高电平则总线出错,退出 */
}
//SDA_DDR_OUT();
//SDA_L();
//SCCB_delay();
return ;
} /*!
* @brief SCCB停止信号
* @since v5.0
*/
static void SCCB_Stop(void)
{
SCL_L();
//SCCB_DELAY();
SDA_L();
SCCB_DELAY();
SCL_H();
SCCB_DELAY();
SDA_H();
SCCB_DELAY();
} /*!
* @brief SCCB应答信号
* @since v5.0
*/
static void SCCB_Ack(void)
{
SCL_L();
SCCB_DELAY();
SDA_L();
SCCB_DELAY();
SCL_H();
SCCB_DELAY();
SCL_L();
SCCB_DELAY();
} /*!
* @brief SCCB无应答信号
* @since v5.0
*/
static void SCCB_NoAck(void)
{
SCL_L();
SCCB_DELAY();
SDA_H();
SCCB_DELAY();
SCL_H();
SCCB_DELAY();
SCL_L();
SCCB_DELAY();
} /*!
* @brief SCCB 等待应答
* @return 应答结果(0表示无应答,1表示有应答)
* @since v5.0
*/
static int SCCB_WaitAck(void)
{
SCL_L();
//SDA_H();
SDA_DDR_IN(); SCCB_DELAY();
SCL_H(); SCCB_DELAY(); if(SDA_IN()) //应答为高电平,异常,通信失败
{
SDA_DDR_OUT();
SCL_L();
return ;
}
SDA_DDR_OUT();
SCL_L();
return ;
} /*!
* @brief SCCB 发送的数据
* @param SendByte 需要发送的数据
* @since v5.0
*/
static void SCCB_SendByte(uint8 SendByte)
{
uint8 i = ;
while(i--)
{ if(SendByte & 0x80) //SDA 输出数据
{
SDA_H();
}
else
{
SDA_L();
}
SendByte <<= ;
SCCB_DELAY();
SCL_H(); //SCL 拉高,采集信号
SCCB_DELAY();
SCL_L(); //SCL 时钟线拉低
//SCCB_DELAY();
}
//SCL_L();
} /*!
* @brief 接收SCCB总线的数据
* @return 接收到的数据
* @since v5.0
*/
static int SCCB_ReceiveByte(void)
{
uint8 i = ;
uint8 ReceiveByte = ; //SDA_H();
//SCCB_DELAY();
SDA_DDR_IN(); while(i--)
{
ReceiveByte <<= ;
SCL_L();
SCCB_DELAY();
SCL_H();
SCCB_DELAY(); if(SDA_IN())
{
ReceiveByte |= 0x01;
} }
SDA_DDR_OUT();
SCL_L();
return ReceiveByte;
} /*****************************************************************************************
* 函数名:SCCB_WriteByte
* 描述 :写一字节数据
* 输入 :- WriteAddress: 待写入地址 - SendByte: 待写入数据 - DeviceAddress: 器件类型
* 输出 :返回为:=1成功写入,=0失败
* 注意 :无
*****************************************************************************************/
static int SCCB_WriteByte_one( uint16 WriteAddress , uint8 SendByte ); int SCCB_WriteByte( uint16 WriteAddress , uint8 SendByte ) //考虑到用sccb的管脚模拟,比较容易失败,因此多试几次
{
uint8 i = ;
while( == SCCB_WriteByte_one ( WriteAddress, SendByte ) )
{
i++;
if(i == )
{
return ;
}
}
return ;
} int SCCB_WriteByte_one( uint16 WriteAddress , uint8 SendByte )
{
if(!SCCB_Start())
{
return ;
}
SCCB_SendByte( DEV_ADR ); /* 器件地址 */
if( !SCCB_WaitAck() )
{
SCCB_Stop();
return ;
}
SCCB_SendByte((uint8)(WriteAddress & 0x00FF)); /* 设置低起始地址 */
SCCB_WaitAck();
SCCB_SendByte(SendByte);
SCCB_WaitAck();
SCCB_Stop();
return ;
} /******************************************************************************************************************
* 函数名:SCCB_ReadByte
* 描述 :读取一串数据
* 输入 :- pBuffer: 存放读出数据 - length: 待读出长度 - ReadAddress: 待读出地址 - DeviceAddress: 器件类型
* 输出 :返回为:=1成功读入,=0失败
* 注意 :无
**********************************************************************************************************************/
static int SCCB_ReadByte_one(uint8 *pBuffer, uint16 length, uint8 ReadAddress); int SCCB_ReadByte(uint8 *pBuffer, uint16 length, uint8 ReadAddress)
{
uint8 i = ;
while( == SCCB_ReadByte_one(pBuffer, length, ReadAddress) )
{
i++;
if(i == )
{
return ;
}
}
return ;
} int SCCB_ReadByte_one(uint8 *pBuffer, uint16 length, uint8 ReadAddress)
{
if(!SCCB_Start())
{
return ;
}
SCCB_SendByte( DEV_ADR ); /* 器件地址 */
if( !SCCB_WaitAck() )
{
SCCB_Stop();
return ;
}
SCCB_SendByte( ReadAddress ); /* 设置低起始地址 */
SCCB_WaitAck();
SCCB_Stop(); if(!SCCB_Start())
{
return ;
}
SCCB_SendByte( DEV_ADR + ); /* 器件地址 */ if(!SCCB_WaitAck())
{
SCCB_Stop();
return ;
}
while(length)
{
*pBuffer = SCCB_ReceiveByte();
if(length == )
{
SCCB_NoAck();
}
else
{
SCCB_Ack();
}
pBuffer++;
length--;
}
SCCB_Stop();
return ;
}

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. uva1625

    思路:每次选择颜色面临有两个选择:1.序列A的首部颜色 2.序列B的首部元素,定义状态d[i][j]表示A序列已经选取了前i个颜色,B序列已经选取了前j个颜色的情况下最小的L(c)总和. 状态转移:c ...

  2. HDU - 3567 IDA* + 曼哈顿距离 + 康托 [kuangbin带你飞]专题二

    这题难度颇大啊,TLE一天了,测试数据组数太多了.双向广度优先搜索不能得到字典序最小的,一直WA. 思路:利用IDA*算法,当前状态到达目标状态的可能最小步数就是曼哈顿距离,用于搜索中的剪枝.下次搜索 ...

  3. C# 之三类文件的读写( .XML,.INI 和 .TXT 文件)

    笔记之用,关于三类.xml, .ini, .txt 文件的 C# 读写,请多多指教! 1,第一类:.xml 文件的读写 先贴上xml文件,下面对这个文件进行操作: <?xml version=& ...

  4. openstack-ocata-网络服务5

    一. 网络服务概述 Networking(neutron),允许创建.插入接口设备,这些设备由其他的OpenStack服务管理.插件式的实现可以容纳不同的网络设备和软件,为OpenStack架构与部署 ...

  5. Linux基础一

    基本命令 useradd xxx 创建一个用户 uname     查看系统架构信息 uname -a  显示详细信息 uname -r  显示内核信息 date      显示当前网络时间 cat ...

  6. PHPmysqli的 预处理执行插入语句

    预编译在mysql端 预编译可以自动防止sql注入攻击 <?php //预编译技术 //1.创建一个mysqli对象 //2.创建myslqi预编译对象 $mysqli=); $mysqli-& ...

  7. 基于嵌入式操作系统VxWorks的多任务并发程序设计(1)――基本概念

    1引言 嵌入式系统定义义为:嵌入到对象体系中的专用计算机系统."嵌入性"."专用性"与"计算机系统"是嵌入式统的三个基本要素,对象系统则是指 ...

  8. Linux显示版本信息并退出

    Linux显示版本信息并退出 youhaidong@youhaidong-ThinkPad-Edge-E545:~$ cat --version cat (GNU coreutils) 8.21 Co ...

  9. OpenStack_I版 3.glance部署

    存储镜像path                 默认镜像不存储在本地,一般放在swift对象存储或Cinder块存储里   glance安装     拷贝配置文件到/ect下,并新建配置目录,日志目 ...

  10. Java并发系列[7]----CountDownLatch源码分析

    CountDownLatch(闭锁)是一个很有用的工具类,利用它我们可以拦截一个或多个线程使其在某个条件成熟后再执行.它的内部提供了一个计数器,在构造闭锁时必须指定计数器的初始值,且计数器的初始值必须 ...