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;< 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_WriteRegPCF8563_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;
}

### 回答1: PCF8563是一款常用的实时时钟(RTC)芯片,可以与STM32F103单片机进行连接和驱动。下面是在STM32F103单片机驱动PCF8563的一些步骤和方法。 首先,需要在STM32F103单片机上设置I2C总线通信。在单片机上配置I2C总线通信的引脚,并初始化I2C外设。然后,需要创建一个用于配置和通信的I2C数据传输结构体,并配置PCF8563的I2C地址。 接着,需要初始化PCF8563芯片。首先,在I2C总线上发送一个开始写传输请求,并发送PCF8563的地址。然后,发送一个控制字节,以配置PCF8563的各种设置,如时钟模式、频率选择等。最后,发送一个停止传输请求,以完成初始化。 在初始化完成后,就可以进行一些常见的RTC操作,如读取和设置时间。要读取时间,可以先发送一个开始写传输请求,并发送PCF8563的地址。然后,发送一个读取命令,并读取PCF8563返回的数据。最后,发送一个停止传输请求,以结束读取操作。要设置时间,可以通过类似的过程,将需要设置的时间数据发送给PCF8563。 此外,还可以对PCF8563进行一些其他操作,如闹钟配置、定时器配置等。这些操作的步骤与读取和设置时间类似,只需根据需要发送不同的命令和数据即可。 总之,通过配置I2C总线通信以及发送相应的命令和数据,可以实现对PCF8563驱动操作。在STM32F103单片机上,可以利用已有的I2C外设来实现PCF8563的通信,从而实现对PCF8563驱动。 ### 回答2: STM32F103是一款32位的ARM Cortex-M3微控制器,而PCF8563是一款实时时钟(RTC)芯片。要驱动PCF8563,我们需要通过I2C协议与其进行通信。 首先,我们需要在STM32F103上配置I2C总线。我们通过设置GPIO引脚为I2C模式,然后初始化I2C控制器,设置通信速率和地址寄存器来实现。 接下来,我们需要编写代码来与PCF8563进行通信。我们可以通过发送命令字节和数据字节来读写寄存器。例如,要读取当前的时间,我们可以发送读取命令字节,然后接收返回的数据字节。 在编写代码之前,我们需要查看PCF8563的数据手册,了解其寄存器的结构和功能。根据手册,我们可以确定读写寄存器的地址和格式。 在代码中,我们首先发送开始信号,然后发送设备地址和命令字节或数据字节。然后等待传输完成,并接收返回的数据字节。最后,我们发送停止信号,结束通信。 通过这种方式,我们可以驱动PCF8563,读取和设置实时时钟的时间和日期。我们可以将这些功能封装在函数中,以便在需要时轻松地调用。 总结一下,驱动PCF8563需要配置STM32F103的I2C总线,并通过发送命令和数据字节与其进行通信。编写的代码需要根据PCF8563的数据手册来实现读写寄存器的功能。这样,我们就能够实现与PCF8563的通信和控制。 ### 回答3: 要驱动STM32F103与PCF8563实时时钟模块,首先需要通过I2C总线连接这两个设备。在STM32的代码中,需要先配置I2C引脚,确定引脚的GPIO模式、速度和上下拉电阻等。然后,需要初始化I2C外设,包括设置I2C的时钟频率、使能I2C的时钟等。接下来,需要在代码中实现与PCF8563通信的相关函数。 通常,在驱动PCF8563时,需要实现以下功能: 1. 设置PCF8563的控制寄存器。控制寄存器常用于设置时钟的工作模式、中断使能等。 2. 读取和设置PCF8563的时间寄存器。时间寄存器包括秒、分钟、小时等,可以通过I2C读取或写入对应的寄存器来获取或设置时间。 3. 读取和设置PCF8563的日期寄存器。日期寄存器包括年、月、日等,同样可以通过I2C读取或写入对应的寄存器来获取或设置日期。 4. 读取和设置PCF8563的闹钟寄存器。闹钟寄存器包括闹钟时间,可以通过I2C读取或写入对应的寄存器来获取或设置闹钟时间。 5. 读取和设置PCF8563的定时器寄存器。定时器寄存器可以用于设置周期性中断或延时功能。 在编写这些函数时,需要先发送启动信号,并指定I2C总线的地址,然后发送读或写命令,最后读取或写入数据到相应的寄存器。 总的来说,驱动PCF8563STM32F103的实时时钟模块需要配置I2C引脚和外设、实现与PCF8563通信的相关函数,以实现对PCF8563的控制和读写操作。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值