STM32驱动PCF8563,使用模拟IIC

#ifndef PCF8563_CFG_H
#define PCF8563_CFG_H
//////////////////////////////////////////////////////////////////////////////////////
//------------使用包含的头文件
#include "i2c_task.h"
#ifdef USE_MCU_STM32
	#include "delay_task.h"
#endif

//---寄存器定义
#define PCF8563_REG_STATUS1						0x00
#define PCF8563_REG_STATUS2						0x01
#define PCF8563_REG_SECOND						0x02
#define PCF8563_REG_MINUTE						0x03
#define PCF8563_REG_HOURS						0x04
#define PCF8563_REG_DAY							0x05
#define PCF8563_REG_WEEK						0x06
#define PCF8563_REG_MONTH						0x07
#define PCF8563_REG_YEAR						0x08
#define PCF8563_REG_MINUTE_ALARM				0x09
#define PCF8563_REG_HOURS_ALARM					0x0A
#define PCF8563_REG_DAY_ALARM					0x0B
#define PCF8563_REG_WEEK_ALARM					0x0C
#define PCF8563_REG_CLKOUT						0x0D
#define PCF8563_REG_TIMER_CTR					0x0E
#define PCF8563_REG_TIMER 						0x0F

//---I2C设备地址
#define PCF8563_WRITE_ADDR						0xA2
#define PCF8563_READ_ADDR						0xA3

//---CLKOUT的输出
#define PCF8563_CLKOUT_32768HZ					0
#define PCF8563_CLKOUT_1024HZ					1
#define PCF8563_CLKOUT_32HZ						2
#define PCF8563_CLKOUT_1HZ						3

//---定义使用的端口
//---SCL
#define PCF8563_SCL_PORT						GPIOB
#define PCF8563_SCL_BIT							LL_GPIO_PIN_8

//---SDA
#define PCF8563_SDA_PORT						GPIOB
#define PCF8563_SDA_BIT							LL_GPIO_PIN_9

//---结构体定义
typedef struct _RTC_HandlerType					RTC_HandlerType;
//---时钟结构体的定义
struct _RTC_HandlerType
{
	UINT8_T second;								//---秒
	UINT8_T minute;								//---分
	UINT8_T hour;								//---时
	UINT8_T day;								//---天
	UINT8_T week;								//---星期
	UINT8_T month;								//---月
	UINT8_T year;								//---年
	UINT8_T century;							//---世纪
};
//---结构体定义
typedef struct _PCF8563_HandlerType				PCF8563_HandlerType;
//---指针结构体定义
typedef struct _PCF8563_HandlerType				*pPCF8563_HandlerType;
//---PCF853的数据结构体
struct _PCF8563_HandlerType
{
	RTC_HandlerType	msgRTC;						//---实时时钟
	I2C_HandlerType msgI2C;						//---使用的I2C
};

//---外部调用的接口函数
extern PCF8563_HandlerType g_PCF8563;
extern pPCF8563_HandlerType pPCF8563;


//---函数定义
UINT8_T PCF8563_Init( void );
UINT8_T PCF8563_WriteReg( UINT8_T reg, UINT8_T val );
UINT8_T PCF8563_ReadReg( UINT8_T reg , UINT8_T *pVal,UINT8_T length );
UINT8_T PCF8563_ClockOut( UINT8_T preVal );
UINT8_T PCF8563_ReadRTC(void);
UINT8_T PCF8563_WriteRTC(RTC_HandlerType rtc);
///////////////////////////////////////////////////////////////////////////////

#endif /* PCF8563_CFG_H */

#include "pcf8563_cfg.h"
 
//---全局变量定义
PCF8563_HandlerType g_PCF8563=
{
	.msgRTC=
	{
	  .year=0,
	  .month=0,
	  .day=0,
	  .hour=0,
	  .minute=0,
	  .second=0,
	},
	.msgI2C=
	{
		.msgI2Cx			= NULL,
		.msgSclPort			= PCF8563_SCL_PORT,
		.msgSdaPort			= PCF8563_SDA_PORT,
		.msgSclBit			= PCF8563_SCL_BIT,
		.msgSdaBit			= PCF8563_SDA_BIT,
		.msgModelIsHW		= 0,
		.msgPluseWidth		= 0,
		.msgDelay			= NULL,
		.msgAddr			= PCF8563_WRITE_ADDR,
		.msgClockSpeed		= 0,
		.msgTask			= NULL,
	},
};
 
//---全局指针变量
pPCF8563_HandlerType pPCF8563=&g_PCF8563;
 
///////////////////////////////////////////////////////////////////////////////
//////函	   数:
//////功	   能:
//////输入参数: 
//////输出参数: 
//////说	   明:
//////////////////////////////////////////////////////////////////////////////
UINT8_T PCF8563_Init(void)
{
	return I2CTask_MSW_Init( &pPCF8563->msgI2C , DelayTask_us );
}
 
///////////////////////////////////////////////////////////////////////////////
//////函	   数:
//////功	   能:写寄存器
//////输入参数: 
//////输出参数: 
//////说	   明:
//////////////////////////////////////////////////////////////////////////////
UINT8_T PCF8563_WriteReg(UINT8_T reg,UINT8_T val)
{
	UINT8_T _return = OK_0;
	//---启动并发送地址
	_return=I2CTask_MSW_START(&pPCF8563->msgI2C, 1);
	if (_return != OK_0)
	{
		//---启动写数据失败
		_return = ERROR_2;
		goto GoToExit;
	}
	//---发送寄存器地址
	I2CTask_MSW_SendByte(&pPCF8563->msgI2C, reg);
	//---读取ACK
	_return = I2CTask_MSW_ReadACK(&pPCF8563->msgI2C);
	if (_return!= OK_0)
	{
		//---发送数据失败
		_return = ERROR_3;
		goto GoToExit;
	}
	//---发送寄存器地址
	I2CTask_MSW_SendByte(&pPCF8563->msgI2C, val);
	//---读取ACK
	_return = I2CTask_MSW_ReadACK(&pPCF8563->msgI2C);
GoToExit:
	//---发送停止信号
	I2CTask_MSW_STOP(&pPCF8563->msgI2C);
	return _return;
}
 
///////////////////////////////////////////////////////////////////////////////
//////函	   数:
//////功	   能:读取寄存器
//////输入参数: 
//////输出参数: 
//////说	   明:
//////////////////////////////////////////////////////////////////////////////
UINT8_T PCF8563_ReadReg( UINT8_T reg , UINT8_T *pVal,UINT8_T length )
{
	UINT8_T _return = OK_0,i=0;
	//---启动写数据
	_return = I2CTask_MSW_START(&pPCF8563->msgI2C, 1);
	if (_return != OK_0)
	{
		//---启动写数据失败
		_return = ERROR_2;
		goto GoToExit;
	}
	//---发送寄存器地址
	I2CTask_MSW_SendByte(&pPCF8563->msgI2C, reg);
	//---读取ACK
	_return = I2CTask_MSW_ReadACK(&pPCF8563->msgI2C);
	if (_return != OK_0)
	{
		//---发送数据失败
		_return = ERROR_3;
		goto GoToExit;
	}
	//---发送停止信号
	I2CTask_MSW_STOP(&pPCF8563->msgI2C);
	//---启动读取数据
	_return = I2CTask_MSW_START(&pPCF8563->msgI2C, 0);
	if (_return != OK_0)
	{
		//---启动读数据失败
		_return = ERROR_4;
		goto GoToExit;
	}
	for (i = 0;i < length;i++)
	{
		//---读取数据
		pVal[i] = I2CTask_MSW_ReadByte(&pPCF8563->msgI2C);
		if (i == (length - 1))
		{
			_return = 1;
		}
		//---发送应答信号
		I2CTask_MSW_SendACK(&pPCF8563->msgI2C, _return);
	}
	_return = OK_0;
GoToExit:
	//---发送停止信号
	I2CTask_MSW_STOP(&pPCF8563->msgI2C);
	return _return;
}
 
///////////////////////////////////////////////////////////////////////////////
//////函	   数: UINT8_T PCF8563_HandlerType_ClockOut(UINT8_T preVal)
//////功	   能: PCF8563输出时钟,输出分频
//////输入参数: 
//////输出参数: 
//////说	   明: 
//////////////////////////////////////////////////////////////////////////////
UINT8_T PCF8563_ClockOut(UINT8_T preVal)
{	
	UINT8_T _return = OK_0;
	UINT8_T temp = 0;
	//---写寄存器
	_return=PCF8563_WriteReg( PCF8563_REG_CLKOUT, ( preVal | 0x80 ) );
	if (_return!= OK_0)
	{
		_return = ERROR_2;
		goto GoToExit;
	}
	//---读取寄存器
	_return = PCF8563_ReadReg(PCF8563_REG_CLKOUT, &temp,1);
	if (_return!=OK_0)
	{
		_return = ERROR_3;
		goto GoToExit;
	}
	//---数据的校验
	if ((temp&0x7F)!=preVal)
	{
		_return = ERROR_1;
	}
GoToExit:
	return _return ;
}
 
///////////////////////////////////////////////////////////////////////////////
//////函	   数:
//////功	   能:
//////输入参数: 
//////输出参数: 
//////说	   明:
//////////////////////////////////////////////////////////////////////////////
UINT8_T PCF8563_ReadRTC(void)
{
	UINT8_T _return = OK_0;
	UINT8_T temp[7];
	//---读取时钟
	_return = PCF8563_ReadReg(PCF8563_REG_SECOND, temp, 7);
	//---解析数据
	if (_return== OK_0)
	{
		//---将获取的数据填充到缓存区
		pPCF8563->msgRTC.second = (temp[0] & 0x7F);
		pPCF8563->msgRTC.minute = (temp[1] & 0x7F);
		pPCF8563->msgRTC.hour	= (temp[2] & 0x3F);
		pPCF8563->msgRTC.day	= (temp[3] & 0x3F);
		pPCF8563->msgRTC.week	= (temp[4] & 0x07);
		pPCF8563->msgRTC.month	= (temp[5] & 0x1F);
		//---年份
		pPCF8563->msgRTC.year = temp[6];
		//---世纪
		if (temp[5] & 0x80)
		{
			pPCF8563->msgRTC.century = 0x19;
		}
		else
		{
			pPCF8563->msgRTC.century = 0x20;
		}
	}
	return _return;
}
 
///////////////////////////////////////////////////////////////////////////////
//////函		数: 
//////功		能: 
//////输入参数: 
//////输出参数: 
//////说		明: 
//////////////////////////////////////////////////////////////////////////////
UINT8_T PCF8563_WriteRTC(RTC_HandlerType rtc)
{
	UINT8_T _return = OK_0;
	//---判断数据类型是不是BCD码
	if ((rtc.century!=0x19)||(rtc.century!=0x20))
	{
		//===处理数据位BCD格式
		rtc.second	= DecToBcd(rtc.second);
		rtc.minute	= DecToBcd(rtc.minute);
		rtc.hour	= DecToBcd(rtc.hour);
		rtc.day		= DecToBcd(rtc.day);
		rtc.week	= DecToBcd(rtc.week);
		rtc.month	= DecToBcd(rtc.month);
		rtc.year	= DecToBcd(rtc.year);
		rtc.century = DecToBcd(rtc.century);
	}
	//---世纪参数的处理
	if (rtc.century == 0x20)
	{
		rtc.month &= 0x3F;
	}
	else
	{
		rtc.month |= 0x80;
	}
	//---写秒
	_return = PCF8563_WriteReg(PCF8563_REG_SECOND, rtc.second);
	if (_return!= OK_0)
	{
		_return = ERROR_2;
		goto GoToExit;
	}
	//---写分
	_return = PCF8563_WriteReg(PCF8563_REG_MINUTE, rtc.minute);
	if (_return!= OK_0)
	{
		_return = ERROR_3;
		goto GoToExit;
	}
	//---写时
	_return = PCF8563_WriteReg(PCF8563_REG_HOURS, rtc.hour);
	if (_return!= OK_0)
	{
		_return = ERROR_4;
		goto GoToExit;
	}
	//---写天
	_return = PCF8563_WriteReg(PCF8563_REG_DAY, rtc.day);
	if (_return!= OK_0)
	{
		_return = ERROR_5;
		goto GoToExit;
	}
	//---写星期
	_return = PCF8563_WriteReg(PCF8563_REG_WEEK, rtc.week);
	if (_return!= OK_0)
	{
		_return = ERROR_6;
		goto GoToExit;
	}
	//---写月
	_return = PCF8563_WriteReg(PCF8563_REG_MONTH, rtc.month);
	if (_return!= OK_0)
	{
		_return = ERROR_7;
		goto GoToExit;
	}
	//---写年
	_return = PCF8563_WriteReg(PCF8563_REG_YEAR, rtc.year);
GoToExit:
	return _return;
}
#ifndef I2C_CFG_H
#define I2C_CFG_H
 
///////////////////////////////////////////////////////////////////////////////
//////使用该函数,首先保证GPIO的时钟已经使能,函数内部已经将端口配置为开漏输出
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
#include "complier_lib.h"
#ifdef USE_MCU_STM32
	#include "gpio_task.h"
#endif
 
//===消息体模式
//---SDA端口
#define I2C_SDA_OUT_0(name,index)				GPIO_OUT_0(		name,index )
#define I2C_SDA_OUT_1(name,index)				GPIO_OUT_1(		name,index )
#define I2C_SDA_STATE(name,index)				GPIO_GET_STATE(	name,index )
#define I2C_SDA_READ(name,index)				GPIO_SET_READ(	name,index )
#define I2C_SDA_WRITE(name,index)				GPIO_SET_WRITE(	name,index )
//---SCL端口
#define I2C_SCL_OUT_0(name,index)				GPIO_OUT_0(		name,index )
#define I2C_SCL_OUT_1(name,index)				GPIO_OUT_1(		name,index )
#define I2C_SCL_STATE(name,index)				GPIO_GET_STATE(	name,index )
#define I2C_SCL_READ(name,index)				GPIO_SET_READ(	name,index )
#define I2C_SCL_WRITE(name,index)				GPIO_SET_WRITE(	name,index )
 
 
//---结构体定义
typedef struct _I2C_HandlerType					I2C_HandlerType;
typedef	struct _I2C_HandlerType					*pI2C_HandlerType;
//---消息体的I2C
struct _I2C_HandlerType
{
	I2C_TypeDef		*msgI2Cx;																				//---使用的I2C接口
	GPIO_TypeDef	*msgSclPort;																			//---SCL端口
	GPIO_TypeDef	*msgSdaPort;																			//---SDA端口
	UINT32_T		msgSclBit;																				//---SCL引脚
	UINT32_T		msgSdaBit;																				//---SDA引脚
	UINT8_T			msgModelIsHW;																			//---工作模式,默认是软件模拟---0,硬件模式---1
	UINT8_T			msgPluseWidth;																			//---脉冲宽度,软件模拟使用
	void			(*msgDelay)(UINT32_T delay);															//---延时参数
	UINT16_T		msgAddr;																				//---设备的地址
	UINT32_T		msgClockSpeed;																			//---硬件I2C的时钟速度
	UINT8_T			(*msgTask)(I2C_HandlerType I2CxHandlerType,UINT16_T length,UINT8_T *pVal,UINT8_T msg);	//---消息体处理函数
};
 
//---函数定义
UINT8_T I2C_HandlerType_Init(I2C_HandlerType *I2CxHandlerType);
UINT8_T I2C_MSW_Init(I2C_HandlerType *I2CxHandlerType, void(*msgDelay)(UINT32_T delay));
UINT8_T I2C_MSW_DeInit(I2C_HandlerType *I2CxHandlerType);
UINT8_T I2C_MSW_START(I2C_HandlerType *I2CxHandlerType);
UINT8_T I2C_MSW_STOP(I2C_HandlerType *I2CxHandlerType);
UINT8_T I2C_MSW_ACK(I2C_HandlerType *I2CxHandlerType);
UINT8_T I2C_MSW_NACK(I2C_HandlerType *I2CxHandlerType);
UINT8_T I2C_MSW_ReadACK(I2C_HandlerType *I2CxHandlerType);
UINT8_T I2C_MSW_WaitACK(I2C_HandlerType *I2CxHandlerType);
UINT8_T I2C_MSW_SendACK(I2C_HandlerType *I2CxHandlerType, UINT8_T isNACK);
UINT8_T I2C_MSW_SendByte(I2C_HandlerType *I2CxHandlerType, UINT8_T val);
UINT8_T I2C_MSW_SendBits(I2C_HandlerType *I2CxHandlerType, UINT8_T *pVal, UINT8_T bitNum);
UINT8_T I2C_MSW_ReadByte(I2C_HandlerType *I2CxHandlerType);
UINT8_T I2C_MSW_ReadBits(I2C_HandlerType *I2CxHandlerType, UINT8_T *pVal, UINT8_T bitNum);
UINT8_T I2C_MSW_SendCMD(I2C_HandlerType *I2CxHandlerType, UINT8_T cmd, UINT8_T isStart, UINT8_T isStop);
 
//////////////////////////////////////////////////////////////////////////////////////
#endif /*i2c_cfg_H */
#include "i2c_cfg.h"
 
///////////////////////////////////////////////////////////////////////////////
//////函		数: 
//////功		能: 
//////输入参数: 
//////输出参数: 
//////说		明: 
//////////////////////////////////////////////////////////////////////////////
UINT8_T I2C_HandlerType_Init(I2C_HandlerType *I2CxHandlerType)
{
	/*
	I2CxHandlerType->msgPluseWidth = 0;
	I2CxHandlerType->msgDelay = NULL;
	I2CxHandlerType->msgAddr = 0;
	I2CxHandlerType->msgClockSpeed = 0;
	I2CxHandlerType->msgTask = NULL;
	*/
	return OK_0;
}
 
///////////////////////////////////////////////////////////////////////////////
//////函		数: 
//////功		能: 
//////输入参数: 
//////输出参数: 
//////说		明: 
//////////////////////////////////////////////////////////////////////////////
UINT8_T I2C_MSW_Init(I2C_HandlerType *I2CxHandlerType,void(*msgDelay)(UINT32_T delay))
{
#ifdef USE_MCU_STM32
	//---使能GPIO的时钟
	GPIOTask_Clock(I2CxHandlerType->msgSclPort,1);
	GPIOTask_Clock(I2CxHandlerType->msgSdaPort,1);
	//---SCL和SDA端口输出高电平
	I2C_SCL_OUT_1(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);
	I2C_SDA_OUT_1(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit);
	//---GPIO的结构体
	LL_GPIO_InitTypeDef GPIO_InitStruct;
	//---GPIO的初始化
	GPIO_InitStruct.Pin			= I2CxHandlerType->msgSclBit;				//---对应的GPIO的引脚
	GPIO_InitStruct.Mode		= LL_GPIO_MODE_OUTPUT;						//---配置状态为输出模式
	GPIO_InitStruct.Speed		= LL_GPIO_SPEED_FREQ_VERY_HIGH;				//---GPIO的速度
	GPIO_InitStruct.OutputType	= LL_GPIO_OUTPUT_OPENDRAIN;					//---输出模式---开漏输出
	GPIO_InitStruct.Pull		= LL_GPIO_PULL_UP;							//---上拉
	//---SCL的初始化
	LL_GPIO_Init(I2CxHandlerType->msgSclPort, &GPIO_InitStruct);
	//---SDA的初始化
	GPIO_InitStruct.Pin = I2CxHandlerType->msgSdaBit;
	LL_GPIO_Init(I2CxHandlerType->msgSdaPort, &GPIO_InitStruct);
#endif 
	//---设置使用的延时函数
	if (msgDelay!=NULL)
	{
		I2CxHandlerType->msgDelay = msgDelay;
	}
	return OK_0;
}
 
///////////////////////////////////////////////////////////////////////////////
//////函		数: 
//////功		能: 
//////输入参数: 
//////输出参数: 
//////说		明: 
//////////////////////////////////////////////////////////////////////////////
UINT8_T I2C_MSW_DeInit(I2C_HandlerType *I2CxHandlerType)
{
	//---端口设置为输入模式
	I2C_SCL_READ(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);
	I2C_SDA_READ(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit);
	//---SCL和SDA端口输出高电平
	I2C_SCL_OUT_1(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);
	I2C_SDA_OUT_1(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit);
	//---注销任务函数
	if (I2CxHandlerType->msgTask!=NULL)
	{
		I2CxHandlerType->msgTask = NULL;
	}
	return OK_0;
}
 
///////////////////////////////////////////////////////////////////////////////
//////函		数: 
//////功		能: 
//////输入参数: 
//////输出参数: 
//////说		明: 
//////////////////////////////////////////////////////////////////////////////
UINT8_T I2C_MSW_START(I2C_HandlerType *I2CxHandlerType)
{	
	//---发送起始条件的数据信号
	I2C_SDA_OUT_1(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit);
	I2C_SCL_OUT_1(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);
	if (I2CxHandlerType->msgDelay != NULL)
	{
		I2CxHandlerType->msgDelay(I2CxHandlerType->msgPluseWidth);
	}
	//---发送起始信号;
	I2C_SDA_OUT_0(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit);
	if (I2CxHandlerType->msgDelay != NULL)
	{
		I2CxHandlerType->msgDelay(I2CxHandlerType->msgPluseWidth);
	}
	//---钳住I2C总线,准备发送或接收数据
	I2C_SCL_OUT_0(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);
	//---判断I2C启动信号是否成功,读取SDA的状态信号,成功SDA---0;失败SDA---1
	if (I2C_SDA_STATE(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit)!= OK_0)
	{
		return ERROR_1;
	}
	return OK_0;
}
 
///////////////////////////////////////////////////////////////////////////////
//////函		数: 
//////功		能: 
//////输入参数: 
//////输出参数: 
//////说		明: 
//////////////////////////////////////////////////////////////////////////////
UINT8_T I2C_MSW_STOP(I2C_HandlerType *I2CxHandlerType)
{
	//---发送停止条件的数据信号
	I2C_SDA_OUT_0(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit);
	I2C_SCL_OUT_1(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);
	if (I2CxHandlerType->msgDelay != NULL)
	{
		I2CxHandlerType->msgDelay(I2CxHandlerType->msgPluseWidth);
	}
	I2C_SDA_OUT_1(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit);
	if (I2CxHandlerType->msgDelay != NULL)
	{
		I2CxHandlerType->msgDelay(I2CxHandlerType->msgPluseWidth);
	}
	//---判断I2C启动信号是否成功,读取SDA的状态信号,成功SDA---1;失败SDA---0
	if (I2C_SDA_STATE(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit)== OK_0)
	{
		return ERROR_1;
	}
	I2C_SCL_OUT_0(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);
	//I2C_SDA_OUT_0(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit);
	return OK_0;
}
 
///////////////////////////////////////////////////////////////////////////////
//////函		数: 
//////功		能: 
//////输入参数: 
//////输出参数: 
//////说		明: 
//////////////////////////////////////////////////////////////////////////////
UINT8_T I2C_MSW_ACK(I2C_HandlerType *I2CxHandlerType)
{
	I2C_SDA_OUT_0(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit);
	I2C_SCL_OUT_1(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);
	if (I2CxHandlerType->msgDelay != NULL)
	{
		I2CxHandlerType->msgDelay(I2CxHandlerType->msgPluseWidth);
	}
	//---清时钟线,钳住I2C总线,准备发送或接收数据
	I2C_SCL_OUT_0(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);
	return OK_0;
}
 
///////////////////////////////////////////////////////////////////////////////
//////函		数: 
//////功		能: 
//////输入参数: 
//////输出参数: 
//////说		明: 
//////////////////////////////////////////////////////////////////////////////
UINT8_T I2C_MSW_NACK(I2C_HandlerType *I2CxHandlerType)
{
	I2C_SDA_OUT_1(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit);
	I2C_SCL_OUT_1(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);
	if (I2CxHandlerType->msgDelay != NULL)
	{
		I2CxHandlerType->msgDelay(I2CxHandlerType->msgPluseWidth);
	}
	//---清时钟线,钳住I2C总线,准备发送或接收数据
	I2C_SCL_OUT_0(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);
	return OK_0;
}
 
///////////////////////////////////////////////////////////////////////////////
//////函		数: 
//////功		能: 
//////输入参数: 
//////输出参数: 
//////说		明: 
//////////////////////////////////////////////////////////////////////////////
UINT8_T I2C_MSW_ReadACK(I2C_HandlerType *I2CxHandlerType)
{
	UINT8_T _return = OK_0;
	//---读取应答信号
	I2C_SDA_OUT_1(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit);
	I2C_SCL_OUT_1(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);
	//---延时等待
	if (I2CxHandlerType->msgDelay != NULL)
	{
		I2CxHandlerType->msgDelay(I2CxHandlerType->msgPluseWidth);
	}
	//---读取SDA的状态信号---ACK状态下SDA为低电平
	if (I2C_SDA_STATE(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit)!= OK_0)
	{
		_return = ERROR_1;
	}
	//---清时钟线,钳住I2C总线,准备发送或接收数据
	I2C_SCL_OUT_0(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);
	return _return;
}
 
///////////////////////////////////////////////////////////////////////////////
//////函		数: 
//////功		能: 
//////输入参数: 
//////输出参数: 
//////说		明: 
//////////////////////////////////////////////////////////////////////////////
UINT8_T I2C_MSW_WaitACK(I2C_HandlerType *I2CxHandlerType)
{
	UINT8_T i = 0;
	//---读取应答信号
	I2C_SDA_OUT_1(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit);
	I2C_SCL_OUT_1(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);
	//---等待应答信号
	for (i = 255; i > 0; i--)
	{
		//---读取SDA的状态
		if (I2C_SDA_STATE(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit))
		{
			break;
		}
	}
	if (i==0)
	{
		I2C_MSW_STOP(I2CxHandlerType);
		return ERROR_1;
	}
	//---清时钟线,钳住I2C总线,准备发送或接收数据
	I2C_SCL_OUT_0(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);
	return OK_0;
}
 
///////////////////////////////////////////////////////////////////////////////
//////函		数: 
//////功		能: 
//////输入参数: 
//////输出参数: 
//////说		明: 
//////////////////////////////////////////////////////////////////////////////
UINT8_T I2C_MSW_SendACK(I2C_HandlerType *I2CxHandlerType,UINT8_T isNACK)
{
	if (isNACK)
	{
		return I2C_MSW_NACK(I2CxHandlerType);
	}
	else
	{
		return I2C_MSW_ACK(I2CxHandlerType);
	}
}
 
///////////////////////////////////////////////////////////////////////////////
//////函		数: 
//////功		能: 
//////输入参数: 
//////输出参数: 
//////说		明: 
//////////////////////////////////////////////////////////////////////////////
UINT8_T I2C_MSW_SendBit(I2C_HandlerType *I2CxHandlerType, UINT8_T bitVal)
{
	if (bitVal&0x80)
	{
		I2C_SDA_OUT_1(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit);
	}
	else
	{
		I2C_SDA_OUT_0(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit);
	}
	//---一个时钟脉冲
	I2C_SCL_OUT_1(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);
	if (I2CxHandlerType->msgDelay != NULL)
	{
		I2CxHandlerType->msgDelay(I2CxHandlerType->msgPluseWidth);
	}
	I2C_SCL_OUT_0(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);
	if (I2CxHandlerType->msgDelay != NULL)
	{
		I2CxHandlerType->msgDelay(I2CxHandlerType->msgPluseWidth);
	}
	return OK_0;
}
 
///////////////////////////////////////////////////////////////////////////////
//////函		数: 
//////功		能: 
//////输入参数: 
//////输出参数: 
//////说		明: 
//////////////////////////////////////////////////////////////////////////////
UINT8_T I2C_MSW_SendByte(I2C_HandlerType *I2CxHandlerType, UINT8_T val)
{
	UINT8_T i = 0;
	//---清时钟线,钳住I2C总线,准备发送或接收数据
	I2C_SCL_OUT_0(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);
	//---发送1字节的数据
	for (i=0;i<8;i++)
	{
		//---读取1Bit的数据
		I2C_MSW_SendBit(I2CxHandlerType,val);
		val <<= 1;
	}
	return OK_0;
}
 
///////////////////////////////////////////////////////////////////////////////
//////函		数: 
//////功		能: 
//////输入参数: 
//////输出参数: 
//////说		明: 
//////////////////////////////////////////////////////////////////////////////
UINT8_T I2C_MSW_SendBits(I2C_HandlerType *I2CxHandlerType, UINT8_T *pVal,UINT8_T bitNum)
{
	//---计算字节个数
	UINT8_T byteCount = (bitNum / 8);
	//---计算bit个数
	UINT8_T bitCount = (bitNum % 8);
	UINT8_T i = 0;
	//---发送整数字节的个数
	for (i=0;i<byteCount;i++)
	{
		I2C_MSW_SendByte(I2CxHandlerType, pVal[i]);
	}
	//---数据左移---数据的发送,首先发送高位
	pVal[byteCount] <<= (8 - bitCount);
	//---发送指定个数的bit
	for (i=0;i<bitCount;i++)
	{
		I2C_MSW_SendBit(I2CxHandlerType, pVal[byteCount]);
		pVal[byteCount] <<= 1;
	}
	return OK_0;
}
 
///////////////////////////////////////////////////////////////////////////////
//////函		数: 
//////功		能: 
//////输入参数: 
//////输出参数: 
//////说		明: 
//////////////////////////////////////////////////////////////////////////////
UINT8_T I2C_MSW_ReadBit(I2C_HandlerType *I2CxHandlerType)
{
	UINT8_T _return = OK_0;
	//---时钟正脉冲
	I2C_SCL_OUT_1(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);
	if (I2CxHandlerType->msgDelay != NULL)
	{
		I2CxHandlerType->msgDelay(I2CxHandlerType->msgPluseWidth);
	}
	//---读取数据位
	if (I2C_SDA_STATE(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit))
	{
		_return = ERROR_1;
	}
	//---时钟负脉冲
	I2C_SCL_OUT_0(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);
	if (I2CxHandlerType->msgDelay != NULL)
	{
		I2CxHandlerType->msgDelay(I2CxHandlerType->msgPluseWidth);
	}
	return  _return;
}
 
///////////////////////////////////////////////////////////////////////////////
//////函		数: 
//////功		能: 
//////输入参数: 
//////输出参数: 
//////说		明: 
//////////////////////////////////////////////////////////////////////////////
UINT8_T I2C_MSW_ReadByte(I2C_HandlerType *I2CxHandlerType)
{
	UINT8_T i = 0;
	UINT8_T _return = 0;
	//---准备数据的读取
	I2C_SDA_OUT_1(I2CxHandlerType->msgSdaPort, I2CxHandlerType->msgSdaBit);
	//---清时钟线,钳住I2C总线,准备发送或接收数据
	I2C_SCL_OUT_0(I2CxHandlerType->msgSclPort, I2CxHandlerType->msgSclBit);
	//---发送1字节的数据
	for (i = 0; i < 8; i++)
	{
		_return <<= 1;
		_return|=I2C_MSW_ReadBit(I2CxHandlerType);
	}
	return _return;
}
 
///////////////////////////////////////////////////////////////////////////////
//////函		数: 
//////功		能: 
//////输入参数: 
//////输出参数: 
//////说		明: 
//////////////////////////////////////////////////////////////////////////////
UINT8_T I2C_MSW_ReadBits(I2C_HandlerType *I2CxHandlerType, UINT8_T *pVal, UINT8_T bitNum)
{
	//---读取字节个数
	UINT8_T byteCount = (bitNum / 8);
	//---读取bit个数
	UINT8_T bitCount = (bitNum % 8);
	UINT8_T i = 0;
	//---读取整数字节的个数
	for (i = 0; i < byteCount; i++)
	{
		pVal[i]=I2C_MSW_ReadByte(I2CxHandlerType);
	}
	//---清零处理
	pVal[byteCount] = 0x00;
	//---读取指定个数的bit
	for (i = 0; i < bitCount; i++)
	{
		pVal[byteCount] <<= 1;
		pVal[byteCount]|=I2C_MSW_ReadBit(I2CxHandlerType);
	}
	return OK_0;
}
 
///////////////////////////////////////////////////////////////////////////////
//////函		数: 
//////功		能: 
//////输入参数: 
//////输出参数: 
//////说		明: 
//////////////////////////////////////////////////////////////////////////////
UINT8_T I2C_MSW_SendCMD(I2C_HandlerType *I2CxHandlerType, UINT8_T cmd, UINT8_T isStart, UINT8_T isStop)
{
	UINT8_T _return = OK_0;
	if (isStart)
	{
		//---发送启动启动信号
		_return=I2C_MSW_START(I2CxHandlerType);
		if (_return)
		{
			I2C_MSW_STOP(I2CxHandlerType);
			return ERROR_1;
		}
	}
	//---发送数据
	_return = I2C_MSW_SendByte(I2CxHandlerType, cmd);
	//---读取应答
	_return = I2C_MSW_ReadACK(I2CxHandlerType);
	//---停止条件的满足
	if ((isStop)||(_return))
	{
		I2C_MSW_STOP(I2CxHandlerType);
	}
	return _return;
}

你可能感兴趣的:(STM32驱动PCF8563,使用模拟IIC)