/*!
* 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. Winform下去除MDI窗体边框

    做项目中间遇到了MDI窗体内边框的问题,经过苦苦寻找,最终得到了解决方案 在Main窗体中调用API // Win32 Constants ; ; private const int WS_BORDE ...

  2. MySQL主从复制_复制过滤

    关于主从过滤,建议只在从服务器做设定,在Master 端为保证二进制日志的完整, 不建议使用二进制日志过滤. Master 可用参数: binlog-do-db= #定义白名单,仅将制定数据库的相关操 ...

  3. 3.2 while 循环

    Python 编程中 while 语句用于循环执行程序,即在条件满足的情况下,循环执行某段代码.所以就需要在循环的代码块中设计一种使代码块循环执行一定次数后是while语句的条件不满足,从而中止whi ...

  4. [Cake] 1. CI中的Cake

    在上一篇C#Make自动化构建-简介中,简单的介绍了下Cake的脚本如何编写以及通过Powershell在本地运行Cake脚本.本篇在此基础上,介绍下如何在CI环境中使用Cake. 1. Cake简介 ...

  5. vim使用教程

    vim的学习曲线相当的大(参看各种文本编辑器的学习曲线),所以,如果你一开始看到的是一大堆VIM的命令分类,你一定会对这个编辑器失去兴趣的.下面的文章翻译自<Learn Vim Progress ...

  6. R语言实现︱局部敏感哈希算法(LSH)解决文本机械相似性的问题(二,textreuse介绍)

    每每以为攀得众山小,可.每每又切实来到起点,大牛们,缓缓脚步来俺笔记葩分享一下吧,please~ --------------------------- 上一篇(R语言实现︱局部敏感哈希算法(LSH) ...

  7. Java中的a++和++a的区别

    1.a++和++a的区别 a++表示先将a放在表达式中运算,然后再加1: ++a表示先将a加1,然后再放在表达式中运算 2.实例 (1)Java代码 /** * @Title:JiaJia.java ...

  8. Column 'id' in where clause is ambiguous

    1.错误描述 org.hibernate.exception.ConstraintViolationException: error executing work at org.hibernate.e ...

  9. HQL查询步骤

    HQL查询步骤 1.获取Hibernate Session对象 2.编写HQL语句 3.以HQL语句作为参数,调用Session的createQuery方法创建查询对象 4.HQL语句包含参数,则调用 ...

  10. 用OpenStack界面轻松创建虚拟机的你,看得懂虚拟机启动的这24个参数么?

    看这篇文章之前,保证看过以下文章: 我是虚拟机内核我困惑?! Qemu,KVM,Virsh傻傻的分不清 裸用KVM创建虚拟机,体验virtualbox为你做的10件事情 大家从OpenStack页面上 ...