#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; //}