#include "eeprom_24c02.h" #define Time_OUT 3000 #define EEPROM_WP_GPIOx GPIOB #define EEPROM_WP_GPIO_PIN_x GPIO_PIN_1 const uint8_t EEPROM_24C02_Flag[2] = {0x55,0xAA}; int8_t AT24C02_OK = ACK_FAIL; I2C_Handle_Struct_t I2C_Handle_EEPROM = {GPIOB, GPIO_PIN_11, GPIOB, GPIO_PIN_10}; //I2C引脚初始化 void EEPROM_24C02_Init(I2C_Handle_Struct_t* I2C_Handle) { //保护 GPIO_InitTypeDef GPIO_InitStruct; GPIO_InitStruct.Pin = EEPROM_WP_GPIO_PIN_x; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM; HAL_GPIO_Init(EEPROM_WP_GPIOx, &GPIO_InitStruct); HAL_GPIO_WritePin(EEPROM_WP_GPIOx, EEPROM_WP_GPIO_PIN_x, GPIO_PIN_SET); I2C_GPIO_Config(I2C_Handle); } //指定地址读取1字节 int8_t EEPROM_24C02_ReadOneByte(I2C_Handle_Struct_t* I2C_Handle, uint8_t ReadAddr, uint8_t *data) //指定地址读取一个字节 { uint16_t Timeout_Cnt = 0; I2C_Start(I2C_Handle); I2C_Write_Byte(I2C_Handle, AT24C02_ADDR_WR); //发送写命令 Timeout_Cnt = 0; do { Timeout_Cnt++; if(Timeout_Cnt>Time_OUT) { return ACK_FAIL; } }while(I2C_Check_Ack(I2C_Handle)); I2C_Write_Byte(I2C_Handle, ReadAddr); Timeout_Cnt = 0; do { Timeout_Cnt++; if(Timeout_Cnt>Time_OUT) { return ACK_FAIL; } }while(I2C_Check_Ack(I2C_Handle)); I2C_Start(I2C_Handle); I2C_Write_Byte(I2C_Handle, AT24C02_ADDR_RD); //发送读命令 Timeout_Cnt = 0; do { Timeout_Cnt++; if(Timeout_Cnt>Time_OUT) { return ACK_FAIL; } }while(I2C_Check_Ack(I2C_Handle)); I2C_Read_Byte(I2C_Handle, data); I2C_Send_Nack(I2C_Handle); I2C_Stop(I2C_Handle); return ACK_OK; } //指定地址写入1字节 int8_t EEPROM_24C02_WriteOneByte(I2C_Handle_Struct_t* I2C_Handle, uint8_t WriteAddr,uint8_t DataToWrite) //指定地址写入一个字节 { uint16_t Timeout_Cnt = 0; HAL_GPIO_WritePin(EEPROM_WP_GPIOx, EEPROM_WP_GPIO_PIN_x, GPIO_PIN_RESET); I2C_Start(I2C_Handle); I2C_Write_Byte(I2C_Handle, AT24C02_ADDR_WR); //发送写命令 Timeout_Cnt = 0; do { Timeout_Cnt++; if(Timeout_Cnt>Time_OUT) { return ACK_FAIL; } }while(I2C_Check_Ack(I2C_Handle)); I2C_Write_Byte(I2C_Handle, WriteAddr); Timeout_Cnt = 0; do { Timeout_Cnt++; if(Timeout_Cnt>Time_OUT) { return ACK_FAIL; } }while(I2C_Check_Ack(I2C_Handle)); I2C_Write_Byte(I2C_Handle, DataToWrite); Timeout_Cnt = 0; do { Timeout_Cnt++; if(Timeout_Cnt>Time_OUT) { return ACK_FAIL; } }while(I2C_Check_Ack(I2C_Handle)); I2C_Stop(I2C_Handle); HAL_Delay(10); HAL_GPIO_WritePin(EEPROM_WP_GPIOx, EEPROM_WP_GPIO_PIN_x, GPIO_PIN_SET); //看门狗清零 #if DEBUG HAL_IWDG_Refresh(&hiwdg); #endif return ACK_OK; } //指定地址写入有效数据 int8_t SaveParamToEEprom_24C02(I2C_Handle_Struct_t* I2C_Handle, uint8_t AddrBegin, uint8_t DataLen, uint8_t *Data) { uint8_t Temp_8 = 0, i; uint16_t CRC_Result = 0; //按字节存储数据 for(i=0;i> 8); if(EEPROM_24C02_WriteOneByte(I2C_Handle, AddrBegin + DataLen , Temp_8) == ACK_FAIL) { return ACK_FAIL; } Temp_8 = (uint8_t)(CRC_Result & 0xFF); if(EEPROM_24C02_WriteOneByte(I2C_Handle, AddrBegin + DataLen + 1 , Temp_8) == ACK_FAIL) { return ACK_FAIL; } return ACK_OK; } //指定地址读取有效数据 uint8_t EEPROM_ReadDataBuf[256]; int8_t GetParamFromEEprom_24C02(I2C_Handle_Struct_t* I2C_Handle, uint8_t AddrBegin, uint8_t DataLen, uint8_t *Data) { uint8_t i, Temp2_8[2]; uint16_t CRC_Data, CRC_Result; //读取DataLen个字节 for(i=0;i> 8)) == ACK_FAIL)//11ms { EEPROM_24C02_WriteOneByte(I2C_Handle, EEPROM_24C02_ADDR_FLAG + 2, (uint8_t)(CRC_Result >> 8)); } if(EEPROM_24C02_WriteOneByte(I2C_Handle, EEPROM_24C02_ADDR_FLAG + 3, (uint8_t)(CRC_Result & 0xFF)) == ACK_FAIL)//11ms { EEPROM_24C02_WriteOneByte(I2C_Handle, EEPROM_24C02_ADDR_FLAG + 3, (uint8_t)(CRC_Result & 0xFF)); } return ACK_OK; } //从EEPROM读取数据 int8_t CopyDataFromEEpprom_24C02(I2C_Handle_Struct_t* I2C_Handle) { //读出校验码 13ms if(GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_CHECKCODE, sizeof(MC_CheckInfo.CheckCode), MC_CheckInfo.CheckCode) == ACK_FAIL) { GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_CHECKCODE, sizeof(MC_CheckInfo.CheckCode), MC_CheckInfo.CheckCode); } //读出力矩传感器1校正系数 5ms if(GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_TORQUE_1_CAL_K, sizeof(TorqueSensor_1_Param.Torque_Cal_K), &TorqueSensor_1_Param.Torque_Cal_K) == ACK_FAIL) { GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_TORQUE_1_CAL_K, sizeof(TorqueSensor_1_Param.Torque_Cal_K), &TorqueSensor_1_Param.Torque_Cal_K); } //读出力矩传感器1零点偏移 5ms if(GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_TORQUE_OFFSET_1, sizeof(TorqueSensor_1_Param.Torque_OffSetData), (uint8_t*)&TorqueSensor_1_Param.Torque_OffSetData.Data) == ACK_FAIL) { GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_TORQUE_OFFSET_1, sizeof(TorqueSensor_1_Param.Torque_OffSetData), (uint8_t*)&TorqueSensor_1_Param.Torque_OffSetData.Data); } //读出力矩传感器2校正系数 5ms if(GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_TORQUE_2_CAL_K, sizeof(TorqueSensor_2_Param.Torque_Cal_K), &TorqueSensor_2_Param.Torque_Cal_K) == ACK_FAIL) { GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_TORQUE_2_CAL_K, sizeof(TorqueSensor_2_Param.Torque_Cal_K), &TorqueSensor_2_Param.Torque_Cal_K); } //读出力矩传感器2零点偏移 5ms if(GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_TORQUE_OFFSET_2, sizeof(TorqueSensor_2_Param.Torque_OffSetData), (uint8_t*)&TorqueSensor_2_Param.Torque_OffSetData.Data) == ACK_FAIL) { GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_TORQUE_OFFSET_2, sizeof(TorqueSensor_2_Param.Torque_OffSetData), (uint8_t*)&TorqueSensor_2_Param.Torque_OffSetData.Data); } //读出力矩传感器3校正系数 5ms if(GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_TORQUE_3_CAL_K, sizeof(TorqueSensor_3_Param.Torque_Cal_K), &TorqueSensor_3_Param.Torque_Cal_K) == ACK_FAIL) { GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_TORQUE_3_CAL_K, sizeof(TorqueSensor_3_Param.Torque_Cal_K), &TorqueSensor_3_Param.Torque_Cal_K); } //读出力矩传感器3零点偏移 5ms if(GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_TORQUE_OFFSET_3, sizeof(TorqueSensor_3_Param.Torque_OffSetData), (uint8_t*)&TorqueSensor_3_Param.Torque_OffSetData.Data) == ACK_FAIL) { GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_TORQUE_OFFSET_3, sizeof(TorqueSensor_3_Param.Torque_OffSetData), (uint8_t*)&TorqueSensor_3_Param.Torque_OffSetData.Data); } //读出运行历史1 44ms if(GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_RUN_LOG1, sizeof(MC_RunLog1_Struct_t), (uint8_t*)&MC_RunLog1.PowerOnCnt) == ACK_FAIL) { GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_RUN_LOG1, sizeof(MC_RunLog1_Struct_t), (uint8_t*)&MC_RunLog1.PowerOnCnt); } MC_RunLog1.PowerOnCnt++; //写入开机次数 75ms if(SaveParamToEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_RUN_LOG1, sizeof(MC_RunLog1_Struct_t), (uint8_t*)&MC_RunLog1.PowerOnCnt) == ACK_FAIL) { SaveParamToEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_RUN_LOG1, sizeof(MC_RunLog1_Struct_t), (uint8_t*)&MC_RunLog1.PowerOnCnt); } //读出运行历史2 if(GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_RUN_LOG2, sizeof(MC_RunLog2_Struct_t), (uint8_t*)&MC_RunLog2.MCU_FaultCnt) == ACK_FAIL) { GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_RUN_LOG2, sizeof(MC_RunLog2_Struct_t), (uint8_t*)&MC_RunLog2.MCU_FaultCnt); } //读取骑行历史信息 if(GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_RIDE_LOG, sizeof(MC_RideLog_Struct_t), (uint8_t*)&MC_RideLog.ODO_Km) == ACK_FAIL) { GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_RIDE_LOG, sizeof(MC_RideLog_Struct_t), (uint8_t*)&MC_RideLog.ODO_Km); } //读出密钥 11ms if(GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_SECRET_KEY, sizeof(Secret_Key), Secret_Key) == ACK_FAIL) { GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_SECRET_KEY, sizeof(Secret_Key), Secret_Key); } //读取平均功耗 16ms if(GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_AVG_POWER, sizeof(MC_AvgPower_Struct_t), (uint8_t*)&MC_AvgPower.GearSt_ECO) == ACK_FAIL) { GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_AVG_POWER, sizeof(MC_AvgPower_Struct_t), (uint8_t*)&MC_AvgPower.GearSt_ECO); } //读取启动值 if(GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_TORQUE_STARDATA, sizeof(TorqueSensorStartData), (uint8_t*)&TorqueSensorStartData) == ACK_FAIL) { GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_TORQUE_STARDATA, sizeof(TorqueSensorStartData), (uint8_t*)&TorqueSensorStartData); } return ACK_OK; } //EEPROM_24C02检测 int8_t EEPROM_24C02_Check(I2C_Handle_Struct_t* I2C_Handle) { uint8_t Temp_8[2] = {0}; uint16_t FlagCRC, FlagCRC_Result; //读取存储标志并计算校验码 EEPROM_24C02_ReadOneByte(I2C_Handle, EEPROM_24C02_ADDR_FLAG, Temp_8);//1ms EEPROM_24C02_ReadOneByte(I2C_Handle, EEPROM_24C02_ADDR_FLAG + 1, (Temp_8 + 1));//1ms FlagCRC_Result = CRC16_Xmodem(Temp_8, 2); //读取存储的校验码 EEPROM_24C02_ReadOneByte(I2C_Handle, EEPROM_24C02_ADDR_FLAG + 2, Temp_8); EEPROM_24C02_ReadOneByte(I2C_Handle, EEPROM_24C02_ADDR_FLAG + 3, (Temp_8 + 1)); FlagCRC = ((uint16_t)Temp_8[0] << 8) + Temp_8[1]; //判断数据是否有效 if((FlagCRC - FlagCRC_Result) == 0) // 数据有效 { return(CopyDataFromEEpprom_24C02(I2C_Handle)); } else // 数据无效,写入默认参数 { return(CopyDefaultDataToEEpprom_24C02(I2C_Handle)); } } //清除指定区间段有效数据 void EEPROM_24C02_ClearData(I2C_Handle_Struct_t* I2C_Handle, uint8_t AddrBegin, uint8_t EndAddr, uint8_t Data) { uint8_t i, Length; Length = EndAddr - AddrBegin; for(i=0; i