#include "bsp_sccb.h"
/********************************************************************
* 函数名:SCCB_Configuration
* 描述 :SCCB管脚配置
* 输入 :无
* 输出 :无
* 注意 :无
********************************************************************/
void SCCB_GPIO_Config(void)
{
GPIO_InitTypeDef GPIO_InitStructure;
/*开启相关的GPIO外设时钟*/
SCCB_SCL_CLK_ENABLE();
SCCB_SDA_CLK_ENABLE();
GPIO_InitStructure.Pin = SCCB_PIN_SDA;
GPIO_InitStructure.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStructure.Pull = GPIO_NOPULL;
GPIO_InitStructure.Speed = GPIO_SPEED_FAST;
HAL_GPIO_Init(SCCB_SDA_PORT, &GPIO_InitStructure);
GPIO_InitStructure.Pin = SCCB_PIN_SCL;
HAL_GPIO_Init(SCCB_SCL_PORT, &GPIO_InitStructure);
SCCB_Stop();
}
/********************************************************************
* 函数名:SCCB_delay
* 描述 :延迟时间
* 输入 :无
* 输出 :无
* 注意 :内部调用
********************************************************************/
void SCCB_delay(void)
{
uint16_t i = 0; //读取很好
for (i = 0; i < 200; i++);
}
/********************************************************************
* 函数名:SCCB_Start
* 描述 :SCCB起始信号
* 输入 :无
* 输出 :无
* 注意 :内部调用
********************************************************************/
void SCCB_Start(void)
{
SDA_H();
SCL_H();
SCCB_delay();
SDA_L();
SCCB_delay();
SCL_L();
SCCB_delay();
}
/********************************************************************
* 函数名:SCCB_Stop
* 描述 :SCCB停止信号
* 输入 :无
* 输出 :无
* 注意 :内部调用
********************************************************************/
void SCCB_Stop(void)
{
SDA_L();
SCL_H();
SCCB_delay();
SDA_H();
}
/********************************************************************
* 函数名:SCCB_Ack
* 描述 :SCCB应答方式
* 输入 :无
* 输出 :无
* 注意 :内部调用
********************************************************************/
void SCCB_Ack(void)
{
SDA_L();
SCCB_delay();
SCL_H();
SCCB_delay();
SCL_L();
SCCB_delay();
SDA_H();
}
/********************************************************************
* 函数名:SCCB_NoAck
* 描述 :SCCB 无应答方式
* 输入 :无
* 输出 :无
* 注意 :内部调用
********************************************************************/
void SCCB_NoAck(void)
{
SDA_H();
SCCB_delay();
SCL_H();
SCCB_delay();
SCL_L();
SCCB_delay();
}
/********************************************************************
* 函数名:SCCB_WaitAck
* 描述 :SCCB 等待应答
* 输入 :无
* 输出 :返回为:=0有ACK,=1无ACK
* 注意 :内部调用
********************************************************************/
uint8_t SCCB_WaitAck(void)
{
uint8_t re;
SDA_H(); /* CPU释放SDA总线 */
SCCB_delay();
SCL_H(); /* CPU驱动SCL = 1, 此时器件会返回ACK应答*/
SCCB_delay();
if(SDA_read()) /* CPU读取SDA口线状态 */
{
re = 1;
}
else
{
re = 0;
}
SCL_L();
SCCB_delay();
return re;
}
/*******************************************************************
* 函数名:SCCB_SendByte
* 描述 :数据从高位到低位
* 输入 :SendByte: 发送的数据
* 输出 :无
* 注意 :内部调用
*********************************************************************/
void SCCB_SendByte(uint8_t SendByte)
{
uint8_t i;
for (i = 0; i < 8; i++)
{
if(SendByte & 0x80)
{
SDA_H();
}
else
{
SDA_L();
}
SCCB_delay();
SCL_H();
SCCB_delay();
SCL_L();
if(i == 7)
{
SDA_H();
}
SendByte<<=1;
SCCB_delay();
}
}
/******************************************************************
* 函数名:SCCB_ReceiveByte
* 描述 :数据从高位到低位
* 输入 :无
* 输出 :SCCB总线返回的数据
* 注意 :内部调用
*******************************************************************/
uint8_t SCCB_ReceiveByte(void)
{
uint8_t i;
uint8_t ReceiveByte=0;
for (i = 0; i < 8; i++)
{
ReceiveByte<<=1;
SCL_H();
SCCB_delay();
if(SDA_read())
{
ReceiveByte++;
}
SCL_L();
SCCB_delay();
}
return ReceiveByte;
}
/*****************************************************************************************
* 函数名:SCCB_WriteByte
* 描述 :写一字节数据
* 输入 :- WriteAddress: 待写入地址 - SendByte: 待写入数据 - DeviceAddress: 器件类型
* 输出 :返回为:=1成功写入,=0失败
* 注意 :无
*****************************************************************************************/
uint8_t SCCB_WriteByte( uint16_t WriteAddress , uint8_t SendByte )
{
uint8_t re;
SCCB_Start();
SCCB_SendByte(OV2640_DEVICE_ADDRESS|SCCB_WR); /* 器件地址 */
re = SCCB_WaitAck();
SCCB_SendByte((uint8_t)(WriteAddress & 0x00FF)); /* 设置低起始地址 */
re = SCCB_WaitAck();
SCCB_SendByte(SendByte);
re = SCCB_WaitAck();
return re;
}
/******************************************************************************************************************
* 函数名:SCCB_ReadByte
* 描述 :读取一个数据
* 输入 :- pBuffer: 存放读出数据 - ReadAddress: 待读出地址 - DeviceAddress: 器件类型
* 输出 :返回为:=1成功读入,=0失败
* 注意 :无
**********************************************************************************************************************/
uint8_t SCCB_ReadByte(uint8_t* pBuffer, uint8_t ReadAddress)
{
uint8_t re;
SCCB_Start();
SCCB_SendByte(OV2640_DEVICE_ADDRESS|SCCB_WR);
re = SCCB_WaitAck();
SCCB_SendByte(ReadAddress);
re = SCCB_WaitAck();
SCCB_Stop();
SCCB_Start();
SCCB_SendByte(OV2640_DEVICE_ADDRESS|SCCB_RD);
re = SCCB_WaitAck();
*pBuffer = SCCB_ReceiveByte();
SCCB_NoAck();
SCCB_Stop();
return re;
}
/*********************************************END OF FILE**********************/
#ifndef __SCCB_H
#define __SCCB_H
#include "main.h"
#define OV2640_DEVICE_ADDRESS 0x60
//#define OV2640_DEVICE_ADDRESS 0xC0
#define SCCB_RD 1
#define SCCB_WR 0
#define SCCB_SCL_PORT GPIOB
#define SCCB_PIN_SCL GPIO_PIN_6
#define SCCB_SCL_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
#define SCCB_SDA_PORT GPIOB
#define SCCB_PIN_SDA GPIO_PIN_7
#define SCCB_SDA_CLK_ENABLE() __HAL_RCC_GPIOB_CLK_ENABLE()
///* 直接操作寄存器的方法控制IO */
//#define digitalHi(p,i) {p->BSRR=i;} //设置为高电平
//#define digitalLo(p,i) {p->BSRR=(uint32_t)i << 16;}//输出低电平
//#define SCL_H digitalHi(GPIOC , GPIO_PIN_6)
//#define SCL_L digitalLo(GPIOC , GPIO_PIN_6)
//
//#define SDA_H digitalHi(GPIOC , GPIO_PIN_7)
//#define SDA_L digitalLo(GPIOC , GPIO_PIN_7)
#if 1
#define SCL_H() HAL_GPIO_WritePin(SCCB_SCL_PORT,SCCB_PIN_SCL ,GPIO_PIN_SET)
#define SCL_L() HAL_GPIO_WritePin(SCCB_SCL_PORT,SCCB_PIN_SCL ,GPIO_PIN_RESET)
#define SDA_H() HAL_GPIO_WritePin(SCCB_SDA_PORT,SCCB_PIN_SDA ,GPIO_PIN_SET)
#define SDA_L() HAL_GPIO_WritePin(SCCB_SDA_PORT,SCCB_PIN_SDA ,GPIO_PIN_RESET)
#endif
#define SCL_read() HAL_GPIO_ReadPin(SCCB_SCL_PORT , SCCB_PIN_SCL)
#define SDA_read() HAL_GPIO_ReadPin(SCCB_SDA_PORT , SCCB_PIN_SDA)
#define ADDR_OV7725 0x42
void SCCB_GPIO_Config(void);
void SCCB_Start(void);
void SCCB_Stop(void);
void SCCB_Ack(void);
void SCCB_NoAck(void);
uint8_t SCCB_WaitAck(void);
void SCCB_SendByte(uint8_t SendByte);
uint8_t SCCB_ReceiveByte(void);
uint8_t SCCB_WriteByte( uint16_t WriteAddress , uint8_t SendByte);
uint8_t SCCB_ReadByte(uint8_t * pBuffer,uint8_t ReadAddress);
#endif