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