151 lines
3.4 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "sccb.h"
#include "delay.h"
//////////////////////////////////////////////////////////////////////////////////
//本程序只供学习使用,未经作者许可,不得用于其它任何用途
//ALIENTEK STM32h7开发板
//OV系列摄像头 SCCB 驱动代码
//正点原子@ALIENTEK
//技术论坛:www.openedv.com
//创建日期:2017/8/15
//版本V1.0
//版权所有,盗版必究。
//Copyright(C) 广州市星翼电子科技有限公司 2014-2024
//All rights reserved
//////////////////////////////////////////////////////////////////////////////////
void SCCB_Delay(void)
{
delay_us(5);
}
//初始化SCCB接口
void SCCB_Init(void)
{
GPIO_InitTypeDef GPIO_Initure;
__HAL_RCC_GPIOB_CLK_ENABLE(); //使能GPIOB时钟
//PB3.4初始化设置
GPIO_Initure.Pin=GPIO_PIN_3|GPIO_PIN_4;
GPIO_Initure.Mode=GPIO_MODE_OUTPUT_PP; //推挽输出
GPIO_Initure.Pull=GPIO_PULLUP; //上拉
GPIO_Initure.Speed=GPIO_SPEED_FREQ_VERY_HIGH; //快速
HAL_GPIO_Init(GPIOB,&GPIO_Initure);
}
//SCCB起始信号
//当时钟为高的时候,数据线的高到低,为SCCB起始信号
//在激活状态下,SDA和SCL均为低电平
void SCCB_Start(void)
{
SCCB_SDA(1); //数据线高电平
SCCB_SCL(1); //在时钟线高的时候数据线由高至低
SCCB_Delay();
SCCB_SDA(0);
SCCB_Delay();
SCCB_SCL(0); //数据线恢复低电平,单操作函数必要
}
//SCCB停止信号
//当时钟为高的时候,数据线的低到高,为SCCB停止信号
//空闲状况下,SDA,SCL均为高电平
void SCCB_Stop(void)
{
SCCB_SDA(0);
SCCB_Delay();
SCCB_SCL(1);
SCCB_Delay();
SCCB_SDA(1);
SCCB_Delay();
}
//产生NA信号
void SCCB_No_Ack(void)
{
SCCB_Delay();
SCCB_SDA(1);
SCCB_SCL(1);
SCCB_Delay();
SCCB_SCL(0);
SCCB_Delay();
SCCB_SDA(0);
SCCB_Delay();
}
//SCCB,写入一个字节
//返回值:0,成功;1,失败.
u8 SCCB_WR_Byte(u8 dat)
{
u8 j,res;
for(j=0;j<8;j++) //循环8次发送数据
{
if(dat&0x80)SCCB_SDA(1);
else SCCB_SDA(0);
dat<<=1;
SCCB_Delay();
SCCB_SCL(1);
SCCB_Delay();
SCCB_SCL(0);
}
SCCB_SDA_IN(); //设置SDA为输入
SCCB_Delay();
SCCB_SCL(1); //接收第九位,以判断是否发送成功
SCCB_Delay();
if(SCCB_READ_SDA)res=1; //SDA=1发送失败返回1
else res=0; //SDA=0发送成功返回0
SCCB_SCL(0);
SCCB_SDA_OUT(); //设置SDA为输出
return res;
}
//SCCB 读取一个字节
//在SCL的上升沿,数据锁存
//返回值:读到的数据
u8 SCCB_RD_Byte(void)
{
u8 temp=0,j;
SCCB_SDA_IN(); //设置SDA为输入
for(j=8;j>0;j--) //循环8次接收数据
{
SCCB_Delay();
SCCB_SCL(1);
temp=temp<<1;
if(SCCB_READ_SDA)temp++;
SCCB_Delay();
SCCB_SCL(0);
}
SCCB_SDA_OUT(); //设置SDA为输出
return temp;
}
////写寄存器
////返回值:0,成功;1,失败.
//u8 SCCB_WR_Reg(u8 reg,u8 data)
//{
// u8 res=0;
// SCCB_Start(); //启动SCCB传输
// if(SCCB_WR_Byte(SCCB_ID))res=1; //写器件ID
// delay_us(100);
// if(SCCB_WR_Byte(reg))res=1; //写寄存器地址
// delay_us(100);
// if(SCCB_WR_Byte(data))res=1; //写数据
// SCCB_Stop();
// return res;
//}
////读寄存器
////返回值:读到的寄存器值
//u8 SCCB_RD_Reg(u8 reg)
//{
// u8 val=0;
// SCCB_Start(); //启动SCCB传输
// SCCB_WR_Byte(SCCB_ID); //写器件ID
// delay_us(100);
// SCCB_WR_Byte(reg); //写寄存器地址
// delay_us(100);
// SCCB_Stop();
// delay_us(100);
// //设置寄存器地址后,才是读
// SCCB_Start();
// SCCB_WR_Byte(SCCB_ID|0X01); //发送读命令
// delay_us(100);
// val=SCCB_RD_Byte(); //读取数据
// SCCB_No_Ack();
// SCCB_Stop();
// return val;
//}