//******************************************************************** // Ver 1.0 // 2021.11.19 1、新建文件。 //******************************************************************** #include "config.h" I2C_Str I2CS_Info; //清除使用静态变量的指针警告信息 #if defined(__CC_ARM) // Suppress warning message: extended constant initialiser used #pragma diag_suppress 1296 #elif defined(__ICCARM__) #elif defined(__GNUC__) #endif __FLASH INT32U I2CS_GpioTab[]={ (INT32U)GPIOB, GPIO_Pin_8, //SCL0 (INT32U)GPIOB, GPIO_Pin_9, //SDA0 (INT32U)GPIOB, GPIO_Pin_13, //SCL1 (INT32U)GPIOB, GPIO_Pin_14, //SDA1 }; void I2CS_PinWrite(INT8U I2Cx, INT8U PINx, INT8U Value) { ATOMIC_Start(); GPIO_WritePin((GPIO_TypeDef *)I2CS_GpioTab[I2Cx*4+PINx*2], (uint16_t)I2CS_GpioTab[I2Cx*4+PINx*2+1], Value); I2CS_BitsDelay(); ATOMIC_Stop(); } INT8U I2CS_PinRead(INT8U I2Cx, INT8U PINx) { //I2CS_BitsDelay(); return(GPIO_ReadPin((GPIO_TypeDef *)I2CS_GpioTab[I2Cx*4+PINx*2], (uint16_t)I2CS_GpioTab[I2Cx*4+PINx*2+1])); } void I2CS_Start(INT8U I2Cx) { I2CS_PinWrite(I2Cx, I2CS_SCL, 1); //SCL=1 I2CS_PinWrite(I2Cx, I2CS_SDA, 1); //SDA=1 I2CS_PinWrite(I2Cx, I2CS_SDA, 0); //SDA=0 I2CS_PinWrite(I2Cx, I2CS_SCL, 0); //SCL=0 } void I2CS_ReStart(INT8U I2Cx) { I2CS_PinWrite(I2Cx, I2CS_SDA, 1); //SDA=1 I2CS_PinWrite(I2Cx, I2CS_SCL, 1); //SCL=1 I2CS_PinWrite(I2Cx, I2CS_SDA, 0); //SDA=0 I2CS_PinWrite(I2Cx, I2CS_SCL, 0); //SCL=0 } void I2CS_Stop(INT8U I2Cx) { I2CS_PinWrite(I2Cx, I2CS_SDA, 0); //SDA=0 I2CS_PinWrite(I2Cx, I2CS_SCL, 0); //SCL=0 I2CS_PinWrite(I2Cx, I2CS_SCL, 1); //SCL=1 if(I2CS_PinRead(I2Cx, I2CS_SCL) == 0) //检测SCL未释放的情况 { I2CS_BitsDelay(); } I2CS_PinWrite(I2Cx, I2CS_SDA, 1); //SDA=1 } void I2CS_WriteByte(INT8U I2Cx, INT8U Value) { INT8U i; for (i=0; i<8; i++) { if (Value & 0x80) { I2CS_PinWrite(I2Cx, I2CS_SDA, 1); //SDA=1 } else { I2CS_PinWrite(I2Cx, I2CS_SDA, 0); //SDA=0 } Value<<=1; I2CS_PinWrite(I2Cx, I2CS_SCL, 1); //SCL=1 if(I2CS_PinRead(I2Cx, I2CS_SCL) == 0) //检测SCL未释放的情况 { I2CS_Info.Info[I2Cx].ErrCnt++; } I2CS_PinWrite(I2Cx, I2CS_SCL, 0); //SCL=0 } } INT8U I2CS_Ack(INT8U I2Cx, INT8U Value) { INT8U i=I2C_SCL_LOW_MAX; I2CS_PinWrite(I2Cx, I2CS_SDA, Value); //SDA=1 I2CS_PinWrite(I2Cx, I2CS_SCL, 1); //SCL=1 while(i--) { I2CS_BitsDelay(); if(I2CS_PinRead(I2Cx, I2CS_SCL) != 0) { break; } } if (I2CS_PinRead(I2Cx, I2CS_SDA) != 0) { I2CS_Info.Info[I2Cx].Ack=1; } else { I2CS_Info.Info[I2Cx].Ack=0; } I2CS_PinWrite(I2Cx, I2CS_SCL, 0); //SCL=0 return(I2CS_Info.Info[I2Cx].Ack); } INT8U I2CS_ReadByte(INT8U I2Cx) { INT8U i=I2C_SCL_LOW_MAX,tValue=0; I2CS_PinWrite(I2Cx, I2CS_SDA, 1); //SDA=1 I2CS_PinWrite(I2Cx, I2CS_SCL, 1); //SCL=1 while(i--) { if(I2CS_PinRead(I2Cx, I2CS_SCL) != 0) { break; } I2CS_BitsDelay(); } for (i=0; i<8; i++) { I2CS_PinWrite(I2Cx, I2CS_SCL, 1); //SCL=1 if(I2CS_PinRead(I2Cx, I2CS_SCL) == 0) //检测SCL未释放的情况 { I2CS_Info.Info[I2Cx].ErrCnt++; } tValue<<=1; if (I2CS_PinRead(I2Cx, I2CS_SDA) != 0) { tValue|=0x01; } I2CS_PinWrite(I2Cx, I2CS_SCL, 0); //SCL=0 } return(tValue); } //Reg: I2C存储地址,15位有效,最高位为 1发送15位地址,最高位为0发送8位地址 INT8U I2CS_ReadMultiByte(INT8U I2Cx, INT8U Addr, INT16U Reg, INT8U *ptr, INT8U Len) { INT8U i; I2CS_Info.Info[I2Cx].SendCnt = 3; while (1) { I2CS_Info.Info[I2Cx].ErrCnt = 0; //ATOMIC_Start(); I2CS_Start(I2Cx); I2CS_WriteByte(I2Cx, Addr); I2CS_Ack(I2Cx, 1); if ((I2CS_Info.Info[I2Cx].Ack == 0) && ((Reg & 0x8000) != 0)) { I2CS_WriteByte(I2Cx, ((INT8U)(Reg >> 8) & 0x7f)); I2CS_Ack(I2Cx, 1); } if (I2CS_Info.Info[I2Cx].Ack == 0) { I2CS_WriteByte(I2Cx, (INT8U)(Reg >> 0)); I2CS_Ack(I2Cx, 1); } if (I2CS_Info.Info[I2Cx].Ack == 0) { I2CS_ReStart(I2Cx); I2CS_WriteByte(I2Cx, Addr | 0x01); I2CS_Ack(I2Cx, 1); } if (I2CS_Info.Info[I2Cx].Ack == 0) { for (i = 0; i < Len; i++) { ptr[i] = I2CS_ReadByte(I2Cx); if (i == (Len - 1)) { I2CS_Ack(I2Cx, 1); I2CS_Info.Info[I2Cx].Ack = 0; } else { I2CS_Ack(I2Cx, 0); } } } I2CS_Stop(I2Cx); //ATOMIC_Stop(); if (((I2CS_Info.Info[I2Cx].Ack == 0) && (I2CS_Info.Info[I2Cx].ErrCnt == 0)) || (I2CS_Info.Info[I2Cx].SendCnt == 0)) { break; } else { I2CS_BytesDelay(); I2CS_Info.Info[I2Cx].SendCnt--; } } return (I2CS_Info.Info[I2Cx].SendCnt); } //Reg: I2C存储地址,15位有效,最高位为 1发送15位地址,最高位为0发送8位地址 INT8U I2CS_WriteMultiByte(INT8U I2Cx,INT8U Addr,INT16U Reg,INT8U *ptr,INT8U Len) { INT8U i; I2CS_Info.Info[I2Cx].SendCnt=3; while (1) { I2CS_Info.Info[I2Cx].ErrCnt=0; //ATOMIC_Start(); I2CS_Start(I2Cx); I2CS_WriteByte(I2Cx, Addr); I2CS_Ack(I2Cx, 1); if ((I2CS_Info.Info[I2Cx].Ack == 0) && ((Reg & 0x8000) != 0)) { I2CS_WriteByte(I2Cx, ((INT8U)(Reg >> 8) & 0x7f)); I2CS_Ack(I2Cx, 1); } if (I2CS_Info.Info[I2Cx].Ack == 0) { I2CS_WriteByte(I2Cx, (INT8U)(Reg >> 0)); I2CS_Ack(I2Cx, 1); } if (I2CS_Info.Info[I2Cx].Ack == 0) { for (i=0; i