STM32HAL_GPIO模拟SCCB

本文介绍了SCCB接口中一系列的配置和通信函数,如GPIO管脚配置、延迟处理、起始/停止信号、应答机制以及数据传输(发送和接收)。这些函数用于控制和管理与外部设备的串行通信。
摘要由CSDN通过智能技术生成
#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 

  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值