#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

{

I2C_MSW_SendByte(I2CxHandlerType, pVal[i]);

}

//---数据左移---数据的发送,首先发送高位

pVal[byteCount] <<= (8 - bitCount);

//---发送指定个数的bit

for (i=0;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 引用地址:STM32驱动PCF8563,使用模拟IIC

上一篇:STM32的boot引脚设置
下一篇:stm32之spi之NSS管脚信号

推荐阅读

现在计算机视觉系统已经很成熟,所以利用计算机视觉来给图片分类也成为可能。IBM与美国官方开发出可以根据种族进行人员搜索的软件,这款软件对警察局来讲应该是非常实用的。美国科技媒体The Intercept和美国国家研究院非盈利调查基金的最新报告显示,IBM与纽约市警察局合作开发了一种系统,让警方可以根据肤色、发色、性别、年龄和各种面部特征去搜索相关...
杨健先生毕业于上海交通大学电子信息与电气工程学院,曾任职于长城电脑(A股)、Cadence(芯片EDA美股,负责中国区设计方法学和代工厂业务);2000年加入汉世纪创投Sino Century VC,2007年协助深创投去南通创立了南通创新投资。2011年创立First Sunshine VC,长期致力于芯片及科技企业的投资。问:有投资机构认为2019年是中国集成电路VC投资的元年,...
据媒体报道,中国科学院深圳先进技术研究院等日前研发出一种基于聚集诱导发光(E)的纳米仿生机器人,用于血脑屏障穿越及脑胶质瘤靶向诊疗。研究人员分别从细胞水平和活体水平对纳米机器人的靶向能力进行验证,在原位移植脑胶质瘤的小鼠模型上,实现高信噪比脑部肿瘤成像引导的光热治疗,为脑肿瘤及其他脑部疾病的诊疗提供新的。 纳米是长度的一个单位...
香港 - 2021 年 9 月 9 日 - 可编程产品平台与技术创新企业易灵思® 今天宣布,为其广受欢迎的 Trion 系列 FPGA 的多款器件提供 AEC-Q100 认证资质,以及一项旨在将其 Trion 和钛金系列产品均延展至汽车市场的重大计划。首批即将发布的具有 AEC-Q100 认证资质的产品是采用 F169 和 F256 封装的 Trion T13 和 T20 FPGA。...

史海拾趣

问答坊 | AI 解惑

步进机

用protues仿真成功的,四线步进机。…

查看全部问答∨

EDK设计的实现流程

嵌入式设计流程包括硬件设计和调试、软件设计和调试。XPS主要用于嵌入式处理器硬件系统的开发。微处理器、外围设备以及这些组件之间的连接问题,还有它们各自的属性设置都在XPS里进行,但是对于复杂的应用Xilinx推荐使用SDK工具。 一、完整的EDK ...…

查看全部问答∨

我写了一个C++小程序,想在arm下跑一下,怎么在windows下模拟啊,急,谢谢大家

我写了一个C++小程序,想在arm下跑一下,怎么在windows下模拟啊,急,谢谢大家 或者其他的办法,linux也行,主要模拟arm4…

查看全部问答∨

‘*’和‘#’有对应的虚拟键码么?

在做输入法,windows CE5.0环境下,4X5键盘输入,请教‘*’和‘#’有对应的虚拟键码么?因为输入法要按‘*’来切换输入法。…

查看全部问答∨

寻觅联手者

毕业都快进两年了 还没找到发展的方向 庆幸的是在所学专业领域之内工作 现在地_哈尔滨 有在哈尔滨工作的或者正在学习的有关硬件开发方面的同仁们 希望能和你一起讨论交流研究这方面的知识技术 QQ:502979394…

查看全部问答∨

模拟输出问题

温度变送器的范围是0——300,为什么经AD转换时使用的SCL指令时坐标上的BX变成了3000勒? 听一个视频上讲数字输出是温度输入的10倍是什么意思?…

查看全部问答∨

****求救啊###

***请教各位大侠了### 下面是C51的程序,用MSP430怎样编这段程序?? 望给为大侠指点; MOV DPTR,#CMD_STD_RD ;标准读命令模式设置 MOV R2,#04H MOV R0,#30H LOOP_M1: MOV A,#00H ;将模式数据放到R0指向的地址中 MOVC A,@A+DPTR MOV @R0,A ...…

查看全部问答∨

电源设计小贴士14:SEPIC转换器提供高效偏置电源

$(\'swf_jhh\').innerHTML=AC_FL_RunContent(\'width\', \'550\', \'height\', \'400\', \'allowNetworking\', \'internal\', \'allowScriptAccess\', \'never\', \'src\', encodeURI(\'http://player.youku.com/player.php/sid/XMzY1NzQ3Nzg4/v.sw ...…

查看全部问答∨

MSP430入门之中断基础

MSP430入门之中断基础 中断的重要性让我怎么分享呢?我个人觉得中断是基于单片机系统编程的核心,熟练的掌握中断是写好SuperLoop程序的基础。单片机的资源毕竟有限,中断掌握好了、协调好了,程序的生命力自然就好了。    &nb ...…

查看全部问答∨

ARM9,s3c2440的Nor和Nand flash启动方式的两个很少注意到的小细节

首先,这两种启动方式及原理我都很清楚,这里有2个细节问题: 1.使用nand flash启动,如果代码小于4K比如3.8K,烧到nand里后启动,2440会自动把代码拷贝到内部4K的SRAM里面,这时候可用的堆栈大小是不是只有0.2K?(在不使用外部SRAM,SDRAM情况下 ...…

查看全部问答∨
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved