#include "SOE.h" #include "stdio.h" #include "parameter.h" #include "FM_RTC.h" #include "flash.h" #include "capture.h" #define eventsOrderRecordStartAddr 4096 typedef struct _soeDataInfo { uint16_t mode; //故障类型 2byte timeInfo time; //时间 6byte float temp; //故障发生时刻的值 4byte } soeDataInfo; #define soeDataInfoSize sizeof(soeDataInfo) typedef struct _soeSaveInfo { soeDataInfo data[5]; uint8_t insertPos; //记录插入数据的位置 uint8_t outPos; //记录输出数据的位置 uint8_t count; //记录可插入数据插入数据个数 soeDataInfo *insertData; //指向能插入数据的位置 soeDataInfo *outData; //指向能输出数据的位置 } soeSaveInfo; typedef struct _soeStorageParameters { uint16_t len; //soe下次记录距离0的偏移量 uint16_t pos; //下次soe记录的位置 } soeStorageParameters; static soeSaveInfo soeInfo = {0}; static soeStorageParameters soeParameters = {0}; /** * @brief 得到一次时间记录的长度 * @param */ uint16_t getSoeDataInfoSize(void) { return soeDataInfoSize; } /** * @brief 初始化事件顺序记录 * @param */ void eventsOrderRecordStartInit(void) { read_Flash((uint8_t *)(&soeParameters), eventsOrderRecordStartAddr, sizeof(soeParameters)); if (soeParameters.len == 0xFFFF && soeParameters.pos == 0xFFFF) { soeParameters.len = 0; soeParameters.pos = eventsOrderRecordStartAddr + sizeof(soeParameters); write_Flash((uint8_t *)(&soeParameters), eventsOrderRecordStartAddr, sizeof(soeParameters)); } else if (soeParameters.len > 100 || soeParameters.pos != eventsOrderRecordStartAddr + sizeof(soeParameters) + soeParameters.len * soeDataInfoSize) { soeParameters.len = 0; soeParameters.pos = eventsOrderRecordStartAddr + sizeof(soeParameters); write_Flash((uint8_t *)(&soeParameters), eventsOrderRecordStartAddr, sizeof(soeParameters)); } soeInfo.count = 5; soeInfo.insertPos = 0; soeInfo.outPos = 0; soeInfo.outData = NULL; soeInfo.insertData = &soeInfo.data[soeInfo.insertPos]; } /** * @brief 插入事件顺序记录 * @param */ /* | 故障类型 | temp | | :-------------------: | :-------: | | firstStageProtection | 输出电流 | | secondStageProtection | 输出电流 | | thirdStageProtection | 输出电流 | | lowInputLoad | 输出电压 | | overTemperature | mos管温度 | | stopTemperature | mos管温度 | | overchargCurr | 充电电流 | | hardwareShortCircuitProtection| 输出电流 | | abnormalControl | 太阳能板输出电压 | */ void insertEventsOrderRecord(eventsOrderRecordMode mode) { /* 无位置插入时,退出 */ if (soeInfo.count <= 0 || soeInfo.insertData == NULL) { return; } soeInfo.count--; soeInfo.insertData->mode = mode; getRTC_Time(&soeInfo.insertData->time); if (mode == firstStageProtection) { soeInfo.insertData->temp = getDischargCurrent(); } else if (mode == secondStageProtection) { soeInfo.insertData->temp = getDischargCurrent(); } else if (mode == thirdStageProtection) { soeInfo.insertData->temp = getDischargCurrent(); } else if (mode == lowInputLoad) { soeInfo.insertData->temp = getOutputVoltage(); } else if (mode == overTemperature) { soeInfo.insertData->temp = getHighSideMosTemperature(); } else if (mode == stopTemperature) { soeInfo.insertData->temp = getHighSideMosTemperature(); } else if (mode == overchargCurr) { soeInfo.insertData->temp = getChargCurrent(); } else if (mode == overInputVolt) { soeInfo.insertData->temp = getSolarInCircuitVoltage(); } else if (mode == hardwareShortCircuitProtection) { soeInfo.insertData->temp = getDischargCurrent(); } else if (mode == hardwareInputProtection) { soeInfo.insertData->temp = get_EXCHG_CURR(); } else if (mode == InputProtection) { soeInfo.insertData->temp = get_EXCHG_CURR(); } else if (mode == startEvent) { soeInfo.insertData->temp = 0; } else if (mode == abnormalControl) { soeInfo.insertData->temp = getSolarInCircuitVoltage(); } else { soeInfo.count++; return; } soeInfo.insertPos++; if (soeInfo.insertPos >= 5) { soeInfo.insertPos = 0; } if (soeInfo.count <= 0) { soeInfo.insertData = NULL; } else { soeInfo.insertData = &soeInfo.data[soeInfo.insertPos]; } soeInfo.outData = &soeInfo.data[soeInfo.outPos]; } /** * @brief 将事件顺序记录在flash中 * @param */ void setEventsOrderRecord(void) { if (soeInfo.outData == NULL || soeInfo.count >= 5) { return; } write_Flash((uint8_t *)(soeInfo.outData), soeParameters.pos, soeDataInfoSize); // read_Flash((uint8_t *)(soeInfo.outData), eventsOrderRecordStartAddr, sizeof(soeStorageParameters)); // debug_printf("mode = %d \n", soeInfo.outData->mode); // debug_printf("year = %d \n", soeInfo.outData->time.year); // debug_printf("month = %d \n", soeInfo.outData->time.month); // debug_printf("day = %d \n", soeInfo.outData->time.day); // debug_printf("hour = %d \n", soeInfo.outData->time.hour); // debug_printf("minute = %d \n", soeInfo.outData->time.minute); // debug_printf("second = %d \n", soeInfo.outData->time.second); soeParameters.len++; if (soeParameters.len >= 100) { soeParameters.len = 0; } soeParameters.pos += soeDataInfoSize; write_Flash((uint8_t *)(&soeParameters), eventsOrderRecordStartAddr, sizeof(soeStorageParameters)); soeInfo.outPos++; if (soeInfo.outPos >= 5) { soeInfo.outPos = 0; } soeInfo.count++; if (soeInfo.count >= 5) { soeInfo.outData = NULL; } else { soeInfo.outData = &soeInfo.data[soeInfo.outPos]; } if (soeInfo.insertData == NULL) { soeInfo.insertData = &soeInfo.data[soeInfo.insertPos]; } } /** * @brief 将事件从flash中依次读取出来 * @param offset : 距离下次写入数据的偏移量 * *data : 数据的储存位置 */ void readEventsOrderRecord(uint16_t offset, uint8_t *data) { uint16_t addr; if (soeParameters.len - offset < 0) { addr = eventsOrderRecordStartAddr + sizeof(soeStorageParameters) + (100 + soeParameters.len - offset) * soeDataInfoSize; } else { addr = eventsOrderRecordStartAddr + sizeof(soeStorageParameters) + (soeParameters.len - offset) * soeDataInfoSize; } read_Flash(data, addr, soeDataInfoSize); } /** * @brief 清除SOE所有事件 * @param */ void cleanEventsOrderRecord(void) { erase_Sector_Flash((eventsOrderRecordStartAddr / 4096)); soeParameters.len = 0; soeParameters.pos = eventsOrderRecordStartAddr + sizeof(soeParameters); write_Flash((uint8_t *)(&soeParameters), eventsOrderRecordStartAddr, sizeof(soeParameters)); }