#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; } //指定地址读取有效数据 int8_t GetParamFromEEprom_24C02(I2C_Handle_Struct_t* I2C_Handle, uint8_t AddrBegin, uint8_t DataLen, uint8_t *Data) { uint8_t Temp1_8[256], i, Temp2_8[2]; uint16_t CRC_Data, CRC_Result; //读取DataLen个字节 for(i=0;i> 8)) == ACK_FAIL) { return ACK_FAIL; } if(EEPROM_24C02_WriteOneByte(I2C_Handle, EEPROM_24C02_ADDR_FLAG + 3, (uint8_t)(CRC_Result & 0xFF)) == ACK_FAIL) { return ACK_FAIL; } return ACK_OK; } //从EEPROM读取数据 int8_t CopyDataFromEEpprom_24C02(I2C_Handle_Struct_t* I2C_Handle) { //读出校验码 if(GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_CHECKCODE, sizeof(MC_CheckInfo.CheckCode), MC_CheckInfo.CheckCode) == ACK_FAIL) { return ACK_FAIL; } //读出配置参数 if(GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_CONFIG_PARAM, sizeof(MC_ConfigParam_Struct_t), &MC_ConfigParam.RS1) == ACK_FAIL) { return ACK_FAIL; } //读出力矩传感器校正信息 if(GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_TORQUE_PARAM, sizeof(MC_TorqueCorrectParam_Struct_t), (uint8_t*)&MC_TorqueCorrectParam.StarData) == ACK_FAIL) { return ACK_FAIL; } //读出马达参数 if(GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_MOTOR_PARAM, sizeof(MC_MotorParam_Struct_t), (uint8_t*)&MC_MotorParam.Rate_Power) == ACK_FAIL) { return ACK_FAIL; } //读出运行历史 if(GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_RUN_LOG, sizeof(MC_RunLog_Struct_t), (uint8_t*)&MC_RunLog.PowerOnCnt) == ACK_FAIL) { return ACK_FAIL; } MC_RunLog.PowerOnCnt++; //写入开机次数 if(SaveParamToEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_RUN_LOG, sizeof(MC_RunLog_Struct_t), (uint8_t*)&MC_RunLog.PowerOnCnt) == ACK_FAIL) { return ACK_FAIL; } MC_RunInfo.ODO_Km = (uint16_t)MC_RunLog.ODO_Km / 10; MC_RunInfo.ODO_Time = MC_RunLog.ODO_Time; //读出力矩传感器零点偏移值 if(GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_TORQUE_OFFSET, sizeof(TorqueOffSetData_Struct_t), (uint8_t*)&TorqueOffSetData.Data[0])) { return ACK_FAIL; } //读出密钥 if(GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_SECRET_KEY, sizeof(Secret_Key), Secret_Key) == ACK_FAIL) { return ACK_FAIL; } //读取平均功耗 if(GetParamFromEEprom_24C02(I2C_Handle, EEPROM_24C02_ADDR_AVG_POWER, sizeof(MC_AvgPower_Struct_t), (uint8_t*)&MC_AvgPower.GearSt_ECO) == ACK_FAIL) { return ACK_FAIL; } 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); EEPROM_24C02_ReadOneByte(I2C_Handle, EEPROM_24C02_ADDR_FLAG + 1, (Temp_8 + 1)); 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