/** ****************************************************************************** * @file Screen.c * @author * @version * @date * @brief ****************************************************************************** * @attention * * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "stm32f10x.h" #include "global.h" #include "rtc.h" #include "soe.h" #include "string.h" #include #include //通用定义 #define SCR_UART USART2 #define SCR_Send USART2_printf #define SCR_MON_CNT 6000 //6000*10ms = 60s #define SCR_RX_BUF_LEN 128 //接收的最大长度 #define SCR_TX_BUF_LEN 128 //发送的最大长度 char SCR_Rx_Buf[SCR_RX_BUF_LEN]; char SCR_Tx_Buf[SCR_TX_BUF_LEN]; uint16_t SCR_Rx_BufIndex; uint16_t SCR_Moni_Count; uint8_t read_index; uint8_t recordBuf[64]; char sendRecord[64]; uint8_t scrBufIndex; uint8_t scrMoniCount; uint8_t scrRecvFlag; uint8_t initFlag; //初始化配置参数 uint8_t clearFlag; //删除记录成功标志(已存在) uint8_t clearFlag_timer; //成功图标保持计时(秒) uint8_t EE_clearFlag; //特殊按钮,点按清空EEPROM //休眠(屏幕自己做) char SCR_sleepOn[] = {0x86,0xFF,0xFF,0xFF}; //屏幕休眠 char SCR_sleepOff[] = {0x87,0xFF,0xFF,0xFF}; //屏幕退出休眠 //分配地址勾选 char SCR_setADDR[] = {0x65,0x0E,0x07,0x01,0xFF,0xFF,0xFF}; //强制开启放电 char SCR_ForceDischarge[] = {0x65, 0x0C, 0x01, 0x01, 0xFF, 0xFF, 0xFF}; // 出厂设置键值 char SCR_FactoryReset[] = {0x65, 0x0D, 0x01, 0x01, 0xFF, 0xFF, 0xFF}; //遮挡历史 char SCR_Hide_History[] = {0x65,0x01,0x10,0x01,0xFF,0xFF,0xFF};//按下历史按键 char SCR_up_History[] = {0x65,0x11,0x0A,0x01,0xFF,0xFF,0xFF};//上翻页 char SCR_down_History[] = {0x65,0x11,0x0B,0x01,0xFF,0xFF,0xFF};//下翻页 char SCR_clean_History[]= {0x65,0x11,0x0C,0x01,0xFF,0xFF,0xFF};//删除历史记录 //并机按键键值 char SCR_Parallel[] = {0x65,0x01,0x11,0x01,0xFF,0xFF,0xFF}; //电池页跳转汇总数据页图标键值 char SCR_Allpack[] = {0x65,0x13,0x0A,0x01,0xFF,0xFF,0xFF}; //汇总数据页返回电池页图标键值 char SCR_Allcell[] = {0x65,0x12,0x11,0x01,0xFF,0xFF,0xFF}; //告警页返回键值 char SCR_Protect[] = {0x65,0x04,0x0C,0x01,0xFF,0xFF,0xFF}; //屏幕休眠唤醒键值 char SCR_Sleep[] = {0x87,0xFF,0xFF,0xFF}; //PACK页-单个电池图标 char SCR_PACK1[] = {0x65,0x12,0x01,0x01,0xFF,0xFF,0xFF}; char SCR_PACK2[] = {0x65,0x12,0x02,0x01,0xFF,0xFF,0xFF}; char SCR_PACK3[] = {0x65,0x12,0x03,0x01,0xFF,0xFF,0xFF}; char SCR_PACK4[] = {0x65,0x12,0x04,0x01,0xFF,0xFF,0xFF}; char SCR_PACK5[] = {0x65,0x12,0x05,0x01,0xFF,0xFF,0xFF}; char SCR_PACK6[] = {0x65,0x12,0x06,0x01,0xFF,0xFF,0xFF}; char SCR_PACK7[] = {0x65,0x12,0x07,0x01,0xFF,0xFF,0xFF}; char SCR_PACK8[] = {0x65,0x12,0x08,0x01,0xFF,0xFF,0xFF}; char SCR_PACK9[] = {0x65,0x12,0x09,0x01,0xFF,0xFF,0xFF}; char SCR_PACK10[] = {0x65,0x12,0x0A,0x01,0xFF,0xFF,0xFF}; char SCR_PACK11[] = {0x65,0x12,0x0B,0x01,0xFF,0xFF,0xFF}; char SCR_PACK12[] = {0x65,0x12,0x0C,0x01,0xFF,0xFF,0xFF}; char SCR_PACK13[] = {0x65,0x12,0x0D,0x01,0xFF,0xFF,0xFF}; char SCR_PACK14[] = {0x65,0x12,0x0E,0x01,0xFF,0xFF,0xFF}; char SCR_PACK15[] = {0x65,0x12,0x0F,0x01,0xFF,0xFF,0xFF}; char SCR_PACK16[] = {0x65,0x12,0x10,0x01,0xFF,0xFF,0xFF}; //选择协议 char SCR_setProtocol_SolArk[] = {0x65,0x06,0x0D,0x01,0xFF,0xFF,0xFF}; char SCR_setProtocol_GoodWe[] = {0x65,0x06,0x0E,0x01,0xFF,0xFF,0xFF}; char SCR_setProtocol_Megarevo[] = {0x65,0x06,0x0F,0x01,0xFF,0xFF,0xFF}; char SCR_setProtocol_Pylon[] = {0x65,0x06,0x10,0x01,0xFF,0xFF,0xFF}; char SCR_setProtocol_Deye[] = {0x65,0x06,0x11,0x01,0xFF,0xFF,0xFF}; char SCR_setProtocol_MUST[] = {0x65,0x06,0x12,0x01,0xFF,0xFF,0xFF}; char SCR_setProtocol_Solis[] = {0x65,0x06,0x13,0x01,0xFF,0xFF,0xFF}; char SCR_setProtocol_Growatt[] = {0x65,0x06,0x14,0x01,0xFF,0xFF,0xFF}; char SCR_setProtocol_Aiswei[] = {0x65,0x06,0x15,0x01,0xFF,0xFF,0xFF}; char SCR_setProtocol_Afore[] = {0x65,0x06,0x16,0x01,0xFF,0xFF,0xFF}; char SCR_setProtocol_Victron[] = {0x65,0x06,0x17,0x01,0xFF,0xFF,0xFF}; char SCR_setProtocol_Sorotec[] = {0x65,0x06,0x18,0x01,0xFF,0xFF,0xFF}; char SCR_setProtocol_SMA[] = {0x65,0x07,0x0D,0x01,0xFF,0xFF,0xFF}; char SCR_setProtocol_Sunways[] = {0x65,0x07,0x0E,0x01,0xFF,0xFF,0xFF}; char SCR_setProtocol_Luxpower[] = {0x65,0x07,0x0F,0x01,0xFF,0xFF,0xFF}; char SCR_setProtocol_Schneider[] = {0x65,0x07,0x10,0x01,0xFF,0xFF,0xFF}; char SCR_setProtocol_AlpSolarr[] = {0x65,0x07,0x11,0x01,0xFF,0xFF,0xFF}; char SCR_setProtocol_SRNE[] = {0x65,0x07,0x12,0x01,0xFF,0xFF,0xFF}; char SCR_setProtocol_Voltronic[] = {0x65,0x07,0x13,0x01,0xFF,0xFF,0xFF}; char SCR_setProtocol_COSUPER[] = {0x65,0x07,0x14,0x01,0xFF,0xFF,0xFF}; char SCR_setProtocol_SMK[] = {0x65,0x07,0x15,0x01,0xFF,0xFF,0xFF}; char SCR_setProtocol_SAKO[] = {0x65,0x07,0x16,0x01,0xFF,0xFF,0xFF}; char SCR_setProtocol_SNADI[] = {0x65,0x07,0x17,0x01,0xFF,0xFF,0xFF}; char SCR_setProtocol_invt[] = {0x65,0x07,0x18,0x01,0xFF,0xFF,0xFF}; char SCR_altProtocol_1[] = {0x65,0x08,0x03,0x01,0xFF,0xFF,0xFF}; char SCR_altProtocol_2[] = {0x65,0x08,0x04,0x01,0xFF,0xFF,0xFF}; //短路保护电压 char SCR_setSCVol_0[] = {0x65,0x15,0x02,0x01,0xFF,0xFF,0xFF}; //设短路电压 page21 b1 50mV char SCR_setSCVol_1[] = {0x65,0x15,0x03,0x01,0xFF,0xFF,0xFF}; //设短路电压 page21 b2 80mV char SCR_setSCVol_2[] = {0x65,0x15,0x04,0x01,0xFF,0xFF,0xFF}; //设短路电压 page21 b3 110mV char SCR_setSCVol_3[] = {0x65,0x15,0x05,0x01,0xFF,0xFF,0xFF}; //设短路电压 page21 b4 140mV char SCR_setSCVol_4[] = {0x65,0x15,0x06,0x01,0xFF,0xFF,0xFF}; //设短路电压 page21 b5 170mV char SCR_setSCVol_5[] = {0x65,0x15,0x07,0x01,0xFF,0xFF,0xFF}; //设短路电压 page21 b6 200mV char SCR_setSCVol_6[] = {0x65,0x15,0x08,0x01,0xFF,0xFF,0xFF}; //设短路电压 page21 b7 230mV char SCR_setSCVol_7[] = {0x65,0x15,0x09,0x01,0xFF,0xFF,0xFF}; //设短路电压 page21 b8 260mV char SCR_setSCVol_8[] = {0x65,0x15,0x0A,0x01,0xFF,0xFF,0xFF}; //设短路电压 page21 b9 290mV char SCR_setSCVol_9[] = {0x65,0x15,0x0B,0x01,0xFF,0xFF,0xFF}; //设短路电压 page21 b10 320mV char SCR_setSCVol_10[] = {0x65,0x15,0x0C,0x01,0xFF,0xFF,0xFF}; //设短路电压 page21 b11 350mV char SCR_setSCVol_11[] = {0x65,0x15,0x0D,0x01,0xFF,0xFF,0xFF}; //设短路电压 page21 b12 400mV //短路保护延时 char SCR_setSCTim_0[] = {0x65,0x16,0x02,0x01,0xFF,0xFF,0xFF}; //设短路延时 page22 b1 0uS char SCR_setSCTim_1[] = {0x65,0x16,0x03,0x01,0xFF,0xFF,0xFF}; //设短路延时 page22 b2 64uS char SCR_setSCTim_2[] = {0x65,0x16,0x04,0x01,0xFF,0xFF,0xFF}; //设短路延时 page22 b3 128uS char SCR_setSCTim_3[] = {0x65,0x16,0x05,0x01,0xFF,0xFF,0xFF}; //设短路延时 page22 b4 192uS char SCR_setSCTim_4[] = {0x65,0x16,0x06,0x01,0xFF,0xFF,0xFF}; //设短路延时 page22 b5 256uS char SCR_setSCTim_5[] = {0x65,0x16,0x07,0x01,0xFF,0xFF,0xFF}; //设短路延时 page22 b6 320uS char SCR_setSCTim_6[] = {0x65,0x16,0x08,0x01,0xFF,0xFF,0xFF}; //设短路延时 page22 b7 348uS char SCR_setSCTim_7[] = {0x65,0x16,0x09,0x01,0xFF,0xFF,0xFF}; //设短路延时 page22 b8 448uS char SCR_setSCTim_8[] = {0x65,0x16,0x0A,0x01,0xFF,0xFF,0xFF}; //设短路延时 page22 b9 512uS char SCR_setSCTim_9[] = {0x65,0x16,0x0B,0x01,0xFF,0xFF,0xFF}; //设短路延时 page22 b10 576uS char SCR_setSCTim_10[] = {0x65,0x16,0x0C,0x01,0xFF,0xFF,0xFF}; //设短路延时 page22 b11 640uS char SCR_setSCTim_11[] = {0x65,0x16,0x0D,0x01,0xFF,0xFF,0xFF}; //设短路延时 page22 b12 704uS //参数(字符串) //逆变器设置 //逆变器充电限流 page9 t1 id1 (输入100后会发送39 2C 31 2C 31 30 30 04 FF FF FF //9,1,100页面9,ID1,100) //逆变器充电限压 page9 t2 id2 //逆变器放电限流 page9 t3 id3 //逆变器放电限压 page9 t4 id4 //BMS设置 //充电过流保护值 page9 t5 id5 //放电过流保护值 page9 t6 id6 //充电高温保护值 page10 t1 id1 //充电高温释放值 page10 t2 id2 //充电低温保护值 page10 t3 id3 //充电低温保护值 page10 t4 id4 //放电高温保护值 page10 t5 id5 //放电高温释放值 page10 t6 id6 //放电低温保护值 page10 t7 id7 //放电低温保护值 page10 t8 id8 //充电过压保护值 page11 t1 id1 //充电过压释放值 page11 t2 id2 //充电欠压保护值 page11 t3 id3 //充电欠压释放值 page11 t4 id4 uint8_t flashUpdateFlag; //按钮反馈,会显示1秒的正在设置 1:只显示 2:显示并且将配置写入Flash uint8_t SCR_setProFlag; //协议按钮反馈,1:按下,0:未按下 uint8_t SCR_setADDRFlag; //分配地址按下标志 uint8_t SCR_HistoryFlag; //遮挡历史按下标志 uint8_t SCR_ParallelFlag;//并机按键按下标志 uint8_t SCR_PACKFlag; //并机页电池图标按下标志 // 强制放电状态 uint8_t force_discharge_flag; // 0=空闲, 1=启动中, 2=倒计时中 //出厂设置标志 uint8_t factory_reset_flag; // 0=空闲, 1=执行中, 2=完成 uint8_t SCR_show[2]; //出现多个保护,轮流显示 1.欠压保护 2.低SOC保护 uint8_t SCR_showIdx; //当前要显示保护的序号 uint8_t SCR_showNum; //总个数 uint8_t SCR_showNum_old; //比较总个数,不同时清零序号 uint8_t protocol; //逆变器通信协议 //屏幕显示数据的地址,默认是自身地址,且只有addr=1可以变化该地址 uint8_t scr_RdData_Index;//屏幕显示数据的地址,默认是自身地址,且只有addr=1可以变化该地址 uint8_t scr_RdRecord_Flg;//屏幕只可以查看自身记录;当记录更新/清空/收到清空指令/进记录页面/上下翻动时,才会读EEPROM更新一次屏幕记录内容 uint8_t bAlarmFlagOld_slave; //主机屏幕显示从机报警的跳转 uint8_t scr_WrZero_Flg; //屏幕写零点校准 uint8_t scr_WrGain_Flg; //屏幕写增益校准 uint8_t LTEStatus_flg; //要传状态的标志 char LTEStatus_str[41]; //4G状态文本 //USART2专用的printf函数(疑问:LW发送内容较多,未使用中断发送,是否影响系统实时性?) int USART2_printf(const char *fmt, ...) { va_list args; va_start(args, fmt); int len = vsnprintf(SCR_Tx_Buf, sizeof(SCR_Tx_Buf), fmt, args); va_end(args); for(int i = 0; i < len; i++) { while(!(USART2->SR & USART_SR_TXE)); // 等待发送完成 USART2->DR = SCR_Tx_Buf[i]; } return len; } //清空标志 void Screen_ClearFlg(void) { } //清空接收缓冲区 void Screen_ClearBuf(void) { SCR_Rx_BufIndex = 0; memset(SCR_Rx_Buf, 0, SCR_RX_BUF_LEN); } //初始化屏幕通讯 void Screen_Init(void) { Screen_ClearFlg(); Screen_ClearBuf(); SCR_Moni_Count = SCR_MON_CNT; uf_UART2_Init(115200); //SCR_DispProcotol(); } //一定时间没有接收到数据,初始化屏幕通讯 void Screen_TIM_Moni(void) { SCR_Moni_Count--; if(SCR_Moni_Count == 0) { Screen_Init(); } } //UART中断接收数据 void Screen_IT_Receive(void) { //接收数据 uint8_t received_byte = USART_ReceiveData(SCR_UART); //防止数组溢出 if(SCR_Rx_BufIndex < SCR_RX_BUF_LEN - 1) { SCR_Rx_Buf[SCR_Rx_BufIndex] = received_byte; SCR_Rx_BufIndex++; } else { Screen_ClearBuf(); } //更新计时 SCR_Moni_Count = SCR_MON_CNT; } //寻找指令对应的接收内容,可用二进制格式 //可能出现在任意位置 uint8_t findHexStr(const char *buf, uint16_t buf_len, const char *cmd, uint16_t cmd_len) { uint16_t i; for(i=0;i0:00 void SCR_Send_TimeCount(uint16_t countdown) { uint8_t min = countdown / 60; uint8_t sec = countdown % 60; SCR_Send("page12.t1.txt=\"%02d:%02d\"\xff\xff\xff", min, sec); } //文本传输:2023-08-07 14:00:00 void SCR_Send_Time(void) { char time_str[20]; sprintf(time_str, "20%02x/%02x/%02x %02x:%02x:%02x", calendar.w_year, calendar.w_month, calendar.w_date, calendar.hour, calendar.min, calendar.sec); SCR_Send("page19.t9.txt=\"%s\"\xff\xff\xff", time_str); } /**报警记录的显示**/ void SCR_Send_RecordTime(uint8_t row) { char time_str[20]; sprintf(time_str, "20%02x/%02x/%02x %02x:%02x:%02x", recordBuf[4], recordBuf[5], recordBuf[6], recordBuf[7], recordBuf[8], recordBuf[9]); if(row == 0) { SCR_Send("page17.t6.txt=\"%s\"\xff\xff\xff", time_str); } else if(row == 1) { SCR_Send("page17.t8.txt=\"%s\"\xff\xff\xff", time_str); } else if(row == 2) { SCR_Send("page17.t10.txt=\"%s\"\xff\xff\xff", time_str); } } void Set_Row_Hide(uint8_t row, uint8_t hide) { if(row == 0) SCR_Send("page17.p2.pic=%d\xff\xff\xff", hide ? 151 : 154); else if(row == 1) SCR_Send("page17.p3.pic=%d\xff\xff\xff", hide ? 151 : 154); else if(row == 2) SCR_Send("page17.p4.pic=%d\xff\xff\xff", hide ? 151 : 154); } void Send_Record_Blank(uint8_t row) { // 设置遮挡 (1=遮挡) Set_Row_Hide(row, 1); // 清空时间和报警文本 if(row == 0) { SCR_Send("page17.t6.txt=\" \"\xff\xff\xff"); SCR_Send("page17.t7.txt=\" \"\xff\xff\xff"); SCR_Send("page17.t3.txt=\" \"\xff\xff\xff"); // 序号也清空 } else if(row == 1) { SCR_Send("page17.t8.txt=\" \"\xff\xff\xff"); SCR_Send("page17.t9.txt=\" \"\xff\xff\xff"); SCR_Send("page17.t4.txt=\" \"\xff\xff\xff"); } else if(row == 2) { SCR_Send("page17.t10.txt=\" \"\xff\xff\xff"); SCR_Send("page17.t11.txt=\" \"\xff\xff\xff"); SCR_Send("page17.t5.txt=\" \"\xff\xff\xff"); } } void SCR_Send_Record(uint8_t row) { uint16_t bStatus1; uint16_t bStatus2; uint16_t bStatus3; uint16_t temperaStatus; char *p = sendRecord; uint8_t cnt = 0; // 清空发送缓冲区 memset(sendRecord, 0, sizeof(sendRecord)); // 判断新旧格式 if((recordBuf[50] == 0x05) && (recordBuf[51] == 0xA5)) { // 旧格式 bStatus1 = recordBuf[44]; bStatus2 = recordBuf[45]; bStatus3 = recordBuf[46]; temperaStatus = recordBuf[47]; } else { // 新格式 bStatus1 = (recordBuf[15] & 0xf0) << 4 | recordBuf[10]; bStatus2 = recordBuf[11]; bStatus3 = recordBuf[12]; temperaStatus = (recordBuf[15] & 0x0f) << 8 | recordBuf[13]; } //电压 if(bStatus1 & 0x0100) { memcpy(p, "Pack_OV ", 8); p += 8; cnt += 8; } if(bStatus1 & 0x0200) { memcpy(p, "Pack_UV ", 8); p += 8; cnt += 8; } if(bStatus1 & 0x0001) { memcpy(p, "OV ", 3); p += 3; cnt += 3; } if(bStatus1 & 0x0002) { memcpy(p, "UV ", 3); p += 3; cnt += 3; } if(bStatus1 & 0x0040) { memcpy(p, "PF ", 3); p += 3; cnt += 3; } if(bStatus3 & 0x0008) { memcpy(p, "L0V ", 4); p += 4; cnt += 4; } //电流 if((bStatus1 & 0x0010) || (temperaStatus & 0x0010)) { memcpy(p, "OCC ", 4); p += 4; cnt += 4; } if((bStatus1 & 0x042C) || (temperaStatus & 0x0020)) { memcpy(p, "OCD ", 4); p += 4; cnt += 4; } if(bStatus1 & 0x0020) { memcpy(p, "SC ", 3); p += 3; cnt += 3; } if(bStatus2 & 0x0010) { memcpy(p, "SC_Lock ", 8); p += 8; cnt += 8; } //温度 if((bStatus2 & 0x0001) || (temperaStatus & 0x0404)) { memcpy(p, "UTC ", 4); p += 4; cnt += 4; } if((bStatus2 & 0x0002) || (temperaStatus & 0x0101)) { memcpy(p, "OTC ", 4); p += 4; cnt += 4; } if((bStatus2 & 0x0004) || (temperaStatus & 0x0808)) { memcpy(p, "UTD ", 4); p += 4; cnt += 4; } if((bStatus2 & 0x0008) || (temperaStatus & 0x0202)) { memcpy(p, "OTD ", 4); p += 4; cnt += 4; } //故障 if(temperaStatus & 0x0040) { memcpy(p, "RPSD_Activated ", 15); p += 15; cnt += 15; } if(bStatus2 & 0x0040) { memcpy(p, "D-MOSfault ", 11); p += 11; cnt += 11; } if(bStatus2 & 0x0080) { memcpy(p, "C-MOSfault ", 11); p += 11; cnt += 11; } if(bStatus2 & 0x0020) { memcpy(p, "PCHG_Fail ", 10); p += 10; cnt += 10; } // 保证字符串以空字符结尾 sendRecord[cnt] = '\0'; // 发送到对应的列 if(row == 0) SCR_Send("page17.t7.txt=\"%s\"\xff\xff\xff", sendRecord); else if(row == 1) SCR_Send("page17.t9.txt=\"%s\"\xff\xff\xff", sendRecord); else if(row == 2) SCR_Send("page17.t11.txt=\"%s\"\xff\xff\xff", sendRecord); } /**报警页面的显示**/ //清空报警数据的显示 void SCR_ClearAlarm(void) { SCR_Send("page4.t0.txt=\"%d\"\xff\xff\xff", bmsMem.E2_485Addr); //报警内容显示 //单体过压 SCR_Send("page4.p1.pic=31\xff\xff\xff"); //31为正常 //单体欠压 SCR_Send("page4.p6.pic=41\xff\xff\xff"); //41为正常 //充电过流 SCR_Send("page4.p2.pic=33\xff\xff\xff"); //33为正常 //放电过流 SCR_Send("page4.p7.pic=43\xff\xff\xff"); //43为正常 //充电高温 SCR_Send("page4.p3.pic=35\xff\xff\xff"); //35为正常 //充电低温 SCR_Send("page4.p8.pic=45\xff\xff\xff"); //45为正常 //放电高温 SCR_Send("page4.p4.pic=37\xff\xff\xff"); //37为正常 //放电低温 SCR_Send("page4.p9.pic=47\xff\xff\xff"); //47为正常 //异常高压 SCR_Send("page4.p5.pic=39\xff\xff\xff"); //39为正常 //低压禁止充电 SCR_Send("page4.p10.pic=49\xff\xff\xff"); //49为正常 //短路保护 SCR_Send("page4.p11.pic=51\xff\xff\xff"); //51为正常 } //读取主机的报警数据的显示 void SCR_ShowAlarm(void) { SCR_Send("page4.t0.txt=\"%d\"\xff\xff\xff", bmsMem.E2_485Addr); //报警内容显示 //单体过压 if((bmsMem.bStatus1 & 0x0001) != 0) { if(bmsMem.soc<99) { SCR_Send("page4.p1.pic=32\xff\xff\xff"); //32为触发 } else //当SOC大于99%,此时触发过压报警,不会跳转屏幕,也不会亮报警灯 { SCR_Send("page4.p1.pic=31\xff\xff\xff"); //31为正常 } } //总体过压 else if((bmsMem.bStatus1 & 0x0100) != 0) { if(bmsMem.soc<99) { SCR_Send("page4.p1.pic=158\xff\xff\xff"); //158为触发 } else //当SOC大于99%,此时触发过压报警,不会跳转屏幕,也不会亮报警灯 { SCR_Send("page4.p1.pic=31\xff\xff\xff"); //31为正常 } } else { SCR_Send("page4.p1.pic=31\xff\xff\xff"); //31为正常 } //afe充电过流&充电过流 if(((bmsMem.bStatus1 & 0x0010) != 0) || ((bmsMem.temperaStatus & 0x0010) != 0)) { SCR_Send("page4.p2.pic=34\xff\xff\xff"); //34为触发 } else { SCR_Send("page4.p2.pic=33\xff\xff\xff"); //33为正常 } //afe充电高温&环境充电高温&电芯充电高温 if(((bmsMem.bStatus2 & 0x0002) != 0) || ((bmsMem.temperaStatus & 0x0100) != 0) || ((bmsMem.temperaStatus & 0x0001) != 0)) { SCR_Send("page4.p3.pic=36\xff\xff\xff"); //36为触发 } else { SCR_Send("page4.p3.pic=35\xff\xff\xff"); //35为正常 } //afe放电高温&环境放电高温&电芯放电高温 if(((bmsMem.bStatus2 & 0x0008) != 0) || ((bmsMem.temperaStatus & 0x0200) != 0) || ((bmsMem.temperaStatus & 0x0002) != 0)) { SCR_Send("page4.p4.pic=38\xff\xff\xff"); //38为触发 } else { SCR_Send("page4.p4.pic=37\xff\xff\xff"); //37为正常 } //异常高压 if((bmsMem.bStatus1 & 0x0040) != 0) { SCR_Send("page4.p5.pic=40\xff\xff\xff"); //40为触发 } else { SCR_Send("page4.p5.pic=39\xff\xff\xff"); //39为正常 } //单体欠压 if((bmsMem.bStatus1 & 0x0002) != 0) { SCR_Send("page4.p6.pic=42\xff\xff\xff"); //42为触发 } //总体欠压 else if((bmsMem.bStatus1 & 0x0200) != 0) { SCR_Send("page4.p6.pic=159\xff\xff\xff"); //159为触发 } else { SCR_Send("page4.p6.pic=41\xff\xff\xff"); //41为正常 } //afe放电过流&放电过流1&放电过流2 if(((bmsMem.bStatus1 & 0x000c) != 0) || ((bmsMem.temperaStatus & 0x0020) != 0) || ((bmsMem.bStatus1 & 0x0400) != 0)) { SCR_Send("page4.p7.pic=44\xff\xff\xff"); //44为触发 } else { SCR_Send("page4.p7.pic=43\xff\xff\xff"); //43为正常 } //afe充电低温&环境充电低温&电芯充电低温 if(((bmsMem.bStatus2 & 0x0001) != 0) || ((bmsMem.temperaStatus & 0x0400) != 0) || ((bmsMem.temperaStatus & 0x0004) != 0)) { SCR_Send("page4.p8.pic=46\xff\xff\xff"); //46为触发 } else { SCR_Send("page4.p8.pic=45\xff\xff\xff"); //45为正常 } //afe放电低温&环境放电低温&电芯放电低温 if(((bmsMem.bStatus2 & 0x0004) != 0) || ((bmsMem.temperaStatus & 0x0800) != 0) || ((bmsMem.temperaStatus & 0x0008) != 0)) { SCR_Send("page4.p9.pic=48\xff\xff\xff"); //48为触发 } else { SCR_Send("page4.p9.pic=47\xff\xff\xff"); //47为正常 } //低压禁止充电 if((bmsMem.bStatus3 & 0x0008) != 0) { SCR_Send("page4.p10.pic=50\xff\xff\xff"); //50为触发 } else { SCR_Send("page4.p10.pic=49\xff\xff\xff"); //49为正常 } //真短路保护 if((bmsMem.bStatus2 & 0x0010) != 0) //只有预充情况才会出现短路锁定,出现则一直保持,这里也一直显示 { SCR_Send("page4.p11.pic=52\xff\xff\xff"); //52为触发 } //浪涌短路保护 else if((bmsMem.bStatus1 & 0x0020) != 0) { SCR_Send("page4.p11.pic=52\xff\xff\xff"); //52为触发 } else { SCR_Send("page4.p11.pic=51\xff\xff\xff"); //51为正常 } } //读取从机的报警数据的显示 void SCR_ShowAlarm_Slave(void) { //报警内容显示 //单体过压 if((bmsMem_slave.bStatus1 & 0x0001) != 0) { if(bmsMem_slave.soc<99) { SCR_Send("page4.p1.pic=32\xff\xff\xff"); //32为触发 } else //当SOC大于99%,此时触发过压报警,不会跳转屏幕,也不会亮报警灯 { SCR_Send("page4.p1.pic=31\xff\xff\xff"); //31为正常 } } //总体过压 else if((bmsMem_slave.bStatus1 & 0x0100) != 0) { if(bmsMem_slave.soc<99) { SCR_Send("page4.p1.pic=158\xff\xff\xff"); //158为触发 } else //当SOC大于99%,此时触发过压报警,不会跳转屏幕,也不会亮报警灯 { SCR_Send("page4.p1.pic=31\xff\xff\xff"); //31为正常 } } else { SCR_Send("page4.p1.pic=31\xff\xff\xff"); //31为正常 } //afe充电过流&充电过流 if(((bmsMem_slave.bStatus1 & 0x0010) != 0) || ((bmsMem_slave.temperaStatus & 0x0010) != 0)) { SCR_Send("page4.p2.pic=34\xff\xff\xff"); //34为触发 } else { SCR_Send("page4.p2.pic=33\xff\xff\xff"); //33为正常 } //afe充电高温&环境充电高温&电芯充电高温 if(((bmsMem_slave.bStatus2 & 0x0002) != 0) || ((bmsMem_slave.temperaStatus & 0x0100) != 0) || ((bmsMem_slave.temperaStatus & 0x0001) != 0)) { SCR_Send("page4.p3.pic=36\xff\xff\xff"); //36为触发 } else { SCR_Send("page4.p3.pic=35\xff\xff\xff"); //35为正常 } //afe放电高温&环境放电高温&电芯放电高温 if(((bmsMem_slave.bStatus2 & 0x0008) != 0) || ((bmsMem_slave.temperaStatus & 0x0200) != 0) || ((bmsMem_slave.temperaStatus & 0x0002) != 0)) { SCR_Send("page4.p4.pic=38\xff\xff\xff"); //38为触发 } else { SCR_Send("page4.p4.pic=37\xff\xff\xff"); //37为正常 } //异常高压 if((bmsMem_slave.bStatus1 & 0x0040) != 0) { SCR_Send("page4.p5.pic=40\xff\xff\xff"); //40为触发 } else { SCR_Send("page4.p5.pic=39\xff\xff\xff"); //39为正常 } //单体欠压 if((bmsMem_slave.bStatus1 & 0x0002) != 0) { SCR_Send("page4.p6.pic=42\xff\xff\xff"); //42为触发 } //总体欠压 else if((bmsMem_slave.bStatus1 & 0x0200) != 0) { SCR_Send("page4.p6.pic=159\xff\xff\xff"); //159为触发 } else { SCR_Send("page4.p6.pic=41\xff\xff\xff"); //41为正常 } //afe放电过流&放电过流1&放电过流2 if(((bmsMem_slave.bStatus1 & 0x000c) != 0) || ((bmsMem_slave.temperaStatus & 0x0020) != 0) || ((bmsMem_slave.bStatus1 & 0x0400) != 0)) { SCR_Send("page4.p7.pic=44\xff\xff\xff"); //44为触发 } else { SCR_Send("page4.p7.pic=43\xff\xff\xff"); //43为正常 } //afe充电低温&环境充电低温&电芯充电低温 if(((bmsMem_slave.bStatus2 & 0x0001) != 0) || ((bmsMem_slave.temperaStatus & 0x0400) != 0) || ((bmsMem_slave.temperaStatus & 0x0004) != 0)) { SCR_Send("page4.p8.pic=46\xff\xff\xff"); //46为触发 } else { SCR_Send("page4.p8.pic=45\xff\xff\xff"); //45为正常 } //afe放电低温&环境放电低温&电芯放电低温 if(((bmsMem_slave.bStatus2 & 0x0004) != 0) || ((bmsMem_slave.temperaStatus & 0x0800) != 0) || ((bmsMem_slave.temperaStatus & 0x0008) != 0)) { SCR_Send("page4.p9.pic=48\xff\xff\xff"); //48为触发 } else { SCR_Send("page4.p9.pic=47\xff\xff\xff"); //47为正常 } //低压禁止充电 if((bmsMem_slave.bStatus3 & 0x0008) != 0) { SCR_Send("page4.p10.pic=50\xff\xff\xff"); //50为触发 } else { SCR_Send("page4.p10.pic=49\xff\xff\xff"); //49为正常 } //真短路保护 if((bmsMem_slave.bStatus2 & 0x0010) != 0) //只有预充情况才会出现短路锁定,出现则一直保持,这里也一直显示 { SCR_Send("page4.p11.pic=52\xff\xff\xff"); //52为触发 } //浪涌短路保护 else if((bmsMem_slave.bStatus1 & 0x0020) != 0) { SCR_Send("page4.p11.pic=52\xff\xff\xff"); //52为触发 } else { SCR_Send("page4.p11.pic=51\xff\xff\xff"); //51为正常 } } //报警记录显示 void SCR_Send_RecordInfo(void) { uint8_t i; uint8_t adrh, adrl; uint32_t ee_index[3]; uint16_t ee_pc[3]; ee_index[0] = read_index; ee_index[1] = read_index + 1; ee_index[2] = read_index + 2; for(i=0; i<3; i++) ee_pc[i] = 0x1000 + 0x40 * ee_index[i]; // 发送最新索引 (t1) 和总数 (t2) uint16_t latest; if (soe.num == 0) { latest = 0; } else { latest = (soe.index % 100 == 0) ? 100 : soe.index % 100; } SCR_Send("page17.t1.txt=\"%d\"\xff\xff\xff", latest); SCR_Send("page17.t2.txt=\"%d\"\xff\xff\xff", soe.num); for(i=0; i<3; i++) { uint8_t row = i; // 0=第一列, 1=第二列, 2=第三列 uint16_t seq = ee_index[i] + 1; // 序号从1显示 if(ee_index[i] < soe.num) { // 读EEPROM adrh = (ee_pc[i] >> 8) & 0xFF; adrl = ee_pc[i] & 0xFF; EEPROM_RdMulByte(adrh, adrl, 52, recordBuf); delay_ms(5); if(recordBuf[0]==0xFF && recordBuf[1]==0xFF && recordBuf[2]==0xFF && recordBuf[3]==0xFF) { // 无数据,清空+遮挡 Set_Row_Hide(row, 1); Send_Record_Blank(row); } else { Set_Row_Hide(row, 0); // 发送序号 if(row==0) SCR_Send("page17.t3.txt=\"%d\"\xff\xff\xff", seq); if(row==1) SCR_Send("page17.t4.txt=\"%d\"\xff\xff\xff", seq); if(row==2) SCR_Send("page17.t5.txt=\"%d\"\xff\xff\xff", seq); // 发送时间 (BCD转字符串) char time_str[20]; sprintf(time_str, "20%02x-%02x-%02x %02x:%02x:%02x", recordBuf[4], recordBuf[5], recordBuf[6], recordBuf[7], recordBuf[8], recordBuf[9]); if(row==0) SCR_Send("page17.t6.txt=\"%s\"\xff\xff\xff", time_str); if(row==1) SCR_Send("page17.t8.txt=\"%s\"\xff\xff\xff", time_str); if(row==2) SCR_Send("page17.t10.txt=\"%s\"\xff\xff\xff", time_str); // 发送报警描述 SCR_Send_Record(row); // 改造该函数为写入 sendRecord 后通过 SCR_Send 发送 } } else { // 超出总记录数,清空+遮挡 Set_Row_Hide(row, 1); Send_Record_Blank(row); } } // 遮挡序号2/3图标 SCR_Send("page17.p0.pic=%d\xff\xff\xff", (ee_index[1] < soe.num) ? 154 : 153); SCR_Send("page17.p1.pic=%d\xff\xff\xff", (ee_index[2] < soe.num) ? 154 : 153); } //用于主机查看从机的报警记录(暂直接显示空白和数据0) void SCR_Send_Slave_RecordBank(void) { // t1, t2 显示 0 SCR_Send("page17.t1.txt=\"0\"\xff\xff\xff"); SCR_Send("page17.t2.txt=\"0\"\xff\xff\xff"); // 三行全遮挡 for(uint8_t row = 0; row < 3; row++) { Set_Row_Hide(row, 1); Send_Record_Blank(row); } // 遮挡序号2/3图标 SCR_Send("page17.p0.pic=153\xff\xff\xff"); SCR_Send("page17.p1.pic=153\xff\xff\xff"); // 删除成功图标隐藏 SCR_Send("page17.p5.pic=154\xff\xff\xff"); } //协议选择 OK void SCR_DispProcotol(void) { uint8_t tmpRd; EEPROM_RdMulByte(EE_PROTOCOL,&tmpRd); protocol = tmpRd; //Sol-Ark if(protocol == 1) { SCR_Send("page6.p1.pic=54\xff\xff\xff"); } else { SCR_Send("page6.p1.pic=53\xff\xff\xff"); } //GoodWe if(protocol == 2) { SCR_Send("page6.p2.pic=56\xff\xff\xff"); } else { SCR_Send("page6.p2.pic=55\xff\xff\xff"); } //Megarevo if(protocol == 30) { SCR_Send("page6.p3.pic=58\xff\xff\xff"); } else { SCR_Send("page6.p3.pic=57\xff\xff\xff"); } //Pylon if(protocol == 12) { SCR_Send("page6.p4.pic=60\xff\xff\xff"); } else { SCR_Send("page6.p4.pic=59\xff\xff\xff"); } //Deye if(protocol == 11) { SCR_Send("page6.p5.pic=62\xff\xff\xff"); } else { SCR_Send("page6.p5.pic=61\xff\xff\xff"); } //MUST if(protocol == 7) { SCR_Send("page6.p6.pic=64\xff\xff\xff"); } else { SCR_Send("page6.p6.pic=63\xff\xff\xff"); } //solis if(protocol == 37) { SCR_Send("page6.p7.pic=66\xff\xff\xff"); } else { SCR_Send("page6.p7.pic=65\xff\xff\xff"); } //Growatt if(protocol == 3) { SCR_Send("page6.p8.pic=68\xff\xff\xff"); } else { SCR_Send("page6.p8.pic=67\xff\xff\xff"); } //Aiswei if(protocol == 4) { SCR_Send("page6.p9.pic=70\xff\xff\xff"); } else { SCR_Send("page6.p9.pic=69\xff\xff\xff"); } //Afore if(protocol == 35) { SCR_Send("page6.p10.pic=72\xff\xff\xff"); } else { SCR_Send("page6.p10.pic=71\xff\xff\xff"); } //Victron if(protocol == 27) { SCR_Send("page6.p11.pic=74\xff\xff\xff"); } else { SCR_Send("page6.p11.pic=73\xff\xff\xff"); } //Sorotec if(protocol == 6) { SCR_Send("page6.p12.pic=76\xff\xff\xff"); } else { SCR_Send("page6.p12.pic=75\xff\xff\xff"); } //SMA if(protocol == 5) { SCR_Send("page7.p1.pic=78\xff\xff\xff"); } else { SCR_Send("page7.p1.pic=77\xff\xff\xff"); } //Sunways if(protocol == 39) { SCR_Send("page7.p2.pic=80\xff\xff\xff"); } else { SCR_Send("page7.p2.pic=79\xff\xff\xff"); } //Luxpower if(protocol == 23) { SCR_Send("page7.p3.pic=82\xff\xff\xff"); } else { SCR_Send("page7.p3.pic=81\xff\xff\xff"); } //Schneider if(protocol == 24) { SCR_Send("page7.p4.pic=84\xff\xff\xff"); } else { SCR_Send("page7.p4.pic=83\xff\xff\xff"); } //AlpSolarr if(protocol == 40) { SCR_Send("page7.p5.pic=86\xff\xff\xff"); } else { SCR_Send("page7.p5.pic=85\xff\xff\xff"); } //SRNE if(protocol == 13) { SCR_Send("page7.p6.pic=88\xff\xff\xff"); } else { SCR_Send("page7.p6.pic=87\xff\xff\xff"); } //Voltronic if(protocol == 14) { SCR_Send("page7.p7.pic=90\xff\xff\xff"); } else { SCR_Send("page7.p7.pic=89\xff\xff\xff"); } //COSUPER if(protocol == 32) { SCR_Send("page7.p8.pic=92\xff\xff\xff"); } else { SCR_Send("page7.p8.pic=91\xff\xff\xff"); } //SMK if(protocol == 17) { SCR_Send("page7.p9.pic=94\xff\xff\xff"); } else { SCR_Send("page7.p9.pic=93\xff\xff\xff"); } //SAKO if(protocol == 31) { SCR_Send("page7.p10.pic=96\xff\xff\xff"); } else { SCR_Send("page7.p10.pic=95\xff\xff\xff"); } //SNADI if(protocol == 18) { SCR_Send("page7.p11.pic=98\xff\xff\xff"); } else { SCR_Send("page7.p11.pic=97\xff\xff\xff"); } //invt if(protocol == 21) { SCR_Send("page7.p12.pic=100\xff\xff\xff"); } else { SCR_Send("page7.p12.pic=99\xff\xff\xff"); } // //备选 // if(protocol == 25) // { // SCR_Send("page8.p1.pic=102\xff\xff\xff"); // } // else // { // SCR_Send("page8.p1.pic=101\xff\xff\xff"); // } // //备选2 // if(protocol == 26) // { // SCR_Send("page8.p2.pic=104\xff\xff\xff"); // } // else // { // SCR_Send("page8.p2.pic=103\xff\xff\xff"); // } if((protocol <= 0) || (protocol > 50)) { //默认Sol-Ark protocol = 1; } } //显示总数据 OK void SCR_Send_TotalInfo(void) { uint16_t voltage; int16_t current; uint16_t totalCapacity; uint16_t capacity; uint8_t soc; int32_t export_P; uint16_t total_W,remain_W,cumuli_W; uint16_t remain_T; //充放电剩余时间 voltage = bmsMem.packVoltage /100; //总电压,单位0.1V current = canMem[0].cur /10; //总电流,单位0.1A totalCapacity = 10 * ncc_Ah * OnlineNum; //总额定容量,单位0.1Ah capacity = totalCapacity * canMem[0].soc /100; //总当前容量,单位0.1Ah soc = canMem[0].soc; //平均soc export_P = voltage*current/10; //当前消耗功率=总电压x总电流,单位0.1W=10*(0.1V*0.1A) total_W = totalCapacity*(3.2*bmsMem.ucCellNum)/1000; //额定能量=额定总容量x额定电压,单位0.1kWh=1000*(0.1Ah*1V) remain_W = capacity*(3.2*bmsMem.ucCellNum)/1000; //剩余能量=当前总容量x额定电压,单位0.1kWh=1000*(0.1Ah*1V) cumuli_W = (canMem[0].cycleCnt*fcc_Ah+canMem[0].cumuliCap)*(3.2*bmsMem.ucCellNum)/100/1000; //累积消耗能量=(总循环次数1x单PACK额定容量Ah+总累积消耗容量Ah)x额定电压V,单位0.1MWh=100000*1Wh //Page19 总数据页 SCR_Send("page19.t1.txt=\"%.1f\"\xff\xff\xff", (float)voltage/10); //总电压 0.1V SCR_Send("page19.t2.txt=\"%.1f\"\xff\xff\xff", (float)export_P/10); //总功率 0.1W SCR_Send("page19.t3.txt=\"%.1f\"\xff\xff\xff", (float)current/10); //总电流 0.1A SCR_Send("page19.t4.txt=\"%.1f\"\xff\xff\xff", (float)remain_W/10); //剩余容量 0.1kWh SCR_Send("page19.t5.txt=\"%.1f\"\xff\xff\xff", (float)total_W/10); //额定容量 0.1kWh SCR_Send("page19.t6.txt=\"%.1f\"\xff\xff\xff", (float)cumuli_W/10); //功率总耗 0.1Mwh SCR_Send("page19.t8.txt=\"%d\"\xff\xff\xff", soc);//总SOC if(current >= 5) //充电0.5A { remain_T = (totalCapacity - capacity)*10/current; //充电剩余时间=(额定总容量-当前总容量)0.1Ah/总电流0.1A,单位0.1h=0.1*0.1Ah/0.1A SCR_Send("page19.t7.txt=\"%.1f\"\xff\xff\xff", (float)remain_T);//剩余时间 0.1h } else if(current <= (-5)) //放电0.5A { remain_T = capacity*10/(-current); //放电剩余时间=当前总容量0.1Ah/总电流0.1A,单位0.1h=0.1*0.1Ah/0.1A SCR_Send("page19.t7.txt=\"%.1f\"\xff\xff\xff", (float)remain_T);//剩余时间 0.1h } else //待机状态 { SCR_Send("page19.t7.txt=\"%d\"\xff\xff\xff", 0);//剩余时间 0 } } //显示自身基本信息 OK void SCR_Send_Self_BasicInfo(void) { static uint8_t last_alarm_stat = 0; uint16_t voltage; int16_t current; int32_t power; uint16_t capacity; uint16_t remain_T; voltage = bmsMem.packVoltage /100; //电压,1位小数 current = bmsMem.packCurrent /100; //电流,1位小数 power = voltage * current /10; //功率,1位小数 capacity = bmsMem.rcc/3600 /100; //容量,1位小数 //发送数据到屏幕 SCR_Send("page1.t0.txt=\"%d\"\xff\xff\xff", bmsMem.E2_485Addr); SCR_Send("page1.t1.txt=\"%.1f\"\xff\xff\xff", (float)voltage/10); SCR_Send("page1.t2.txt=\"%.1f\"\xff\xff\xff", (float)power/10); SCR_Send("page1.t3.txt=\"%.1f\"\xff\xff\xff", (float)current/10); SCR_Send("page1.t4.txt=\"%.1f\"\xff\xff\xff", (float)capacity/10); SCR_Send("page1.t5.txt=\"%.1f\"\xff\xff\xff", (float)(TemperatureAverage - 2731)/10); SCR_Send("page1.t6.txt=\"%d\"\xff\xff\xff", bmsMem.soc); SCR_Send("page1.t7.txt=\"%d\"\xff\xff\xff", bmsMem.can_cycleCnt); SCR_Send("page2.t0.txt=\"%d\"\xff\xff\xff", bmsMem.E2_485Addr); SCR_Send("page2.t1.txt=\"%d\"\xff\xff\xff", cellVol[0]); SCR_Send("page2.t2.txt=\"%d\"\xff\xff\xff", cellVol[1]); SCR_Send("page2.t3.txt=\"%d\"\xff\xff\xff", cellVol[2]); SCR_Send("page2.t4.txt=\"%d\"\xff\xff\xff", cellVol[3]); SCR_Send("page2.t5.txt=\"%d\"\xff\xff\xff", cellVol[4]); SCR_Send("page2.t6.txt=\"%d\"\xff\xff\xff", cellVol[5]); SCR_Send("page2.t7.txt=\"%d\"\xff\xff\xff", cellVol[6]); SCR_Send("page2.t8.txt=\"%d\"\xff\xff\xff", cellVol[7]); SCR_Send("page2.t9.txt=\"%d\"\xff\xff\xff", cellVol[8]); SCR_Send("page2.t10.txt=\"%d\"\xff\xff\xff", cellVol[9]); SCR_Send("page2.t11.txt=\"%d\"\xff\xff\xff", cellVol[10]); SCR_Send("page2.t12.txt=\"%d\"\xff\xff\xff", cellVol[11]); SCR_Send("page2.t13.txt=\"%d\"\xff\xff\xff", cellVol[12]); SCR_Send("page2.t14.txt=\"%d\"\xff\xff\xff", cellVol[13]); SCR_Send("page2.t15.txt=\"%d\"\xff\xff\xff", cellVol[14]); SCR_Send("page2.t16.txt=\"%d\"\xff\xff\xff", cellVol[15]); SCR_Send("page3.t0.txt=\"%d\"\xff\xff\xff", bmsMem.E2_485Addr); SCR_Send("page3.t1.txt=\"%.1f\"\xff\xff\xff", (float)(bmsMem.mcu_T1 - 2731)/10); SCR_Send("page3.t2.txt=\"%.1f\"\xff\xff\xff", (float)(bmsMem.mcu_T2 - 2731)/10); SCR_Send("page3.t3.txt=\"%.1f\"\xff\xff\xff", (float)(bmsMem.mcu_T3 - 2731)/10); SCR_Send("page3.t4.txt=\"%.1f\"\xff\xff\xff", (float)(bmsMem.mcu_T4 - 2731)/10); SCR_Send("page3.t5.txt=\"%.1f\"\xff\xff\xff", (float)(bmsMem.afe_T3 - 2731)/10); //环境温度 SCR_Send("page3.t6.txt=\"%.1f\"\xff\xff\xff", (float)(bmsMem.afe_T1 - 2731)/10); //接线柱温度1 SCR_Send("page3.t7.txt=\"%.1f\"\xff\xff\xff", (float)(bmsMem.afe_T2 - 2731)/10); //接线柱温度2 if(bAlarmFlag == 0) //无屏幕上的报警 { // 仅在从报警状态恢复时,才清除报警页图标 if(last_alarm_stat != 0) { SCR_ClearAlarm(); } last_alarm_stat = 0; if((bmsMem.temperaStatus & 0x40) !=0) //急停 { SCR_Send("page1.p1.pic=27\xff\xff\xff"); //27为急停 } else if((bmsMem.bStatus2 & 0xe0) !=0) { SCR_Send("page1.p1.pic=26\xff\xff\xff"); //26为报警 } else { if(bSTANDBY == 1) { SCR_Send("page1.p1.pic=25\xff\xff\xff"); //25为待机 } else if(bCHGING ==1) { if((bmsMem.balanceStatus & 0x10) != 0) { SCR_Send("page1.p1.pic=28\xff\xff\xff"); //28为限流 } else { SCR_Send("page1.p1.pic=23\xff\xff\xff"); //23为充电 } } else { SCR_Send("page1.p1.pic=24\xff\xff\xff"); //24为放电 } } SCR_ClearAlarm(); } else { last_alarm_stat = 1; // 记录本次有报警 SCR_Send("page1.p1.pic=26\xff\xff\xff"); //“Fault”(屏幕上的报警) if(bAlarmFlagOld ==0) { bAlarmFlagOld = 1; SCR_JumpToAlarm(); } SCR_ShowAlarm(); } if(current >= 5) //充电0.5A { remain_T = (fcc - bmsMem.rcc)/36000/current; //充电剩余时间=((额定总容量-当前总容量mAS)/36000)/总电流,单位0.1h=0.01Ah/0.1A SCR_Send("page1.t8.txt=\"%.1f\"\xff\xff\xff", (float)remain_T);//剩余时间 0.1h } else if(current <= (-5)) //放电0.5A { remain_T = bmsMem.rcc/36000/(-current); //放电剩余时间=当前总容量mAS/36000/总电流,单位0.1h=0.01Ah/0.1A SCR_Send("page1.t8.txt=\"%.1f\"\xff\xff\xff", (float)remain_T);//剩余时间 0.1h } else//待机状态 { SCR_Send("page1.t8.txt=\"%d\"\xff\xff\xff", 0);//剩余时间 0 } //均衡状态 if(balancing ==1) { SCR_Send("page1.p2.pic=29\xff\xff\xff"); //29为开启 } else { SCR_Send("page1.p2.pic=30\xff\xff\xff"); //30为关闭 } } void SCR_Send_Slave_BasicInfo(void) { uint16_t voltage; int16_t current; int32_t power; uint16_t capacity; uint8_t soc; uint16_t Ave_Temp; //平均温度 uint16_t remain_T; //充放电剩余时间 voltage = bmsMem_slave.packVoltage /100; //电压,单位0.1V current = bmsMem_slave.packCurrent /100; //电流,单位0.1A power = voltage * current /10; //功率,1位小数 capacity = bmsMem_slave.rcc/360000; //当前容量,单位0.1Ah Ave_Temp = (bmsMem_slave.mcu_T1 + bmsMem_slave.mcu_T2 + bmsMem_slave.mcu_T3 + bmsMem_slave.mcu_T4)/4; soc = bmsMem_slave.soc; //平均SOC //发送数据到屏幕 SCR_Send("page1.t1.txt=\"%.1f\"\xff\xff\xff", (float)voltage/10); SCR_Send("page1.t2.txt=\"%.1f\"\xff\xff\xff", (float)power/10); SCR_Send("page1.t3.txt=\"%.1f\"\xff\xff\xff", (float)current/10); SCR_Send("page1.t4.txt=\"%.1f\"\xff\xff\xff", (float)capacity/10); SCR_Send("page1.t5.txt=\"%.1f\"\xff\xff\xff", (float)(Ave_Temp - 2731)/10); SCR_Send("page1.t6.txt=\"%d\"\xff\xff\xff", soc); SCR_Send("page1.t7.txt=\"%d\"\xff\xff\xff", bmsMem.can_cycleCnt); SCR_Send("page2.t1.txt=\"%d\"\xff\xff\xff", (int16_t)(bmsMem_slave.vCell[0]*32/5)*5/32); SCR_Send("page2.t2.txt=\"%d\"\xff\xff\xff", (int16_t)(bmsMem_slave.vCell[1]*32/5)*5/32); SCR_Send("page2.t3.txt=\"%d\"\xff\xff\xff", (int16_t)(bmsMem_slave.vCell[2]*32/5)*5/32); SCR_Send("page2.t4.txt=\"%d\"\xff\xff\xff", (int16_t)(bmsMem_slave.vCell[3]*32/5)*5/32); SCR_Send("page2.t5.txt=\"%d\"\xff\xff\xff", (int16_t)(bmsMem_slave.vCell[4]*32/5)*5/32); SCR_Send("page2.t6.txt=\"%d\"\xff\xff\xff", (int16_t)(bmsMem_slave.vCell[5]*32/5)*5/32); SCR_Send("page2.t7.txt=\"%d\"\xff\xff\xff", (int16_t)(bmsMem_slave.vCell[6]*32/5)*5/32); SCR_Send("page2.t8.txt=\"%d\"\xff\xff\xff", (int16_t)(bmsMem_slave.vCell[7]*32/5)*5/32); SCR_Send("page2.t9.txt=\"%d\"\xff\xff\xff", (int16_t)(bmsMem_slave.vCell[8]*32/5)*5/32); SCR_Send("page2.t10.txt=\"%d\"\xff\xff\xff", (int16_t)(bmsMem_slave.vCell[9]*32/5)*5/32); SCR_Send("page2.t11.txt=\"%d\"\xff\xff\xff", (int16_t)(bmsMem_slave.vCell[10]*32/5)*5/32); SCR_Send("page2.t12.txt=\"%d\"\xff\xff\xff", (int16_t)(bmsMem_slave.vCell[11]*32/5)*5/32); SCR_Send("page2.t13.txt=\"%d\"\xff\xff\xff", (int16_t)(bmsMem_slave.vCell[12]*32/5)*5/32); SCR_Send("page2.t14.txt=\"%d\"\xff\xff\xff", (int16_t)(bmsMem_slave.vCell[13]*32/5)*5/32); SCR_Send("page2.t15.txt=\"%d\"\xff\xff\xff", (int16_t)(bmsMem_slave.vCell[14]*32/5)*5/32); SCR_Send("page2.t16.txt=\"%d\"\xff\xff\xff", (int16_t)(bmsMem_slave.vCell[15]*32/5)*5/32); SCR_Send("page3.t1.txt=\"%.1f\"\xff\xff\xff", (float)(bmsMem_slave.mcu_T1 - 2731)/10); SCR_Send("page3.t2.txt=\"%.1f\"\xff\xff\xff", (float)(bmsMem_slave.mcu_T2 - 2731)/10); SCR_Send("page3.t3.txt=\"%.1f\"\xff\xff\xff", (float)(bmsMem_slave.mcu_T3 - 2731)/10); SCR_Send("page3.t4.txt=\"%.1f\"\xff\xff\xff", (float)(bmsMem_slave.mcu_T4 - 2731)/10); SCR_Send("page3.t5.txt=\"%.1f\"\xff\xff\xff", (float)(bmsMem_slave.afe_T3 - 2731)/10); //环境温度 SCR_Send("page3.t6.txt=\"%.1f\"\xff\xff\xff", (float)(bmsMem_slave.afe_T1 - 2731)/10); //接线柱温度1 SCR_Send("page3.t7.txt=\"%.1f\"\xff\xff\xff", (float)(bmsMem_slave.afe_T2 - 2731)/10); //接线柱温度2 //首页的状态显示and报警跳转 if(((bmsMem_slave.bStatus1 & 0x7e)==0) && ((bmsMem_slave.bStatus2 & 0x0f) ==0) && ((bmsMem_slave.bStatus3 & 0x18) ==0) && ((bmsMem_slave.temperaStatus & 0x3f) ==0) ) //无屏幕上的报警 { if(((bmsMem_slave.bStatus1 & 0x01) != 0) && (bmsMem_slave.soc<99) ) //过压报警的判断:满电时发生[过压保护],屏幕不显示过压 { SCR_Send("page1.p1.pic=26\xff\xff\xff"); //“Fault”(屏幕上的报警) //从机报警的跳转 if(bAlarmFlagOld_slave == 0) { bAlarmFlagOld_slave = 1; SCR_JumpToAlarm(); } SCR_ShowAlarm_Slave(); } else { if((bmsMem_slave.temperaStatus & 0x40) !=0) { SCR_Send("page1.p1.pic=27\xff\xff\xff"); //27为急停 } else if((bmsMem_slave.bStatus2 & 0xe0) !=0) { SCR_Send("page1.p1.pic=26\xff\xff\xff"); //“Fault”(屏幕上的报警) } else { if(bmsMem_slave.packCurrent > 100) { if((bmsMem.balanceStatus & 0x10) != 0) { SCR_Send("page1.p1.pic=28\xff\xff\xff"); //28为限流 } else { SCR_Send("page1.p1.pic=23\xff\xff\xff"); //23为充电 } } else if(bmsMem_slave.packCurrent < (-100)) { SCR_Send("page1.p1.pic=24\xff\xff\xff"); //24为放电 } else { SCR_Send("page1.p1.pic=25\xff\xff\xff"); //25为待机 } } bAlarmFlagOld_slave = 0; SCR_ClearAlarm(); } } else { SCR_Send("page1.p1.pic=26\xff\xff\xff"); //“Fault”(屏幕上的报警) //从机报警的跳转 if(bAlarmFlagOld_slave ==0) { bAlarmFlagOld_slave = 1; SCR_JumpToAlarm(); } SCR_ShowAlarm_Slave(); } //均衡状态 if((bmsMem_slave.balanceStatus & 0x01) !=0) { SCR_Send("page1.p2.pic=29\xff\xff\xff"); //29为开启 } else { SCR_Send("page1.p2.pic=30\xff\xff\xff"); //30为关闭 } if(current >= 5) //充电0.5A { remain_T = (fcc - bmsMem_slave.rcc)/36000/current; //充电剩余时间=((额定总容量-当前总容量mAS)/36000)/总电流,单位0.1h=0.01Ah/0.1A SCR_Send("page1.t8.txt=\"%.1f\"\xff\xff\xff", (float)remain_T);//剩余时间 0.1h } else if(current <= (-5)) //放电0.5A { remain_T = bmsMem_slave.rcc/36000/(-current); //放电剩余时间=当前总容量mAS/36000/总电流,单位0.1h=0.01Ah/0.1A SCR_Send("page1.t8.txt=\"%.1f\"\xff\xff\xff", (float)remain_T);//剩余时间 0.1h } else//待机状态 { SCR_Send("page1.t8.txt=\"%d\"\xff\xff\xff", 0);//剩余时间 0 } } //定时发送数据,1s1次 void Screen_IQ_Transmit(void) { uint16_t scv,sct; //用于显示短路参数 /**** 时间显示 ****/ SCR_Send_Time(); //系统时间 /**** 汇总信息 ****/ if(bmsMem.E2_485Addr == 1) { SCR_Send_TotalInfo(); //显示总数据 } /**** 基本信息 ****/ if((bmsMem.E2_485Addr != 1) || (scr_RdData_Index == 1)) //当前是从机或主机自身,一直显示自身数据 { SCR_Send_Self_BasicInfo(); } else //当前是主机,可显示自身数据或所选从机数据 { SCR_Send_Slave_BasicInfo(); } /**** 删除记录的显示 ****/ if((SCR_HistoryFlag == 1) && (clearFlag == 1)) { if(clearFlag_timer > 0) { SCR_Send("page17.p5.pic=152\xff\xff\xff"); // 显示删除成功图标 clearFlag_timer--; } else { SCR_Send("page17.p5.pic=154\xff\xff\xff"); // 隐藏成功图标 clearFlag = 0; // 标志复位 SCR_HistoryFlag = 0; } } /**** 欠压保护恢复倒计时的显示 ****/ if((bmsMem.balanceStatus & 0x20) != 0) { uint16_t time; //正常情况下,在RTC时钟里计算 if(LSEErrFlag == 0) time = uvofftime; //若RTC遇到问题,在定时器里计算 else time = uvoff_Moni_Count/100; uint8_t min = time / 60; uint8_t sec = time % 60; SCR_Send("page12.t1.txt=\"%02d:%02d\"\xff\xff\xff", min, sec); } else { SCR_Send("page12.b0.pic=105\xff\xff\xff"); // 恢复默认图标 SCR_Send("page12.t1.txt=\" \"\xff\xff\xff"); } /**** 并机图标根据地址显示 ****/ if(bmsMem.E2_485Addr == 1) { SCR_Send("page1.p3.pic=150\xff\xff\xff"); //150为并机 } else { SCR_Send("page1.p3.pic=149\xff\xff\xff"); //149不并机 } /**** 电池并机页显示 ****/ //显示当前正在轮询还是正在分配 if(SCR_ParallelFlag == 1) { #if Addr_SetAuto if((paraMem.addr_FREE_Flg == 0) && ((assignAddr_State == 0) || (assignAddr_State == 1))) { SCR_Send("page18.p0.pic=146\xff\xff\xff"); //146为分配 } else #endif if(ConfigData_Index == 1) //除了上位机读数据的其他时候 { SCR_Send("page18.p0.pic=145\xff\xff\xff"); //145为轮询 } else { SCR_Send("page18.p0.pic=144\xff\xff\xff"); //144为空 } for(int i = 1; i <= 16; i++) { int picId; if(onlineMem.Online[i] == 0xAA) { picId = 110 + i * 2; // 在线 } else if(onlineMem.Online[i] == 0xBB) { picId = 111 + i * 2; // 报警 } else { picId = 111; // 空 } char cmd[32]; sprintf(cmd, "page18.p%d.pic=%d\xff\xff\xff", i, picId); SCR_Send(cmd); } if(SCR_PACKFlag == 1) { SCR_ParallelFlag = 0; SCR_PACKFlag = 0; SCR_Send("page page1\xff\xff\xff"); //跳转到page1数据页 } } /**** 历史记录显示 ****/ //在首页,历史记录按钮只有主机1显示 if(bmsMem.E2_485Addr == 1) { SCR_Send("page1.p0.pic=147\xff\xff\xff"); //147为不遮挡历史 } else { SCR_Send("page1.p0.pic=148\xff\xff\xff"); //148为遮挡历史 } //历史记录页显示 if(SCR_HistoryFlag == 1) { if((bmsMem.E2_485Addr != 1) || (scr_RdData_Index == 1)) //看自身数据 { SCR_Send_RecordInfo(); } else { SCR_Send_Slave_RecordBank(); } } /**** 地址释放控制的打勾显示 ****/ if(paraMem.addr_FREE_Flg == 1) { SCR_Send("page14.p1.pic=157\xff\xff\xff");//勾选 } else { SCR_Send("page14.p1.pic=156\xff\xff\xff");//取消 } /**** 地址与从机地址修改状态显示 ****/ if(sdwa_WrAddr_Flg == 1) { SCR_Send("page14.t1.txt=\"%d\"\xff\xff\xff", 0); // 正在修改 } else if(sdwa_WrAddr_Flg == 2) { sdwa_WrAddr_Flg = 0; canMem[scr_RdData_Index].com = 0; canMem[sdwa_WrAddr].com = 1; scr_RdData_Index = sdwa_WrAddr; // 切换查看 SCR_Send("page14.t1.txt=\"%d\"\xff\xff\xff", sdwa_WrAddr); } else if(sdwa_WrAddr_Flg == 3) { sdwa_WrAddr_Flg = 0; SCR_Send("page14.t1.txt=\"%d\"\xff\xff\xff", scr_RdData_Index); // 恢复 } else { if((bmsMem.E2_485Addr != 1) || (scr_RdData_Index == 1)) { SCR_Send("page14.t1.txt=\"%d\"\xff\xff\xff", bmsMem.E2_485Addr); } else { SCR_Send("page14.t1.txt=\"%d\"\xff\xff\xff", scr_RdData_Index); } } #if LTE_Conn /**** 4G状态显示 ****/ if(LTEStatus_flg == 0) { if(LTE_WarmDelay > 0) { LTEStatus_flg = 1; strcpy(LTEStatus_str, "wait 4G warm"); } else if(LTE_OTA_Flag == 1) //4G等待OTA升级 { LTEStatus_flg = 1; strcpy(LTEStatus_str, "Upgrade loading"); } else if(MQTT_READY_flag == 1) //4G已在正常工作流程 { LTEStatus_flg = 1; strcpy(LTEStatus_str, "working"); } else if((LTE_rssi > 0) && (LTE_rssi <= 13)) //出现问题:弱网环境 { LTEStatus_flg = 1; strcpy(LTEStatus_str, "weak grid"); } else if(LTE_Onlineflag == 0xAA) //出现问题:4G联网错误 { LTEStatus_flg = 1; strcpy(LTEStatus_str, "network exist fault"); } } else { if((LTE_Rx_BufIndex == 0) && (CRESET_flag == 0) && (MQTT_RST_flag == 0)) { strcat(LTEStatus_str, " Null"); } } if(LTEStatus_flg == 1) { LTEStatus_flg = 0; SCR_Send("page14.t3.txt=\"%s\"\xff\xff\xff", LTEStatus_str); } else { SCR_Send("page14.t3.txt=\" \"\xff\xff\xff"); } #endif /**** 恢复出厂设置功能+完成图标显示 ****/ if(factory_reset_flag == 1) { // 执行恢复默认参数 //P1 bmsMem.ee_scv_sct = 0x10; //80mV 0uS bmsMem.inverter_chgVolLimit = 640; //60.4V bmsMem.inverter_dsgVolLimit = 480; //48.0V bmsMem.inverter_chgCurLimit = paraMem.alarm_occ * 10 - 100; //充电过流告警-10A bmsMem.inverter_dsgCurLimit = paraMem.alarm_ocd1 * 10 - 100; //放电过流告警-10A //P2 bmsMem.ee_ocd1v_ocd1t = (bmsMem.ee_ocd1v_ocd1t & 0x0F) | 0x10; //30mV bmsMem.ee_ocd2v_ocd2t = (bmsMem.ee_ocd2v_ocd2t & 0x0F) | 0x10; //40mV bmsMem.ee_occv_occt = (bmsMem.ee_occv_occt & 0x0F) | 0x10; //30mV bmsMem.mcu_occ = 0xCD; //充电过流 205A bmsMem.mcu_ocd = 0xCD; //放电过流 205A bmsMem.ee_ovt_ldrt_ovh = (bmsMem.ee_ovt_ldrt_ovh & 0xFC) | 0x02; bmsMem.ee_ovl = 0xD0; //过压保护电压 0x2D0*5=3600mV bmsMem.ee_uvt_ovrh = (bmsMem.ee_uvt_ovrh & 0xFC) | 0x02; bmsMem.ee_ovrl = 0xA8; //过压保护释放 0x2A8*5=3400mV bmsMem.ee_uv = 0x87; //欠压保护电压 0x87*20=2700mV bmsMem.ee_uvr = 0x91; //欠压保护释放 0x91*20=2900mV //P3 bmsMem.mcu_otc = 0x3C; //充电高温 60 bmsMem.mcu_otcr = 0x37; //充电高温释放 55 bmsMem.mcu_utc = 0x00; //充电低温 0 bmsMem.mcu_utcr = 0x05; //充电低温释放 5 bmsMem.mcu_otd = 0x41; //放电高温 65 bmsMem.mcu_otdr = 0x3C; //放电高温释放 60 bmsMem.mcu_utd = 0xEC; //放电低温 -20 bmsMem.mcu_utdr = 0xF1; //放电低温释放 -15 // 更新 Flash 和 AFE if((MEMORY_UpdateFlash(FLASH_DATA_A_BASE) == 0) && (MEMORY_UpdateFlash(FLASH_DATA_B_BASE) == 0)) { bmsMem.packStatus &= ~BIT0; if(MEMORY_UpdateAFE() == 0) bmsMem.packStatus &= ~BIT1; else bmsMem.packStatus |= BIT1; } else { bmsMem.packStatus |= BIT0; } factory_reset_flag = 2; SCR_Send("page13.b0.pic=109\xff\xff\xff"); // 配置中 } else if(factory_reset_flag == 2) { // 延时一定时间后恢复默认图标(例如通过计数器) static uint8_t reset_timer = 0; reset_timer++; if(reset_timer >= 3) // 3秒后恢复 { reset_timer = 0; factory_reset_flag = 0; SCR_Send("page13.b0.pic=108\xff\xff\xff");//默认 } else { SCR_Send("page13.b0.pic=110\xff\xff\xff"); // 成功图标 } } /**** 参数显示 ****/ SCR_Send_VER(); //地址、SN号、版本号 SCR_DispProcotol(); //逆变器协议 //一屏多显,当前显示地址 uint8_t dispAddr = (scr_RdData_Index == 1) ? bmsMem.E2_485Addr : scr_RdData_Index; for (int p = 1; p <= 17; p++) { SCR_Send("page%d.t0.txt=\"%d\"\xff\xff\xff", p, dispAddr); } //额定容量 SCR_Send("page14.t2.txt=\"%d\"\xff\xff\xff", bmsMem.ncc/3600/1000); /**** 可设参数显示+正在设置图标 ****/ if(flashUpdateFlag != 0) { uint8_t i; uint8_t* data; uint8_t temp[26]; //要计算校验码 if(flashUpdateFlag >= 2) //2代表修改单个参数,3代表初始化所有参数 》》但都需要计算CRC值 { data = (uint8_t *)&bmsMem.ee_sconf1; for(i=0;i<25;i++) { temp[i] = *data; data++; } temp[25] = CRC8_Cal(&temp[0],25); //更改对应校验值 bmsMem.ee_tr = temp[25]; data = (uint8_t *)&bmsMem.mcu_otc; for(i=0;i<13;i++) { temp[i] = *data; data++; } temp[13] = CRC8_Cal(&temp[0],13); //更改对应校验值 bmsMem.mcu_crc = temp[13]; } //bmsMem中数据更新到FLASH A区和B区和AFE EEPORM if((MEMORY_UpdateFlash(FLASH_DATA_A_BASE) == 0) && (MEMORY_UpdateFlash(FLASH_DATA_B_BASE) == 0)) { staPack.bits.flashUpdate= 0; if(MEMORY_UpdateAFE() ==0) //更新AFE EEPROM内容 { staPack.bits.eepromUpdate = 0; } else { staPack.bits.eepromUpdate = 1; } } else { staPack.bits.flashUpdate= 1; } bmsMem.packStatus = staPack.byte; //清空值 flashUpdateFlag = 0; } else { //短路参数 scv = (bmsMem.ee_scv_sct & 0xF0)>>4; if(scv == 0x0B) { scv = 400; } else { scv = 50 + 30 * scv; } sct = 0 + 64*(bmsMem.ee_scv_sct & 0x0F); //Page9 SCR_Send("page9.t1.txt=\"%.1f\"\xff\xff\xff", (float)bmsMem.inverter_chgCurLimit / 10); SCR_Send("page9.t2.txt=\"%.1f\"\xff\xff\xff", (float)bmsMem.inverter_chgVolLimit / 10); SCR_Send("page9.t3.txt=\"%.1f\"\xff\xff\xff", (float)bmsMem.inverter_dsgCurLimit / 10); SCR_Send("page9.t4.txt=\"%.1f\"\xff\xff\xff", (float)bmsMem.inverter_dsgVolLimit / 10); SCR_Send("page9.t5.txt=\"%d\"\xff\xff\xff", bmsMem.mcu_occ); SCR_Send("page9.t6.txt=\"%d\"\xff\xff\xff", bmsMem.mcu_ocd); //Page10 SCR_Send("page10.t1.txt=\"%d\"\xff\xff\xff", bmsMem.mcu_otc); SCR_Send("page10.t2.txt=\"%d\"\xff\xff\xff", bmsMem.mcu_otcr); SCR_Send("page10.t3.txt=\"%d\"\xff\xff\xff", bmsMem.mcu_utc); SCR_Send("page10.t4.txt=\"%d\"\xff\xff\xff", bmsMem.mcu_utcr); SCR_Send("page10.t5.txt=\"%d\"\xff\xff\xff", bmsMem.mcu_otd); SCR_Send("page10.t6.txt=\"%d\"\xff\xff\xff", bmsMem.mcu_otdr); SCR_Send("page10.t7.txt=\"%d\"\xff\xff\xff", bmsMem.mcu_utd); SCR_Send("page10.t8.txt=\"%d\"\xff\xff\xff", bmsMem.mcu_utdr); //Page11 SCR_Send("page11.t1.txt=\"%d\"\xff\xff\xff", 5* (((bmsMem.ee_ovt_ldrt_ovh & 0x03)<<8) + bmsMem.ee_ovl)); SCR_Send("page11.t2.txt=\"%d\"\xff\xff\xff", 5* (((bmsMem.ee_uvt_ovrh & 0x03)<<8) + bmsMem.ee_ovrl)); SCR_Send("page11.t3.txt=\"%d\"\xff\xff\xff", bmsMem.ee_uv *20); SCR_Send("page11.t4.txt=\"%d\"\xff\xff\xff", bmsMem.ee_uvr * 20); SCR_Send("page11.t5.txt=\"%d\"\xff\xff\xff", scv);//短路保护电压 SCR_Send("page11.t6.txt=\"%d\"\xff\xff\xff", sct);//短路保护延时 } } //接收一帧数据,帧间断小于x ms仍然认为是一帧 //定时器中断里进行接收数据解析并准备回送数据 void Screen_IT_Update(void) { uint8_t protocol_Index; //屏幕写入增多,加一层判断以减少写入协议选择的次数 protocol_Index = protocol; uint8_t tmpWr[2]; if(SCR_Rx_BufIndex >= 4) //按钮指令都是7字节,写参数指令至少5字节,休眠/退出休眠指令是4字节 { uint8_t i; uint32_t temp = 0; //过程量(绝对值) //屏幕休眠唤醒 if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_Sleep, 4)) { SCR_Send("page page1\xff\xff\xff"); // 唤醒跳转至首页 if(sleep_flag == 1) { sleep_flag = 0; SLEEP_Refresh(); SLEEP2_Refresh(); } } //手动分配地址勾选 if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setADDR, 7)) { SCR_setADDRFlag = 1; } //历史记录界面 if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_Hide_History, 7)) { SCR_HistoryFlag = 1; SCR_Send("page page17\xff\xff\xff"); // 只发一次跳转 } if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_up_History, 7)) //上翻页 { if(read_index >= 3) read_index -= 3; else read_index = 0; } if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_down_History, 7)) //下翻页 { if(read_index + 3 < soe.num) read_index += 3; } if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_clean_History, 7)) { if(soe.num != 0) // 有记录才删除 { uint16_t i; uint16_t pc; uint8_t adrh, adrl; uint8_t wrBuf[64]; //清空所有记录内容(填充0xFF) memset(wrBuf, 0xFF, sizeof(wrBuf)); pc = 0x1000; for(i=0; i<100; i++) { adrh = (pc >> 8) & 0xFF; adrl = pc & 0xFF; EEPROM_WrMulByte(EE_SOE, wrBuf); // 使用EE_SOE宏,传入adrh,adrl delay_ms(10); pc += 0x40; } //重置 soe 统计信息 soe.index = 0; soe.pc = 0x1000; soe.num = 0; wrBuf[0] = (soe.index >> 24) & 0xFF; wrBuf[1] = (soe.index >> 16) & 0xFF; wrBuf[2] = (soe.index >> 8) & 0xFF; wrBuf[3] = soe.index & 0xFF; wrBuf[4] = (soe.pc >> 8) & 0xFF; wrBuf[5] = soe.pc & 0xFF; wrBuf[6] = (soe.num >> 8) & 0xFF; wrBuf[7] = soe.num & 0xFF; EEPROM_WrMulByte(EE_SOE_INF, wrBuf); delay_ms(10); //重置显示起始索引 read_index = 0; //设置删除成功标志 clearFlag = 1; // 已存在 clearFlag_timer = 3; // 显示3秒 } } // 分配地址勾选 if(SCR_setADDRFlag == 1) { SCR_setADDRFlag = 0; // 保证单次执行 if(paraMem.addr_FREE_Flg != 1) { paraMem.addr_FREE_Flg = 1; //若改为手动控制,则及时将当前地址写入EEPROM tmpWr[0] = bmsMem.E2_485Addr; EEPROM_WrMulByte(EE_ADDR,&tmpWr[0]); delay_ms(5); } else { paraMem.addr_FREE_Flg = 0; } } // 欠压强制复位按钮 if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_ForceDischarge, 7)) { SCR_Send("page12.b0.pic=106\xff\xff\xff"); // 配置中 force_discharge_flag = 1; //当前总体和单体欠压的报警/保护位都置0 bmsMem.bStatus1 &= ~0x0202; bmsMem.bStatus3 &= ~0x0A00; //状态位置1,更新计时起点 bmsMem.balanceStatus |= 0x0020; if(LSEErrFlag!=1) { uvofftimecount = RTC_GetCounter(); uvofftime = 300; } else { uvoff_Moni_Count = UVOff_MON_CNT; } SCR_Send("page12.b0.pic=107\xff\xff\xff"); // 成功启动,显示成功图标 } // 恢复默认参数按钮 if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_FactoryReset, 7)) { factory_reset_flag = 1; } //并机界面 if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_Parallel, 7)) { SCR_ParallelFlag = 1; SCR_PACKFlag = 0; if(bmsMem.E2_485Addr == 1) { SCR_Send("page page18\xff\xff\xff"); // 只发一次跳转 } } //汇总数据页跳转至电池页(跳转屏幕做,置1标志位) if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_Allpack, 7)) { SCR_ParallelFlag = 1; } //电池页跳转至汇总数据页(跳转屏幕做,清0标志位) if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_Allcell, 7)) { SCR_ParallelFlag = 0; } //跳转到单个电池页 if(SCR_ParallelFlag == 1) { if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_PACK1, 7)) { scr_RdData_Index = 1; SCR_PACKFlag = 1; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_PACK2, 7)) { scr_RdData_Index = 2; SCR_PACKFlag = 1; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_PACK3, 7)) { scr_RdData_Index = 3; SCR_PACKFlag = 1; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_PACK4, 7)) { scr_RdData_Index = 4; SCR_PACKFlag = 1; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_PACK5, 7)) { scr_RdData_Index = 5; SCR_PACKFlag = 1; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_PACK6, 7)) { scr_RdData_Index = 6; SCR_PACKFlag = 1; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_PACK7, 7)) { scr_RdData_Index = 7; SCR_PACKFlag = 1; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_PACK8, 7)) { scr_RdData_Index = 8; SCR_PACKFlag = 1; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_PACK9, 7)) { scr_RdData_Index = 9; SCR_PACKFlag = 1; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_PACK10, 7)) { scr_RdData_Index = 10; SCR_PACKFlag = 1; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_PACK11, 7)) { scr_RdData_Index = 11; SCR_PACKFlag = 1; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_PACK12, 7)) { scr_RdData_Index = 12; SCR_PACKFlag = 1; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_PACK13, 7)) { scr_RdData_Index = 13; SCR_PACKFlag = 1; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_PACK14, 7)) { scr_RdData_Index = 14; SCR_PACKFlag = 1; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_PACK15, 7)) { scr_RdData_Index = 15; SCR_PACKFlag = 1; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_PACK16, 7)) { scr_RdData_Index = 16; SCR_PACKFlag = 1; } } //短路保护电压 if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setSCVol_0, 7)) { flashUpdateFlag = 2; temp = 0; bmsMem.ee_scv_sct &= ~0xF0; bmsMem.ee_scv_sct |= temp<<4; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setSCVol_1, 7)) { flashUpdateFlag = 2; temp = 1; bmsMem.ee_scv_sct &= ~0xF0; bmsMem.ee_scv_sct |= temp<<4; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setSCVol_2, 7)) { flashUpdateFlag = 2; temp = 2; bmsMem.ee_scv_sct &= ~0xF0; bmsMem.ee_scv_sct |= temp<<4; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setSCVol_3, 7)) { flashUpdateFlag = 2; temp = 3; bmsMem.ee_scv_sct &= ~0xF0; bmsMem.ee_scv_sct |= temp<<4; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setSCVol_4, 7)) { flashUpdateFlag = 2; temp = 4; bmsMem.ee_scv_sct &= ~0xF0; bmsMem.ee_scv_sct |= temp<<4; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setSCVol_5, 7)) { flashUpdateFlag = 2; temp = 5; bmsMem.ee_scv_sct &= ~0xF0; bmsMem.ee_scv_sct |= temp<<4; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setSCVol_6, 7)) { flashUpdateFlag = 2; temp = 6; bmsMem.ee_scv_sct &= ~0xF0; bmsMem.ee_scv_sct |= temp<<4; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setSCVol_7, 7)) { flashUpdateFlag = 2; temp = 7; bmsMem.ee_scv_sct &= ~0xF0; bmsMem.ee_scv_sct |= temp<<4; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setSCVol_8, 7)) { flashUpdateFlag = 2; temp = 8; bmsMem.ee_scv_sct &= ~0xF0; bmsMem.ee_scv_sct |= temp<<4; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setSCVol_9, 7)) { flashUpdateFlag = 2; temp = 9; bmsMem.ee_scv_sct &= ~0xF0; bmsMem.ee_scv_sct |= temp<<4; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setSCVol_10, 7)) { flashUpdateFlag = 2; temp = 10; bmsMem.ee_scv_sct &= ~0xF0; bmsMem.ee_scv_sct |= temp<<4; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setSCVol_11, 7)) { flashUpdateFlag = 2; temp = 11; bmsMem.ee_scv_sct &= ~0xF0; bmsMem.ee_scv_sct |= temp<<4; } //短路保护延时 if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setSCTim_0, 7)) { flashUpdateFlag = 2; temp = 0; bmsMem.ee_scv_sct &= ~0x0F; bmsMem.ee_scv_sct |= temp; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setSCTim_1, 7)) { flashUpdateFlag = 2; temp = 1; bmsMem.ee_scv_sct &= ~0x0F; bmsMem.ee_scv_sct |= temp; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setSCTim_2, 7)) { flashUpdateFlag = 2; temp = 2; bmsMem.ee_scv_sct &= ~0x0F; bmsMem.ee_scv_sct |= temp; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setSCTim_3, 7)) { flashUpdateFlag = 2; temp = 3; bmsMem.ee_scv_sct &= ~0x0F; bmsMem.ee_scv_sct |= temp; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setSCTim_4, 7)) { flashUpdateFlag = 2; temp = 4; bmsMem.ee_scv_sct &= ~0x0F; bmsMem.ee_scv_sct |= temp; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setSCTim_5, 7)) { flashUpdateFlag = 2; temp = 5; bmsMem.ee_scv_sct &= ~0x0F; bmsMem.ee_scv_sct |= temp; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setSCTim_6, 7)) { flashUpdateFlag = 2; temp = 6; bmsMem.ee_scv_sct &= ~0x0F; bmsMem.ee_scv_sct |= temp; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setSCTim_7, 7)) { flashUpdateFlag = 2; temp = 7; bmsMem.ee_scv_sct &= ~0x0F; bmsMem.ee_scv_sct |= temp; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setSCTim_8, 7)) { flashUpdateFlag = 2; temp = 8; bmsMem.ee_scv_sct &= ~0x0F; bmsMem.ee_scv_sct |= temp; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setSCTim_9, 7)) { flashUpdateFlag = 2; temp = 9; bmsMem.ee_scv_sct &= ~0x0F; bmsMem.ee_scv_sct |= temp; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setSCTim_10, 7)) { flashUpdateFlag = 2; temp = 10; bmsMem.ee_scv_sct &= ~0x0F; bmsMem.ee_scv_sct |= temp; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setSCTim_11, 7)) { flashUpdateFlag = 2; temp = 11; bmsMem.ee_scv_sct &= ~0x0F; bmsMem.ee_scv_sct |= temp; } //设置逆变器协议 if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setProtocol_SolArk, 7)) { if(protocol_Index != 1) protocol_Index = 1; else protocol_Index = 0; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setProtocol_GoodWe, 7)) { if(protocol_Index != 2) protocol_Index = 2; else protocol_Index = 0; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setProtocol_Megarevo, 7)) { if(protocol_Index != 30) protocol_Index = 30; else protocol_Index = 0; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setProtocol_Pylon, 7)) { if(protocol_Index != 12) protocol_Index = 12; else protocol_Index = 0; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setProtocol_Deye, 7)) { if(protocol_Index != 11) protocol_Index = 11; else protocol_Index = 0; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setProtocol_MUST, 7)) { if(protocol_Index != 7) protocol_Index = 7; else protocol_Index = 0; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setProtocol_Solis, 7)) { if(protocol_Index != 37) protocol_Index = 37; else protocol_Index = 0; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setProtocol_Growatt, 7)) { if(protocol_Index != 3) protocol_Index = 3; else protocol_Index = 0; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setProtocol_Aiswei, 7)) { if(protocol_Index != 4) protocol_Index = 4; else protocol_Index = 0; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setProtocol_Afore, 7)) { if(protocol_Index != 35) protocol_Index = 35; else protocol_Index = 0; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setProtocol_Victron, 7)) { if(protocol_Index != 27) protocol_Index = 27; else protocol_Index = 0; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setProtocol_Sorotec, 7)) { if(protocol_Index != 6) protocol_Index = 6; else protocol_Index = 0; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setProtocol_SMA, 7)) { if(protocol_Index != 5) protocol_Index = 5; else protocol_Index = 0; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setProtocol_Sunways, 7)) { if(protocol_Index != 39) protocol_Index = 39; else protocol_Index = 0; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setProtocol_Luxpower, 7)) { if(protocol_Index != 23) protocol_Index = 23; else protocol_Index = 0; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setProtocol_Schneider, 7)) { if(protocol_Index != 24) protocol_Index = 24; else protocol_Index = 0; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setProtocol_AlpSolarr, 7)) { if(protocol_Index != 40) protocol_Index = 40; else protocol_Index = 0; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setProtocol_SRNE, 7)) { if(protocol_Index != 13) protocol_Index = 13; else protocol_Index = 0; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setProtocol_Voltronic, 7)) { if(protocol_Index != 14) protocol_Index = 14; else protocol_Index = 0; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setProtocol_COSUPER, 7)) { if(protocol_Index != 32) protocol_Index = 32; else protocol_Index = 0; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setProtocol_SMK, 7)) { if(protocol_Index != 17) protocol_Index = 17; else protocol_Index = 0; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setProtocol_SAKO, 7)) { if(protocol_Index != 31) protocol_Index = 31; else protocol_Index = 0; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setProtocol_SNADI, 7)) { if(protocol_Index != 18) protocol_Index = 18; else protocol_Index = 0; } else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_setProtocol_invt, 7)) { if(protocol_Index != 21) protocol_Index = 21; else protocol_Index = 0; } // else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_altProtocol_1, 7)) // { // //预留 // } // else if(findHexStr(SCR_Rx_Buf, SCR_RX_BUF_LEN, SCR_altProtocol_2, 7)) // { // //预留 // } if(protocol != protocol_Index) //协议更新才写入,减少访问次数 { protocol = protocol_Index; EEPROM_WrMulByte(EE_PROTOCOL,&protocol); delay_ms(5); uf_CAN1_Init(); //SCR_DispProcotol(); } char para_str[6]; //无符号整数0~65535 或 有符号整数-32768~32767 或小数 //最长6位 uint8_t len = 0; //字符串长度 uint8_t pmFlg = 0; //是负数的标志 uint8_t cotFlg = 0; //出现小数点的标志 uint8_t tmpWr[2]; uint8_t tmpRd[2]; // ===== 逆变器设置 (page9 id1~id4) ===== if(strstr(SCR_Rx_Buf, "9,1,")) // 逆变器充电限流 { len = GetStr("9,1,", '\xff', '\xff', SCR_Rx_Buf, para_str); if(len > 0) { for(i=0; i= '0' && para_str[i] <= '9') { temp = temp * 10 + (para_str[i] - '0'); } else if(para_str[i] == '.') { if((para_str[i+1] >= '0') && (para_str[i+1] <= '9')) { cotFlg = 1; temp = temp * 10 + (para_str[i+1] - '0'); } break; //遇到小数点,取后1位,剩下不算 } } if(cotFlg == 0) //没有小数点,值*10 { temp = temp * 10; } if((temp > 0) && (temp <= 20000)) //0.1~2000.0A { flashUpdateFlag = 1; bmsMem.inverter_chgCurLimit = temp; } } } else if(strstr(SCR_Rx_Buf, "9,2,")) // 逆变器充电限压 { len = GetStr("9,2,", '\xff', '\xff', SCR_Rx_Buf, para_str); if(len > 0) { for(i=0; i= '0' && para_str[i] <= '9') { temp = temp * 10 + (para_str[i] - '0'); } else if(para_str[i] == '.') { if((para_str[i+1] >= '0') && (para_str[i+1] <= '9')) { cotFlg = 1; temp = temp * 10 + (para_str[i+1] - '0'); } break; //遇到小数点,取后1位,剩下不算 } } if(cotFlg == 0) //没有小数点,值*10 { temp = temp * 10; } if((temp > 0) && (temp <= 1000)) //0.1~100.0V { flashUpdateFlag = 1; bmsMem.inverter_chgVolLimit = temp; } } } else if(strstr(SCR_Rx_Buf, "9,3,")) // 逆变器放电限流 { len = GetStr("9,3,", '\xff', '\xff', SCR_Rx_Buf, para_str); if(len > 0) { for(i=0; i= '0' && para_str[i] <= '9') { temp = temp * 10 + (para_str[i] - '0'); } else if(para_str[i] == '.') { if((para_str[i+1] >= '0') && (para_str[i+1] <= '9')) { cotFlg = 1; temp = temp * 10 + (para_str[i+1] - '0'); } break; //遇到小数点,取后1位,剩下不算 } } if(cotFlg == 0) //没有小数点,值*10 { temp = temp * 10; } if((temp > 0) && (temp <= 20000)) //0.1~2000.0A { flashUpdateFlag = 1; bmsMem.inverter_dsgCurLimit = temp; } } } else if(strstr(SCR_Rx_Buf, "9,4,")) // 逆变器放电限压 { len = GetStr("9,4,", '\xff', '\xff', SCR_Rx_Buf, para_str); if(len > 0) { for(i=0; i= '0' && para_str[i] <= '9') { temp = temp * 10 + (para_str[i] - '0'); } else if(para_str[i] == '.') { if((para_str[i+1] >= '0') && (para_str[i+1] <= '9')) { cotFlg = 1; temp = temp * 10 + (para_str[i+1] - '0'); } break; //遇到小数点,取后1位,剩下不算 } } if(cotFlg == 0) //没有小数点,值*10 { temp = temp * 10; } if((temp > 0) && (temp <= 1000)) //0.1~100.0V { flashUpdateFlag = 1; bmsMem.inverter_dsgVolLimit = temp; } } } // ===== BMS过流保护 (page9 id5~id6) ===== else if(strstr(SCR_Rx_Buf, "9,5,")) // 充电过流保护值 { len = GetStr("9,5,", '\xff', '\xff', SCR_Rx_Buf, para_str); if(len > 0) { temp = 0; for(i=0; i= '0' && para_str[i] <= '9') temp = temp * 10 + (para_str[i] - '0'); else break; // 遇到非数字停止 } if(temp <= 255) // uint8_t 范围 { flashUpdateFlag = 2; bmsMem.mcu_occ = (uint8_t)temp; } } } else if(strstr(SCR_Rx_Buf, "9,6,")) // 放电过流保护值 { len = GetStr("9,6,", '\xff', '\xff', SCR_Rx_Buf, para_str); if(len > 0) { temp = 0; for(i=0; i= '0' && para_str[i] <= '9') temp = temp * 10 + (para_str[i] - '0'); else break; } if(temp <= 255) { flashUpdateFlag = 2; bmsMem.mcu_ocd = (uint8_t)temp; } } } // ===== 充电温度保护 (page10 id1~id4) ===== else if(strstr(SCR_Rx_Buf, "10,1,")) // 充电高温保护值 { len = GetStr("10,1,", '\xff', '\xff', SCR_Rx_Buf, para_str); if(len > 0) { for(i=0;i= '0') && (para_str[i] <= '9')) { temp = temp * 10 + (para_str[i] - '0'); } else if(para_str[i] == '.') { break; //遇到小数点,剩下不算 } } if((pmFlg == 0) && (temp <= 115)) //-45~115℃ { flashUpdateFlag = 2; bmsMem.mcu_otc = temp; } else if((pmFlg == 1) && (temp <= 45)) //-45~115℃ { flashUpdateFlag = 2; bmsMem.mcu_otc = -temp; } } } else if(strstr(SCR_Rx_Buf, "10,2,")) // 充电高温释放值 { len = GetStr("10,2,", '\xff', '\xff', SCR_Rx_Buf, para_str); if(len > 0) { for(i=0;i= '0') && (para_str[i] <= '9')) { temp = temp * 10 + (para_str[i] - '0'); } else if(para_str[i] == '.') { break; //遇到小数点,剩下不算 } } if((pmFlg == 0) && (temp <= 115)) //-45~115℃ { flashUpdateFlag = 2; bmsMem.mcu_otcr = temp; } else if((pmFlg == 1) && (temp <= 45)) //-45~115℃ { flashUpdateFlag = 2; bmsMem.mcu_otcr = -temp; } } } else if(strstr(SCR_Rx_Buf, "10,3,")) // 充电低温保护值 { len = GetStr("10,3,", '\xff', '\xff', SCR_Rx_Buf, para_str); if(len > 0) { for(i=0;i= '0') && (para_str[i] <= '9')) { temp = temp * 10 + (para_str[i] - '0'); } else if(para_str[i] == '.') { break; //遇到小数点,剩下不算 } } if((pmFlg == 0) && (temp <= 115)) //-45~115℃ { flashUpdateFlag = 2; bmsMem.mcu_utc = temp; } else if((pmFlg == 1) && (temp <= 45)) //-45~115℃ { flashUpdateFlag = 2; bmsMem.mcu_utc = -temp; } } } else if(strstr(SCR_Rx_Buf, "10,4,")) // 充电低温释放值 { len = GetStr("10,4,", '\xff', '\xff', SCR_Rx_Buf, para_str); if(len > 0) { for(i=0;i= '0') && (para_str[i] <= '9')) { temp = temp * 10 + (para_str[i] - '0'); } else if(para_str[i] == '.') { break; //遇到小数点,剩下不算 } } if((pmFlg == 0) && (temp <= 115)) //-45~115℃ { flashUpdateFlag = 2; bmsMem.mcu_utcr = temp; } else if((pmFlg == 1) && (temp <= 45)) //-45~115℃ { flashUpdateFlag = 2; bmsMem.mcu_utcr = -temp; } } } // ===== 放电温度保护 (page10 id5~id8) ===== else if(strstr(SCR_Rx_Buf, "10,5,")) // 放电高温保护值 { len = GetStr("10,5,", '\xff', '\xff', SCR_Rx_Buf, para_str); if(len > 0) { for(i=0;i= '0') && (para_str[i] <= '9')) { temp = temp * 10 + (para_str[i] - '0'); } else if(para_str[i] == '.') { break; //遇到小数点,剩下不算 } } if((pmFlg == 0) && (temp <= 115)) //-45~115℃ { flashUpdateFlag = 2; bmsMem.mcu_otd = temp; } else if((pmFlg == 1) && (temp <= 45)) //-45~115℃ { flashUpdateFlag = 2; bmsMem.mcu_otd = -temp; } } } else if(strstr(SCR_Rx_Buf, "10,6,")) // 放电高温释放值 { len = GetStr("10,6,", '\xff', '\xff', SCR_Rx_Buf, para_str); if(len > 0) { for(i=0;i= '0') && (para_str[i] <= '9')) { temp = temp * 10 + (para_str[i] - '0'); } else if(para_str[i] == '.') { break; //遇到小数点,剩下不算 } } if((pmFlg == 0) && (temp <= 115)) //-45~115℃ { flashUpdateFlag = 2; bmsMem.mcu_otdr = temp; } else if((pmFlg == 1) && (temp <= 45)) //-45~115℃ { flashUpdateFlag = 2; bmsMem.mcu_otdr = -temp; } } } else if(strstr(SCR_Rx_Buf, "10,7,")) // 放电低温保护值 { len = GetStr("10,7,", '\xff', '\xff', SCR_Rx_Buf, para_str); if(len > 0) { for(i=0;i= '0') && (para_str[i] <= '9')) { temp = temp * 10 + (para_str[i] - '0'); } else if(para_str[i] == '.') { break; //遇到小数点,剩下不算 } } if((pmFlg == 0) && (temp <= 115)) //-45~115℃ { flashUpdateFlag = 2; bmsMem.mcu_utd = temp; } else if((pmFlg == 1) && (temp <= 45)) //-45~115℃ { flashUpdateFlag = 2; bmsMem.mcu_utd = -temp; } } } else if(strstr(SCR_Rx_Buf, "10,8,")) // 放电低温释放值 { len = GetStr("10,8,", '\xff', '\xff', SCR_Rx_Buf, para_str); if(len > 0) { for(i=0;i= '0') && (para_str[i] <= '9')) { temp = temp * 10 + (para_str[i] - '0'); } else if(para_str[i] == '.') { break; //遇到小数点,剩下不算 } } if((pmFlg == 0) && (temp <= 115)) //-45~115℃ { flashUpdateFlag = 2; bmsMem.mcu_utdr = temp; } else if((pmFlg == 1) && (temp <= 45)) //-45~115℃ { flashUpdateFlag = 2; bmsMem.mcu_utdr = -temp; } } } // ===== 电压保护 (page11 id1~id4) ===== else if(strstr(SCR_Rx_Buf, "11,1,")) // 充电过压保护值 (单体) { len = GetStr("11,1,", '\xff', '\xff', SCR_Rx_Buf, para_str); if(len > 0) { for(i=0;i= '0') && (para_str[i] <= '9')) { temp = temp * 10 + (para_str[i] - '0'); } else if(para_str[i] == '.') { break; //遇到小数点,剩下不算 } } if((temp >= 3500) && (temp <= 3750)) //3500mV~3750mV { flashUpdateFlag = 2; temp = temp/5; bmsMem.ee_ovt_ldrt_ovh &= 0xfc;//~0x03 bmsMem.ee_ovt_ldrt_ovh += (temp & 0x0300) >>8; bmsMem.ee_ovl = temp & 0x00ff; } } } else if(strstr(SCR_Rx_Buf, "11,2,")) // 充电过压释放值 { len = GetStr("11,2,", '\xff', '\xff', SCR_Rx_Buf, para_str); if(len > 0) { for(i=0; i= '0') && (para_str[i] <= '9')) { temp = temp * 10 + (para_str[i] - '0'); } else if(para_str[i] == '.') { break; //遇到小数点,剩下不算 } } if(temp >= 3300 && temp <= 3700) { flashUpdateFlag = 2; temp = temp / 5; bmsMem.ee_uvt_ovrh = (bmsMem.ee_uvt_ovrh & 0xfc) | ((temp >> 8) & 0x03); bmsMem.ee_ovrl = temp & 0xff; } } } else if(strstr(SCR_Rx_Buf, "11,3,")) // 充电欠压保护值 (单体) { len = GetStr("11,3,", '\xff', '\xff', SCR_Rx_Buf, para_str); if(len > 0) { for(i=0;i= '0') && (para_str[i] <= '9')) { temp = temp * 10 + (para_str[i] - '0'); } else if(para_str[i] == '.') { break; //遇到小数点,剩下不算 } } if((temp >= 2000) && (temp <= 3500)) //2000mV~3500mV { flashUpdateFlag = 2; temp = temp/20; bmsMem.ee_uv = temp; } } } else if(strstr(SCR_Rx_Buf, "11,4,")) // 充电欠压释放值 { len = GetStr("11,4,", '\xff', '\xff', SCR_Rx_Buf, para_str); if(len > 0) { temp = 0; for(int i=0; i= '0') && (para_str[i] <= '9')) { temp = temp * 10 + (para_str[i] - '0'); } else if(para_str[i] == '.') { break; //遇到小数点,剩下不算 } } if(temp >= 2000 && temp <= 3500) { flashUpdateFlag = 2; temp = temp / 20; bmsMem.ee_uvr = temp; } } } // ===== 其他 (page14 id1~id2) ===== //写地址 else if(strstr(SCR_Rx_Buf, "14,1,")) { len = GetStr("14,1,", '\xff', '\xff', SCR_Rx_Buf, para_str); if(len > 0) { temp = 0; for(i = 0; i < len; i++) { if(para_str[i] >= '0' && para_str[i] <= '9') temp = temp * 10 + (para_str[i] - '0'); else break; } if((temp >= 1) && (temp <= AddrMax)) { if(bmsMem.E2_485Addr == 1) //作为主机 { if((scr_RdData_Index>=2) && (scr_RdData_Index<=paraMem.PACK_NUM)) //想通过主机修改从机地址 { if((temp != 1) && (temp <= paraMem.PACK_NUM)) { sdwa_WrAddr = temp; sdwa_WrAddr_Flg = 1; } } else //修改主机地址 { if(paraMem.addr_FREE_Flg != 0) //只有允许手动改地址,才能改主机 { tmpWr[0] = temp; EEPROM_WrMulByte(EE_ADDR,&tmpWr[0]); delay_ms(5); EEPROM_RdMulByte(EE_ADDR,&tmpRd[0]); bmsMem.E2_485Addr = tmpRd[0]; tmpWr[0] = 0; tmpWr[1] = 0; bmsMem.can_ArrayIndex = 0; EEPROM_WrMulByte(EE_ASSIGN,tmpWr); delay_ms(5); scr_RdData_Index = bmsMem.E2_485Addr; } } } else //作为从机 { if((temp != 1) || (paraMem.addr_FREE_Flg != 0)) //只有允许手动改地址,才能改1 { tmpWr[0] = temp; EEPROM_WrMulByte(EE_ADDR,&tmpWr[0]); delay_ms(5); EEPROM_RdMulByte(EE_ADDR,&tmpRd[0]); bmsMem.E2_485Addr = tmpRd[0]; tmpWr[0] = 0; tmpWr[1] = 0; bmsMem.can_ArrayIndex = 0; EEPROM_WrMulByte(EE_ASSIGN,tmpWr); delay_ms(5); scr_RdData_Index = bmsMem.E2_485Addr; } } } } } //写容量 else if(strstr(SCR_Rx_Buf, "14,2,")) { len = GetStr("14,2,", '\xff', '\xff', SCR_Rx_Buf, para_str); if(len > 0) { for(int i=0;i= '0') && (para_str[i] <= '9')) { temp = temp * 10 + (para_str[i] - '0'); } else if(para_str[i] == '.') { break; //遇到小数点,剩下不算 } } if((temp >= 1) && (temp <= 1000)) //1~1000Ah { //写入额定容量到 EEPROM uint8_t tmpWr[2]; tmpWr[0] = (temp >> 8) & 0xFF; tmpWr[1] = temp & 0xFF; EEPROM_WrMulByte(EE_NCC, tmpWr); delay_ms(5); //重新读取 ncc_Ah uint8_t tmpRd[2]; EEPROM_RdMulByte(EE_NCC, tmpRd); ncc_Ah = (tmpRd[0] << 8) | tmpRd[1]; bmsMem.ncc = 3600 * 1000 * ncc_Ah; //满充容量设为额定容量 fcc = bmsMem.ncc; fcc_Ah = ncc_Ah; uint8_t tmpFCC[8]; tmpFCC[0] = (fcc >> 24) & 0xFF; tmpFCC[1] = (fcc >> 16) & 0xFF; tmpFCC[2] = (fcc >> 8) & 0xFF; tmpFCC[3] = fcc & 0xFF; tmpFCC[4] = tmpFCC[0] ^ 0xFF; tmpFCC[5] = tmpFCC[1] ^ 0xFF; tmpFCC[6] = tmpFCC[2] ^ 0xFF; tmpFCC[7] = tmpFCC[3] ^ 0xFF; EEPROM_WrMulByte(EE_FCC, tmpFCC); delay_ms(20); //更新剩余容量 bmsMem.rcc = fcc / 100 * bmsMem.soc; rcc_Ah = fcc_Ah * bmsMem.soc / 100; oldrcc_Ah = rcc_Ah; } } } Screen_ClearBuf(); } }