×
单片机 > 单片机程序设计 > 详情

STM32驱动PCF8563,使用模拟IIC

发布时间:2020-05-22 发布时间:
|

#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 


『本文转载自网络,版权归原作者所有,如有侵权请联系删除』

热门文章 更多
ARM 汇编的必知必会