/** ****************************************************************************** * @file tim.c * @author Jerry * @version V2.1 * @date 19-April-2022 * @brief tim program body. ****************************************************************************** * @attention * * ****************************************************************************** */ /* Includes ------------------------------------------------------------------*/ #include "stm32f10x.h" #include "global.h" #include "rtc.h" #include "soe.h" #include "AFE_SH367309.h" #include "string.h" #define VAR_CHARGE 0 #define VAR_DISCHARGE 1 #define VAR_FAULT 2 #define VAR_ON 3 #define VAR_OFF 4 //AFE过流保护对应采集电压值, //单位mV,要转换为电流值 //取x8,用MCU过流保护电流和其比较,选择稍大一点的值 //const uint16_t OCD1V[16]= //{ // 20, 30, 40, 50, // 60, 70, 80, 90, // 100,110,120,130, // 140,160,180,200 //}; //const uint16_t OCD2V[16]= //{ // 30, 40, 50, 60, // 70, 80, 90,100, // 120,140,160,180, // 200,300,400,500 //}; //const uint16_t OCCV[16]= //{ // 20, 30, 40, 50, // 60, 70, 80, 90, // 100,110,120,130, // 140,160,180,200 //}; uint8_t protocol; //逆变器通信协议 //uint8_t language; //屏幕语言 uint8_t sdwaBuf[20]; uint8_t sdwaBufIndex; uint8_t sdwaMoniCount; uint8_t sdwaRecvFlag; uint8_t read_index; uint8_t recordBuf[64]; char sendRecord[64]; uint8_t initFlag; //初始化配置参数 uint8_t clearFlag; //清除报警记录 uint8_t EE_clearFlag; //特殊按钮,点按清空EEPROM uint8_t sdwa_sleep_flag; //用于排除平时接收亮度的报文 uint8_t scr_WrZero_Flg; //屏幕写零点校准 uint8_t scr_WrGain_Flg; //屏幕写增益校准 uint8_t scr_RdData_Index;//屏幕显示数据的地址,默认是自身地址,且只有addr=1可以变化该地址 uint8_t scr_RdRecord_Flg;//屏幕只可以查看自身记录;当记录更新/清空/收到清空指令/进记录页面/上下翻动时,才会读EEPROM更新一次屏幕记录内容 uint8_t bAlarmFlagOld_slave; //主机屏幕显示从机报警的跳转 uint8_t sdwa_ExitTotal_Flg; //主机地址变化为从机,需要变化后退出总数据页 //用于发送数据/显示图标 //A5 5A 05 82 01 87 00 00 void SDWA_Send_VAR(uint16_t addr, uint16_t data) { USART_SendData(USART2, 0xA5); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x5A); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x05); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x82); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, (addr&0xff00)>>8); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, (addr&0x00ff)); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, (data>>8) & 0xff); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, (data & 0xff) ); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); } //页面跳转函数 void SDWA_JumpToNumber(uint16_t number) { USART_SendData(USART2, 0xA5); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x5A); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x04); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x80); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x03); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x00); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, number); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); } //开机和息屏跳转时,根据语言跳转首页 void SDWA_JumpToHome(void) { // if(language == 0) // { SDWA_JumpToNumber(1); // } // else if(language == 1) // { // SDWA_JumpToNumber(29); // } } //改变屏幕背光亮度 uint8_t LightChange_flg; void SDWA_ChangeLight(uint8_t light) { if(LightChange_flg == 0) { LightChange_flg = 1; USART_SendData(USART2, 0xA5); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x5A); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x03); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x80); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x01); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, light); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); } } //当关机时,若收到摁亮屏幕报文,控制灭 void SDWA_KeepLight0(void) { if(sdwaRecvFlag == 1) { sdwaRecvFlag = 0; sdwaBufIndex = 0; if((sdwaBuf[0] == 0xA5) && (sdwaBuf[1] == 0x5A)) { if((sdwaBuf[2]==0x04) && (sdwaBuf[3]==0x81) && ( (sdwaBuf[6]>=0x20) && (sdwaBuf[6]<=0x40) )) { LightChange_flg = 0; SDWA_ChangeLight(0); } } } } /**4G状态的显示**/ uint8_t LTEStatus_flg; //要传状态的标志 char LTEStatus_str[41]; //4G状态文本 void SDWA_Send_LTE(uint16_t addr) { uint8_t i; uint8_t len = strlen(LTEStatus_str); //最大长度20,对应ASCII码40个 USART_SendData(USART2, 0xA5); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x5A); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, len+3); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x82); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, (addr&0xff00)>>8); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, (addr&0x00ff)); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); for(i=0;i>8); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, (addr&0x00ff)); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); if(data[0] < 10) { USART_SendData(USART2, 0x30+data[0]); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); } else { USART_SendData(USART2, 0x30+data[0]/10); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+data[0]%10); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); } USART_SendData(USART2, '.'); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); if(data[1] < 10) { USART_SendData(USART2, 0x30+data[1]); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); } else { USART_SendData(USART2, 0x30+data[1]/10); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+data[1]%10); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); } USART_SendData(USART2, '.'); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); if(data[2] < 10) { USART_SendData(USART2, 0x30+data[2]); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); } else if(data[2] < 0xA0) //软件版本不是特殊版 { USART_SendData(USART2, 0x30+data[2]/10); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+data[2]%10); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); } else { USART_SendData(USART2, 'A'+data[2]/16-0x0A); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+data[2]%16); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); } USART_SendData(USART2, '.'); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); if(data[3] < 10) { USART_SendData(USART2, 0x30+data[3]); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); } else { USART_SendData(USART2, 0x30+data[3]/10); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+data[3]%10); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); } USART_SendData(USART2, 0xff ); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0xff ); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); } //显示硬件版本号 0x02D6 void SDWA_Send_VER_HARD(uint16_t addr, uint8_t *data) { USART_SendData(USART2, 0xA5); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x5A); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x0A); //5+5 while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x82); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, (addr&0xff00)>>8); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, (addr&0x00ff)); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+data[0]); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, '.'); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+data[1]); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, '.'); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); if(data[2] < 0x41) //硬件版本没有字母 { USART_SendData(USART2, 0x30+data[2]); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); } else { USART_SendData(USART2, data[2]); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); } USART_SendData(USART2, 0xff ); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0xff ); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); } //显示屏幕号 0x02E9 void SDWA_Send_VER_SCRN(uint16_t addr, uint8_t data) { uint16_t list1,list2; //最高两位表示型号,00对应028,01对应035,10对应042,11对应070 //剩下6位表示序号Index,范围0~63,显示为1~64 (028的要排除0/1/2/3为特殊项,从0x04开始) if((data>>6 == 0x00) && (data >= 0x04)) { list1 = 28; list2 = (data & 0x3f) +1-4; } else if(data>>6 == 0x01) { list1 = 35; list2 = (data & 0x3f) +1; } else if(data>>6 == 0x02) { list1 = 43; list2 = (data & 0x3f) +1; } else if(data>>6 == 0x03) { list1 = 70; list2 = (data & 0x3f) +1; } else { return; //型号以外的(比如=0),不显示 } USART_SendData(USART2, 0xA5); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x5A); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x0A); //5+5 while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x82); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, (addr&0xff00)>>8); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, (addr&0x00ff)); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+list1/100); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+list1/10%10); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+list1%10); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+list2/10); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+list2%10); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0xff ); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0xff ); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); } //显示BMS的SN号 //0x02CD void SDWA_Send_VER_BMSSN(uint16_t addr, uint8_t *data) { uint8_t i; USART_SendData(USART2, 0xA5); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x5A); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x0E); //9+5 while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x82); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, (addr&0xff00)>>8); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, (addr&0x00ff)); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); for(i=0;i<9;i++) { USART_SendData(USART2, data[i]); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); } USART_SendData(USART2, 0xff ); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0xff ); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); } //显示PACK的SN号 //0x02C0 void SDWA_Send_VER_PACKSN(uint16_t addr, uint8_t *data) { uint8_t i; uint8_t n=0; //有几个有效字符 for(i=0;i<15;i++) { if(data[i]!=0xff) { n++; } } USART_SendData(USART2, 0xA5); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x5A); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, n+5); //length while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x82); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, (addr&0xff00)>>8); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, (addr&0x00ff)); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); for(i=0;i0:00 void SDWA_Send_TimeCount(uint16_t addr,uint16_t countdown) { uint8_t min=countdown/60; uint8_t sec=countdown%60; USART_SendData(USART2, 0xA5); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x5A); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x0A); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x82); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, (addr&0xff00)>>8); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, (addr&0x00ff)); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+min/10); //min while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+min%10); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, ':'); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+sec/10); //sec while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+sec%10); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0xff ); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0xff ); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); } //0x0020,文本传输:2023-08-07 14:00:00 //A5 5A 0A 82 00 20 year month date week hour min sec void SDWA_Send_Time(uint16_t addr) { USART_SendData(USART2, 0xA5); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x5A); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x18); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x82); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, (addr&0xff00)>>8); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, (addr&0x00ff)); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+calendar.w_date/16); //day while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+calendar.w_date%16); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, '/'); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+calendar.w_month/16); //month while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+calendar.w_month%16); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, '/'); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, '2'); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, '0'); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+calendar.w_year/16); //year while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+calendar.w_year%16); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, ' '); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+calendar.hour/16); //hour while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+calendar.hour%16); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, ':'); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+calendar.min/16); //min while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+calendar.min%16); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, ':'); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+calendar.sec/16); //sec while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+calendar.sec%16); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0xff ); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0xff ); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); } /**报警记录的显示**/ //0x0040,0x0080,0x00C0 void SDWA_Send_RecordTime(uint16_t addr) { uint8_t time[6]; time[0] = recordBuf[4]; //year time[1] = recordBuf[5]; //month time[2] = recordBuf[6]; //date time[3] = recordBuf[7]; //hour time[4] = recordBuf[8]; //min time[5] = recordBuf[9]; //sec USART_SendData(USART2, 0xA5); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x5A); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x18); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x82); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, (addr&0xff00)>>8); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, (addr&0x00ff)); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+time[2]/16); //day while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+time[2]%16); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, '/'); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+time[1]/16); //month while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+time[1]%16); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, '/'); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, '2'); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, '0'); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+time[0]/16); //year while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+time[0]%16); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, ' '); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+time[3]/16); //hour while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+time[3]%16); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, ':'); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+time[4]/16); //min while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+time[4]%16); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, ':'); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+time[5]/16); //sec while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x30+time[5]%16); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0xff ); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0xff ); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); } //0x0060,0x00A0,0x00E0 void SDWA_Send_Record(uint16_t addr) { uint16_t bStatus1; uint16_t bStatus2; uint16_t bStatus3; uint16_t temperaStatus; uint8_t i; uint8_t sendcount; char *p = &sendRecord[0]; if((recordBuf[50] == 0x05) && (recordBuf[51] == 0xA5)) //旧报警记录格式 { bStatus1 = recordBuf[44]; bStatus2 = recordBuf[45]; bStatus3 = recordBuf[46]; temperaStatus = recordBuf[47]; } else //新报警记录格式 //宁化时代新增保护,把recordBuf[15]拆分到原来的位置 { bStatus1 = (recordBuf[15] & 0xf0) <<4 | recordBuf[10]; bStatus2 = recordBuf[11]; bStatus3 = recordBuf[12]; temperaStatus = (recordBuf[15] & 0x0f) <<8 | recordBuf[13]; } sendcount = 0; for(i=0;i<64;i++) { sendRecord[i]=0; } /*电压*/ if((bStatus1 & 0x0100) != 0) //总体过压 { sendcount +=8; *p = 'P'; p++; *p = 'a'; p++; *p = 'c'; p++; *p = 'k'; p++; *p = '_'; p++; *p = 'O'; p++; *p = 'V'; p++; *p = ' '; p++; } if((bStatus1 & 0x0200) != 0) //总体欠压 { sendcount +=8; *p = 'P'; p++; *p = 'a'; p++; *p = 'c'; p++; *p = 'k'; p++; *p = '_'; p++; *p = 'U'; p++; *p = 'V'; p++; *p = ' '; p++; } if((bStatus1 & 0x0001) != 0) //单体过压 { sendcount +=3; *p = 'O'; p++; *p = 'V'; p++; *p = ' '; p++; } if((bStatus1 & 0x0002) != 0) //单体欠压 { sendcount +=3; *p = 'U'; p++; *p = 'V'; p++; *p = ' '; p++; } if((bStatus1 & 0x0040) !=0) //异常高压保护 { sendcount +=3; *p = 'P'; p++; *p = 'F'; p++; *p = ' '; p++; } if((bStatus3 & 0x0008) !=0) //低电压禁止充电 { sendcount +=4; *p = 'L'; p++; *p = '0'; p++; *p = 'V'; p++; *p = ' '; p++; } /**电流**/ if(((bStatus1 & 0x0010) != 0) || ((temperaStatus & 0x0010) != 0)) //充电过流 { sendcount +=4; *p = 'O'; p++; *p = 'C'; p++; *p = 'C'; p++; *p = ' '; p++; } if(((bStatus1 & 0x042C) != 0) || ((temperaStatus & 0x0020) != 0)) //放电过流1/2 { sendcount +=4; *p = 'O'; p++; *p = 'C'; p++; *p = 'D'; p++; *p = ' '; p++; } if((bStatus1 & 0x0020) !=0) //浪涌短路 { sendcount +=3; *p = 'S'; p++; *p = 'C'; p++; *p = ' '; p++; } if((bStatus2 & 0x0010) !=0) //真短路保护 { sendcount +=8; *p = 'S'; p++; *p = 'C'; p++; *p = '_'; p++; *p = 'L'; p++; *p = 'o'; p++; *p = 'c'; p++; *p = 'k'; p++; *p = ' '; p++; } /**温度**/ if(((bStatus2 & 0x0001) !=0) || ((temperaStatus & 0x0404) !=0)) //充电低温 { sendcount +=4; *p = 'U'; p++; *p = 'T'; p++; *p = 'C'; p++; *p = ' '; p++; } if(((bStatus2 & 0x0002) !=0) || ((temperaStatus & 0x0101) !=0)) //充电高温 { sendcount +=4; *p = 'O'; p++; *p = 'T'; p++; *p = 'C'; p++; *p = ' '; p++; } if(((bStatus2 & 0x0004) !=0) || ((temperaStatus & 0x0808) !=0)) //放电低温 { sendcount +=4; *p = 'U'; p++; *p = 'T'; p++; *p = 'D'; p++; *p = ' '; p++; } if(((bStatus2 & 0x0008) !=0) || ((temperaStatus & 0x0202) !=0)) //放电高温 { sendcount +=4; *p = 'O'; p++; *p = 'T'; p++; *p = 'D'; p++; *p = ' '; p++; } /**故障**/ if((temperaStatus & 0x0040) !=0) //急停 RPSD_Activated { sendcount +=15; *p = 'R'; p++; *p = 'P'; p++; *p = 'S'; p++; *p = 'D'; p++; *p = '_'; p++; *p = 'A'; p++; *p = 'c'; p++; *p = 't'; p++; *p = 'i'; p++; *p = 'v'; p++; *p = 'a'; p++; *p = 't'; p++; *p = 'e'; p++; *p = 'd'; p++; *p = ' '; p++; } if((bStatus2 & 0x0040) !=0) //放电MOS故障 { sendcount +=11; *p = 'D'; p++; *p = '-'; p++; *p = 'M'; p++; *p = 'O'; p++; *p = 'S'; p++; *p = 'f'; p++; *p = 'a'; p++; *p = 'u'; p++; *p = 'l'; p++; *p = 't'; p++; *p = ' '; p++; } if((bStatus2 & 0x0080) !=0) //充电MOS故障 { sendcount +=11; *p = 'C'; p++; *p = '-'; p++; *p = 'M'; p++; *p = 'O'; p++; *p = 'S'; p++; *p = 'f'; p++; *p = 'a'; p++; *p = 'u'; p++; *p = 'l'; p++; *p = 't'; p++; *p = ' '; p++; } if((bStatus2 & 0x0020) !=0) //预充失败 { sendcount +=10; *p = 'P'; p++; *p = 'C'; p++; *p = 'H'; p++; *p = 'G'; p++; *p = '_'; p++; *p = 'F'; p++; *p = 'a'; p++; *p = 'i'; p++; *p = 'l'; p++; *p = ' '; p++; } USART_SendData(USART2, 0xA5); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x5A); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, sendcount+3); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x82); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, (addr&0xff00)>>8); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, (addr&0x00ff)); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); for(i=0;i>8); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, (addr&0x00ff)); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); for(i=0;i<64;i++) { USART_SendData(USART2, sendRecord[i]); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); } __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); __nop(); } /**报警页面的显示**/ void SDWA_ClearAlarm(void) { //报警内容显示 //单体过压 SDWA_Send_VAR(0x0187, 0); //单体欠压 SDWA_Send_VAR(0x0193, 0); //充电过流 SDWA_Send_VAR(0x0188, 0); //放电过流 SDWA_Send_VAR(0x0194, 0); //充电高温 SDWA_Send_VAR(0x0189, 0); //充电低温 SDWA_Send_VAR(0x0195, 0); //放电高温 SDWA_Send_VAR(0x0190, 0); //放电低温 SDWA_Send_VAR(0x0196, 0); //异常高压 SDWA_Send_VAR(0x0191, 0); //低压禁止充电 SDWA_Send_VAR(0x0197, 0); //短路保护 SDWA_Send_VAR(0x0192, 0); } void SDWA_ShowAlarm(void) { //报警内容显示 //单体过压&总体过压 if(((bmsMem.bStatus1 & 0x0001) != 0) || ((bmsMem.bStatus1 & 0x0100) != 0)) { if(bmsMem.soc<99) { SDWA_Send_VAR(0x0187, 1); } else //当SOC大于99%,此时触发过压报警,不会跳转屏幕,也不会亮报警灯 { SDWA_Send_VAR(0x0187, 0); } } else { SDWA_Send_VAR(0x0187, 0); } //单体欠压&总体欠压 if(((bmsMem.bStatus1 & 0x0002) != 0) || ((bmsMem.bStatus1 & 0x0200) != 0)) { SDWA_Send_VAR(0x0193, 1); } else { SDWA_Send_VAR(0x0193, 0); } //afe充电过流&充电过流 if(((bmsMem.bStatus1 & 0x0010) != 0) || ((bmsMem.temperaStatus & 0x0010) != 0)) { SDWA_Send_VAR(0x0188, 1); } else { SDWA_Send_VAR(0x0188, 0); } //afe放电过流&放电过流1&放电过流2 if(((bmsMem.bStatus1 & 0x000c) != 0) || ((bmsMem.temperaStatus & 0x0020) != 0) || ((bmsMem.bStatus1 & 0x0400) != 0)) { SDWA_Send_VAR(0x0194, 1); } else { SDWA_Send_VAR(0x0194, 0); } //afe充电高温&环境充电高温&电芯充电高温 if(((bmsMem.bStatus2 & 0x0002) != 0) || ((bmsMem.temperaStatus & 0x0100) != 0) || ((bmsMem.temperaStatus & 0x0001) != 0)) { SDWA_Send_VAR(0x0189, 1); } else { SDWA_Send_VAR(0x0189, 0); } //afe放电高温&环境放电高温&电芯放电高温 if(((bmsMem.bStatus2 & 0x0008) != 0) || ((bmsMem.temperaStatus & 0x0200) != 0) || ((bmsMem.temperaStatus & 0x0002) != 0)) { SDWA_Send_VAR(0x0190, 1); } else { SDWA_Send_VAR(0x0190, 0); } //afe充电低温&环境充电低温&电芯充电低温 if(((bmsMem.bStatus2 & 0x0001) != 0) || ((bmsMem.temperaStatus & 0x0400) != 0) || ((bmsMem.temperaStatus & 0x0004) != 0)) { SDWA_Send_VAR(0x0195, 1); } else { SDWA_Send_VAR(0x0195, 0); } //afe放电低温&环境放电低温&电芯放电低温 if(((bmsMem.bStatus2 & 0x0004) != 0) || ((bmsMem.temperaStatus & 0x0800) != 0) || ((bmsMem.temperaStatus & 0x0008) != 0)) { SDWA_Send_VAR(0x0196, 1); } else { SDWA_Send_VAR(0x0196, 0); } //异常高压 if((bmsMem.bStatus1 & 0x0040) != 0) { SDWA_Send_VAR(0x0191, 1); } else { SDWA_Send_VAR(0x0191, 0); } //低压禁止充电 if((bmsMem.bStatus3 & 0x0008) != 0) { SDWA_Send_VAR(0x0197, 1); } else { SDWA_Send_VAR(0x0197, 0); } //真短路保护 if((bmsMem.bStatus2 & 0x0010) != 0) //只有预充情况才会出现短路锁定,出现则一直保持,这里也一直显示 { SDWA_Send_VAR(0x0192, 1); } //浪涌短路保护 else if((bmsMem.bStatus1 & 0x0020) != 0) { SDWA_Send_VAR(0x0192, 1); } else { SDWA_Send_VAR(0x0192, 0); } } void SDWA_ShowAlarm_Slave(void) //读取的从机报警数据的显示 { //报警内容显示 //单体过压&总体过压 if(((bmsMem_slave.bStatus1 & 0x0001) != 0) || ((bmsMem_slave.bStatus1 & 0x0100) != 0)) { if(bmsMem_slave.soc<99) { SDWA_Send_VAR(0x0187, 1); } else //当SOC大于99%,此时触发过压报警,不会跳转屏幕,也不会亮报警灯 { SDWA_Send_VAR(0x0187, 0); } } else { SDWA_Send_VAR(0x0187, 0); } //单体欠压&总体欠压 if(((bmsMem_slave.bStatus1 & 0x0002) != 0) || ((bmsMem_slave.bStatus1 & 0x0200) != 0)) { SDWA_Send_VAR(0x0193, 1); } else { SDWA_Send_VAR(0x0193, 0); } //afe充电过流&充电过流 if(((bmsMem_slave.bStatus1 & 0x0010) != 0) || ((bmsMem_slave.temperaStatus & 0x0010) != 0)) { SDWA_Send_VAR(0x0188, 1); } else { SDWA_Send_VAR(0x0188, 0); } //afe放电过流&放电过流1&放电过流2 if(((bmsMem_slave.bStatus1 & 0x000c) != 0) || ((bmsMem_slave.temperaStatus & 0x0020) != 0) || ((bmsMem_slave.bStatus1 & 0x0400) != 0)) { SDWA_Send_VAR(0x0194, 1); } else { SDWA_Send_VAR(0x0194, 0); } //afe充电高温&环境充电高温&电芯充电高温 if(((bmsMem_slave.bStatus2 & 0x0002) != 0) || ((bmsMem_slave.temperaStatus & 0x0100) != 0) || ((bmsMem_slave.temperaStatus & 0x0001) != 0)) { SDWA_Send_VAR(0x0189, 1); } else { SDWA_Send_VAR(0x0189, 0); } //afe放电高温&环境放电高温&电芯放电高温 if(((bmsMem_slave.bStatus2 & 0x0008) != 0) || ((bmsMem_slave.temperaStatus & 0x0200) != 0) || ((bmsMem_slave.temperaStatus & 0x0002) != 0)) { SDWA_Send_VAR(0x0190, 1); } else { SDWA_Send_VAR(0x0190, 0); } //afe充电低温&环境充电低温&电芯充电低温 if(((bmsMem_slave.bStatus2 & 0x0001) != 0) || ((bmsMem_slave.temperaStatus & 0x0400) != 0) || ((bmsMem_slave.temperaStatus & 0x0004) != 0)) { SDWA_Send_VAR(0x0195, 1); } else { SDWA_Send_VAR(0x0195, 0); } //afe放电低温&环境放电低温&电芯放电低温 if(((bmsMem_slave.bStatus2 & 0x0004) != 0) || ((bmsMem_slave.temperaStatus & 0x0800) != 0) || ((bmsMem_slave.temperaStatus & 0x0008) != 0)) { SDWA_Send_VAR(0x0196, 1); } else { SDWA_Send_VAR(0x0196, 0); } //异常高压 if((bmsMem_slave.bStatus1 & 0x0040) != 0) { SDWA_Send_VAR(0x0191, 1); } else { SDWA_Send_VAR(0x0191, 0); } //低压禁止充电 if((bmsMem_slave.bStatus3 & 0x0008) != 0) { SDWA_Send_VAR(0x0197, 1); } else { SDWA_Send_VAR(0x0197, 0); } //真短路保护 if((bmsMem_slave.bStatus2 & 0x0010) != 0) //只有预充情况才会出现短路锁定,出现则一直保持,这里也一直显示 { SDWA_Send_VAR(0x0192, 1); } //浪涌短路保护 else if((bmsMem_slave.bStatus1 & 0x0020) != 0) { SDWA_Send_VAR(0x0192, 1); } else { SDWA_Send_VAR(0x0192, 0); } } void SDWA_JumpToAlarm(void) { // if(language == 0) // { SDWA_JumpToNumber(4); // } // else if(language == 1) // { // SDWA_JumpToNumber(32); // } } /**报警记录显示**/ //被SDWA_Init()调用,用于自身报警记录和信息显示 void SDWA_Send_RecordInfo(void) { uint8_t i; uint8_t adrh,adrl; uint32_t ee_index[3]; uint16_t ee_pc[3]; //报警记录序号,初始默认0,1,2 ee_index[0] = read_index; ee_pc[0] = 0x1000 + 0x0040 * ee_index[0]; ee_index[1] = read_index+1; ee_pc[1] = 0x1000 + 0x0040 * ee_index[1]; ee_index[2] = read_index+2; ee_pc[2] = 0x1000 + 0x0040 * ee_index[2]; SDWA_Send_VAR(0x0132, ee_index[0]+1); if(ee_index[2] != 101) //对应序号101.102不显示 { SDWA_Send_VAR(0x0144, 0); SDWA_Send_VAR(0x0133, ee_index[1]+1); SDWA_Send_VAR(0x0134, ee_index[2]+1); } else { SDWA_Send_VAR(0x0144, 1); } //报警记录序号对应的报警内容 if(read_index < soe.num)//为减少读写EEPROM次数,只当序号在soe.num范围内时可用 //read_index+1 <= soe.num的简写 { for(i=0;i<3;i++) { adrh = (ee_pc[i]>>8) & 0xff; adrl = ee_pc[i] & 0xff; EEPROM_RdMulByte(adrh,adrl,52,recordBuf); delay_ms(10); if(recordBuf[0]==0xff && recordBuf[1]==0xff && recordBuf[2]==0xff && recordBuf[3]==0xff)//序号数据全是0xff,表示无数据 { SDWA_Send_Blank(0x0040 + 0x0040*i); SDWA_Send_Blank(0x0060 + 0x0040*i); SDWA_Send_VAR(0x0140 + 0x0001*i,1); } else { SDWA_Send_VAR(0x0140 + 0x0001*i,0); if(recordBuf[4]!=0 || recordBuf[5]!=0 || recordBuf[6]!=0 || recordBuf[7]!=0 || recordBuf[8]!=0 || recordBuf[9]!=0) { SDWA_Send_RecordTime(0x0040 + 0x0040*i); } else { SDWA_Send_Blank(0x0040 + 0x0040*i); } SDWA_Send_Blank(0x0060 + 0x0040*i); //防止上次的记录比这次长 SDWA_Send_Record(0x0060 + 0x0040*i); } } } else { for(i=0;i<3;i++) { SDWA_Send_Blank(0x0040 + 0x0040*i); SDWA_Send_Blank(0x0060 + 0x0040*i); SDWA_Send_VAR(0x0140 + 0x0001*i,1); } } //报警记录个数和最新记录对应序号(更新) SDWA_Send_VAR(0x0130, soe.num ); //记录个数的显示 if((soe.index == 0) || (soe.index%100 != 0)) //最新记录所在 { SDWA_Send_VAR(0x0131, soe.index%100 ); } else { SDWA_Send_VAR(0x0131, 100 ); } } //被SDWA_Init()调用,用于主机查看从机的报警记录(暂直接显示空白和数据0) void SDWA_Send_Slave_RecordBank(void) { uint8_t i; //报警记录序号 SDWA_Send_VAR(0x0132, 1); SDWA_Send_VAR(0x0133, 2); SDWA_Send_VAR(0x0144, 0); SDWA_Send_VAR(0x0134, 3); //报警记录序号对应的报警内容 for(i=0;i<3;i++) { SDWA_Send_VAR(0x0140 + 0x0001*i,1); } //报警记录个数和最新记录对应序号 SDWA_Send_VAR(0x0130, 0 ); SDWA_Send_VAR(0x0131, 0 ); } /**协议选择的显示**/ //A5 5A 06 83 03 10 01 00 01 勾选 //A5 5A 06 83 03 10 01 00 00 取消勾选 //A5 5A 05 82 03 00 00 01 显示勾选 //A5 5A 05 82 03 00 00 00 显示取消勾选 void SDWA_DispProcotol(uint8_t addrH, uint8_t addrL, uint8_t data) { USART_SendData(USART2, 0xA5); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x5A); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x05); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x82); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, addrH); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, addrL); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, 0x00); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); USART_SendData(USART2, data); while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET); } void SDWA_DispProtocol_P1Null(void) { //P1 SDWA_DispProcotol(0x03,0x00,0x00); SDWA_DispProcotol(0x03,0x01,0x00); SDWA_DispProcotol(0x03,0x02,0x00); SDWA_DispProcotol(0x03,0x03,0x00); SDWA_DispProcotol(0x03,0x04,0x00); SDWA_DispProcotol(0x03,0x05,0x00); } void SDWA_DispProtocol_P2Null(void) { //P2 SDWA_DispProcotol(0x03,0x06,0x00); SDWA_DispProcotol(0x03,0x07,0x00); SDWA_DispProcotol(0x03,0x08,0x00); SDWA_DispProcotol(0x03,0x09,0x00); SDWA_DispProcotol(0x03,0x0A,0x00); SDWA_DispProcotol(0x03,0x0B,0x00); SDWA_DispProcotol(0x03,0x0C,0x00); SDWA_DispProcotol(0x03,0x0D,0x00); SDWA_DispProcotol(0x03,0x0E,0x00); } void SDWA_DispProtocol_P3Null(void) { //P3 SDWA_DispProcotol(0x03,0x0F,0x00); SDWA_DispProcotol(0x03,0x20,0x00); SDWA_DispProcotol(0x03,0x21,0x00); SDWA_DispProcotol(0x03,0x22,0x00); SDWA_DispProcotol(0x03,0x23,0x00); SDWA_DispProcotol(0x03,0x24,0x00); SDWA_DispProcotol(0x03,0x25,0x00); SDWA_DispProcotol(0x03,0x26,0x00); SDWA_DispProcotol(0x03,0x27,0x00); } void SDWA_DispProtocol_P4Null(void) { //P4 SDWA_DispProcotol(0x03,0x28,0x00); SDWA_DispProcotol(0x03,0x29,0x00); SDWA_DispProcotol(0x03,0x2A,0x00); SDWA_DispProcotol(0x03,0x2B,0x00); SDWA_DispProcotol(0x03,0x2C,0x00); SDWA_DispProcotol(0x03,0x2D,0x00); SDWA_DispProcotol(0x03,0x2E,0x00); SDWA_DispProcotol(0x03,0x2F,0x00); SDWA_DispProcotol(0x03,0x40,0x00); } void SDWA_DispProtocol_P5Null(void) { //P5 SDWA_DispProcotol(0x03,0x41,0x00); SDWA_DispProcotol(0x03,0x42,0x00); SDWA_DispProcotol(0x03,0x43,0x00); SDWA_DispProcotol(0x03,0x44,0x00); SDWA_DispProcotol(0x03,0x47,0x00); //在这里跳过2个地址 SDWA_DispProcotol(0x03,0x48,0x00); SDWA_DispProcotol(0x03,0x49,0x00); SDWA_DispProcotol(0x03,0x4A,0x00); SDWA_DispProcotol(0x03,0x4B,0x00); } /**屏幕数据更新的显示**/ //被SDWA_UpdateData()调用,用于显示总数据 void SDWA_Send_TotalInfo(void) { uint16_t voltage; int16_t current; uint16_t temperature; //【不删兼容其他屏幕】 uint16_t totalCapacity; uint16_t capacity; uint8_t soc; /**Wh版屏幕相关**/ int32_t export_P; uint16_t total_W,remain_W,cumuli_W; uint8_t OV_bAlarmFlag = 0; //过压报警标志位 int16_t Progress; //充放电进度条 uint16_t remain_T; //充放电剩余时间 /**Wh版屏幕相关**/ voltage = bmsMem.packVoltage /100; //总电压,单位0.1V current = canMem[0].cur /10; //总电流,单位0.1A temperature = canMem[0].temp; //温度 //【不删兼容其他屏幕】 totalCapacity = 10 * ncc_Ah * OnlineNum; //总额定容量,单位0.1Ah capacity = totalCapacity * canMem[0].soc /100; //总当前容量,单位0.1Ah soc = canMem[0].soc; //平均soc SDWA_Send_VAR(0x0241, voltage); //总电压 SDWA_Send_VAR(0x0242, current); //总电流 SDWA_Send_VAR(0x0245, temperature - 2731);//平均温度 //【不删兼容其他屏幕】 SDWA_Send_VAR(0x0243, totalCapacity); //总额定容量 //【不删兼容其他屏幕】 SDWA_Send_VAR(0x0244, capacity); //总当前容量 //【不删兼容其他屏幕】 SDWA_Send_VAR(0x0246, soc); //平均soc /**Wh版屏幕相关**/ 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 SDWA_Send_VAR(0x0378,(export_P>>16) & 0xFFFF); //当前消耗功率,高16位 SDWA_Send_VAR(0x0379, export_P & 0xFFFF); //当前消耗功率,低16位 SDWA_Send_VAR(0x0372, total_W); //额定能量 SDWA_Send_VAR(0x0371, remain_W); //剩余能量 SDWA_Send_VAR(0x0373, cumuli_W); //总累积消耗功率Mwh Progress = (voltage*current)/18000; //充放电进度条,100%对应18kW,1%对应0.18kW=18000*0.1V*0.1A if(Progress>112) { Progress = 112; } else if(Progress<(-112)) { Progress = -112; } if(((canMem[0].status_byte1 & 0x7e)==0) && ((canMem[0].status_byte2 & 0xef) ==0) && ((canMem[0].status_byte3 & 0x18) ==0) && ((canMem[0].status_byte4 & 0x3f) ==0)) //9.27 除了过压报警,其他报警都没有 { if(((bmsMem.bStatus1 & 0x7e)==0) && ((bmsMem.bStatus2 & 0xef) ==0) && ((bmsMem.bStatus3 & 0x18) ==0) && ((bmsMem.temperaStatus & 0x3f) ==0)) //9.27 除了过压报警,其他报警都没有【主机自身】 { if(((bmsMem.bStatus1 & 0x01) != 0) && (bmsMem.soc<99)) //过压报警的判断:满电时发生[过压保护],屏幕不显示过压【主机自身】 { OV_bAlarmFlag = 1; } else if((canMem[0].status_byte1 & 0x01) != 0) //若并机线上有过压报警,需判断是否需要报警 { //轮询每个收集到的数据,若有未满压且发生过压报警的从机,则总数据显示报警 uint8_t i; for(i=1;i<=paraMem.PACK_NUM;i++) { if(canMem[i].com != 0) //该从机在线 { if(((canMem[i].status_byte1 & 0x01) != 0) && (canMem[i].soc<99)) //该从机正在过压报警 { OV_bAlarmFlag = 1; break; } } } } if(OV_bAlarmFlag == 1) //过压报警 { SDWA_Send_VAR(0x0374, 2); //“Fault” } else { if(current>100) //充电状态 { SDWA_Send_VAR(0x0374, 0); //“Charge” } else if(current<(-100)) //放电状态 { SDWA_Send_VAR(0x0374, 1); //“Discharge” } else //待机状态 { SDWA_Send_VAR(0x0374, 6); //“Standby” } } } else { SDWA_Send_VAR(0x0374, 2); //“Fault” } } else { SDWA_Send_VAR(0x0374, 2); //“Fault” } if(current>100) //充电状态 { SDWA_Send_VAR(0x05B6, 0); //放电进度条隐去 SDWA_Send_VAR(0x05B5, Progress); //充电进度条 remain_T = (totalCapacity - capacity)*10/current; //充电剩余时间=(额定总容量-当前总容量)0.1Ah/总电流0.1A,单位0.1h=0.1*0.1Ah/0.1A SDWA_Send_VAR(0x0375, remain_T); //充电剩余时间 SDWA_Send_VAR(0x0376, 0); //充放电剩余时间挡条不显示 } else if(current<(-100)) //放电状态 { SDWA_Send_VAR(0x05B5, 0); //充电进度条隐去 SDWA_Send_VAR(0x05B6, -Progress); //放电进度条 remain_T = capacity*10/(-current); //放电剩余时间=当前总容量0.1Ah/总电流0.1A,单位0.1h=0.1*0.1Ah/0.1A SDWA_Send_VAR(0x0375, remain_T); //放电剩余时间 SDWA_Send_VAR(0x0376, 0); //充放剩余电时间挡条不显示 } else //待机状态 { SDWA_Send_VAR(0x05B5, 0); //充电进度条隐去 SDWA_Send_VAR(0x05B6, 0); //放电进度条隐去 SDWA_Send_VAR(0x0375, 0); //充放电剩余时间都为0 SDWA_Send_VAR(0x0376, 1); //充放电剩余时间挡条显示 } /**Wh版屏幕相关**/ } //被SDWA_UpdateData()调用,用于显示自身基本信息 void SDWA_Send_Self_BasicInfo(void) { uint8_t i; uint16_t voltage; int16_t current; uint16_t capacity; uint8_t soc; /**Wh版屏幕相关**/ int32_t export_P; uint16_t remain_W; uint16_t Ave_Temp; //平均温度 int16_t Progress; //充放电进度条 uint16_t remain_T; //充放电剩余时间 /**Wh版屏幕相关**/ voltage = bmsMem.packVoltage /100; //电压,单位0.1V current = bmsMem.packCurrent /100; //电流,单位0.1A capacity = bmsMem.rcc/360000; //当前容量,单位0.1Ah soc = bmsMem.soc; //平均SOC //发送数据到串口显示屏,已经调试成功 SDWA_Send_VAR(0x0000, voltage); //TOTAL VOLTAGE SDWA_Send_VAR(0x0002, current); //CURRENT SDWA_Send_VAR(0x0004, capacity); //CAPACITY //【不删兼容其他屏幕】 SDWA_Send_VAR(0x0230, soc); //SOC for(i=0;i<16;i++) { if(cellVol[i] >= 0) { SDWA_Send_VAR(0x0010+i, bmsMem.vCell[i]); } else { SDWA_Send_VAR(0x0010+i, 0); } } // SDWA_Send_VAR(0x0010, bmsMem.vCell[0]); //CELL1 // SDWA_Send_VAR(0x0011, bmsMem.vCell[1]); //CELL2 // SDWA_Send_VAR(0x0012, bmsMem.vCell[2]); //CELL3 // SDWA_Send_VAR(0x0013, bmsMem.vCell[3]); //CELL4 // SDWA_Send_VAR(0x0014, bmsMem.vCell[4]); //CELL5 // SDWA_Send_VAR(0x0015, bmsMem.vCell[5]); //CELL6 // SDWA_Send_VAR(0x0016, bmsMem.vCell[6]); //CELL7 // SDWA_Send_VAR(0x0017, bmsMem.vCell[7]); //CELL8 // SDWA_Send_VAR(0x0018, bmsMem.vCell[8]); //CELL9 // SDWA_Send_VAR(0x0019, bmsMem.vCell[9]); //CELL10 // SDWA_Send_VAR(0x001A, bmsMem.vCell[10]); //CELL11 // SDWA_Send_VAR(0x001B, bmsMem.vCell[11]); //CELL12 // SDWA_Send_VAR(0x001C, bmsMem.vCell[12]); //CELL13 // SDWA_Send_VAR(0x001D, bmsMem.vCell[13]); //CELL14 // SDWA_Send_VAR(0x001E, bmsMem.vCell[14]); //CELL15 // SDWA_Send_VAR(0x001F, bmsMem.vCell[15]); //CELL16 SDWA_Send_VAR(0x0201, bmsMem.mcu_T1 - 2731); //MCU T1 SDWA_Send_VAR(0x0204, bmsMem.mcu_T2 - 2731); //MCU T2 SDWA_Send_VAR(0x0202, bmsMem.mcu_T3 - 2731); //MCU T3 SDWA_Send_VAR(0x0205, bmsMem.mcu_T4 - 2731); //MCU T4 SDWA_Send_VAR(0x0200, bmsMem.afe_T1 - 2731); //AFE T1 SDWA_Send_VAR(0x0203, bmsMem.afe_T2 - 2731); //AFE T2 SDWA_Send_VAR(0x0206, bmsMem.afe_T3 - 2731); //AFE T3 SDWA_Send_VAR(0x0287, bmsMem.cellVoltageMaxIndex+1); //最高电压电芯序号 SDWA_Send_VAR(0x028B, bmsMem.cellVoltageMinIndex+1); //最低电压电芯序号 //首页的状态显示and报警跳转 if(bAlarmFlag == 0) //无屏幕上的报警 { if( (bmsMem.temperaStatus & 0x40) !=0) //急停 { SDWA_Send_VAR(0x0100, 5); //“RPSD_Activated”(急停) } else if((bmsMem.bStatus2 & 0xe0) !=0) { SDWA_Send_VAR(0x0100, 2); //“Fault”(其他报警:放电MOS故障、充电MOS故障、预充失败) } else { if(bSTANDBY == 1) { SDWA_Send_VAR(0x0100, 6); //“Standby”(待机) } else if(bCHGING ==1) { if((bmsMem.balanceStatus & 0x10) != 0) { SDWA_Send_VAR(0x0100, 7); //“CL-start”(限流) } else { SDWA_Send_VAR(0x0100, 0); //“Charge”(充电) } } else { SDWA_Send_VAR(0x0100, 1); //“Discharge”(放电) } } SDWA_ClearAlarm(); } else { SDWA_Send_VAR(0x0100, 2); //“Fault”(屏幕上的报警) if(bAlarmFlagOld ==0) { bAlarmFlagOld = 1; SDWA_JumpToAlarm(); } SDWA_ShowAlarm(); } //平衡状态 if(balancing ==1) { SDWA_Send_VAR(0x0110, 0); //"On"(开启) } else { SDWA_Send_VAR(0x0110, 1); //"Off"(关闭) } /**Wh版屏幕相关**/ export_P = voltage*current/100; //当前消耗功率=总电压x总电流,单位1W=100*(0.1V*0.1A) remain_W = capacity*(3.2*bmsMem.ucCellNum)/1000; //剩余能量=当前总容量x额定电压,单位0.1kWh=1000*(0.1Ah*1V) Ave_Temp = TemperatureAverage; SDWA_Send_VAR(0x0366,(export_P>>16) & 0xFFFF); //当前消耗功率,高16位 SDWA_Send_VAR(0x0367, export_P & 0xFFFF); //当前消耗功率,低16位 SDWA_Send_VAR(0x0361, remain_W); //剩余能量 SDWA_Send_VAR(0x0364, Ave_Temp - 2731); //平均温度 SDWA_Send_VAR(0x0365, bmsMem.cycleCount); //循环次数 Progress = (voltage*current)/6000; //充放电进度条,100%对应6kW,1%对应0.06kW=6000*0.1V*0.1A if(Progress>100) { Progress = 100; } else if(Progress<(-100)) { Progress = -100; } if(bCHGING ==1) //充电状态 { remain_T = (fcc - bmsMem.rcc)/36000/current; //充电剩余时间=((额定总容量-当前总容量mAS)/36000)/总电流,单位0.1h=0.01Ah/0.1A } else //放电状态 { remain_T = bmsMem.rcc/36000/(-current); //放电剩余时间=当前总容量mAS/36000/总电流,单位0.1h=0.01Ah/0.1A } if(bSTANDBY == 1) //待机状态 { SDWA_Send_VAR(0x05A9, 0); //充电进度条隐去 SDWA_Send_VAR(0x05AA, 0); //放电进度条隐去 SDWA_Send_VAR(0x0362, 0); //充放电剩余时间都为0 SDWA_Send_VAR(0x0377, 1); //充放电剩余时间挡条显示 } else if(bCHGING ==1) //充电状态 { SDWA_Send_VAR(0x05AA, 0); //放电进度条隐去 SDWA_Send_VAR(0x05A9, Progress); //充电进度条 SDWA_Send_VAR(0x0362, remain_T); //充电剩余时间 SDWA_Send_VAR(0x0377, 0); //充放电剩余时间挡条不显示 } else //放电状态 { SDWA_Send_VAR(0x05A9, 0); //充电进度条隐去 SDWA_Send_VAR(0x05AA, -Progress); //放电进度条 SDWA_Send_VAR(0x0362, remain_T); //放电剩余时间 SDWA_Send_VAR(0x0377, 0); //充放电剩余时间挡条不显示 } /**Wh版屏幕相关**/ } //被SDWA_UpdateData()调用,用于显示从机基本信息 void SDWA_Send_Slave_BasicInfo(void) { uint8_t i; uint16_t voltage; int16_t current; uint16_t capacity; uint8_t soc; /**Wh版屏幕相关**/ int32_t export_P; uint16_t remain_W; uint16_t Ave_Temp; //平均温度 int16_t Progress; //充放电进度条 uint16_t remain_T; //充放电剩余时间 /**Wh版屏幕相关**/ voltage = bmsMem_slave.packVoltage /100; //电压,单位0.1V current = bmsMem_slave.packCurrent /100; //电流,单位0.1A capacity = bmsMem_slave.rcc/360000; //当前容量,单位0.1Ah soc = bmsMem_slave.soc; //平均SOC //发送数据到串口显示屏,已经调试成功 SDWA_Send_VAR(0x0000, voltage); //TOTAL VOLTAGE SDWA_Send_VAR(0x0002, current); //CURRENT SDWA_Send_VAR(0x0004, capacity); //CAPACITY //【不删兼容其他屏幕】 SDWA_Send_VAR(0x0230, soc); //SOC for(i=0;i<16;i++) { int16_t vol = (int16_t)(bmsMem_slave.vCell[i]*32/5)*5/32; if(vol >= 0) { SDWA_Send_VAR(0x0010+i, bmsMem_slave.vCell[i]); } else { SDWA_Send_VAR(0x0010+i, 0); } } // SDWA_Send_VAR(0x0010, bmsMem_slave.vCell[0]); //CELL1 // SDWA_Send_VAR(0x0011, bmsMem_slave.vCell[1]); //CELL2 // SDWA_Send_VAR(0x0012, bmsMem_slave.vCell[2]); //CELL3 // SDWA_Send_VAR(0x0013, bmsMem_slave.vCell[3]); //CELL4 // SDWA_Send_VAR(0x0014, bmsMem_slave.vCell[4]); //CELL5 // SDWA_Send_VAR(0x0015, bmsMem_slave.vCell[5]); //CELL6 // SDWA_Send_VAR(0x0016, bmsMem_slave.vCell[6]); //CELL7 // SDWA_Send_VAR(0x0017, bmsMem_slave.vCell[7]); //CELL8 // SDWA_Send_VAR(0x0018, bmsMem_slave.vCell[8]); //CELL9 // SDWA_Send_VAR(0x0019, bmsMem_slave.vCell[9]); //CELL10 // SDWA_Send_VAR(0x001A, bmsMem_slave.vCell[10]); //CELL11 // SDWA_Send_VAR(0x001B, bmsMem_slave.vCell[11]); //CELL12 // SDWA_Send_VAR(0x001C, bmsMem_slave.vCell[12]); //CELL13 // SDWA_Send_VAR(0x001D, bmsMem_slave.vCell[13]); //CELL14 // SDWA_Send_VAR(0x001E, bmsMem_slave.vCell[14]); //CELL15 // SDWA_Send_VAR(0x001F, bmsMem_slave.vCell[15]); //CELL16 SDWA_Send_VAR(0x0201, bmsMem_slave.mcu_T1 - 2731); //MCU T1 SDWA_Send_VAR(0x0204, bmsMem_slave.mcu_T2 - 2731); //MCU T2 SDWA_Send_VAR(0x0202, bmsMem_slave.mcu_T3 - 2731); //MCU T3 SDWA_Send_VAR(0x0205, bmsMem_slave.mcu_T4 - 2731); //MCU T4 SDWA_Send_VAR(0x0200, bmsMem_slave.afe_T1 - 2731); //AFE T1 SDWA_Send_VAR(0x0203, bmsMem_slave.afe_T2 - 2731); //AFE T2 SDWA_Send_VAR(0x0206, bmsMem_slave.afe_T3 - 2731); //AFE T3 SDWA_Send_VAR(0x0287, bmsMem_slave.cellVoltageMaxIndex+1); //最高电压电芯序号 SDWA_Send_VAR(0x028B, bmsMem_slave.cellVoltageMinIndex+1); //最低电压电芯序号 //首页的状态显示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) ) //过压报警的判断:满电时发生[过压保护],屏幕不显示过压 { SDWA_Send_VAR(0x0100, 2); //“Fault”(过压报警) //从机报警的跳转 if(bAlarmFlagOld_slave ==0) { bAlarmFlagOld_slave = 1; SDWA_JumpToAlarm(); } SDWA_ShowAlarm_Slave(); } else { if((bmsMem_slave.temperaStatus & 0x40) !=0) { SDWA_Send_VAR(0x0100, 5); //“RPSD_Activated”(急停) } else if((bmsMem_slave.bStatus2 & 0xe0) !=0) { SDWA_Send_VAR(0x0100, 2); //“Fault”(其他报警:放电MOS故障、充电MOS故障、预充失败) } else { if(bmsMem_slave.packCurrent > 100) { if((bmsMem.balanceStatus & 0x10) != 0) { SDWA_Send_VAR(0x0100, 7); //“CL-start”(限流) } else { SDWA_Send_VAR(0x0100, 0); //“Charge”(充电) } } else if(bmsMem_slave.packCurrent < (-100)) { SDWA_Send_VAR(0x0100, 1); //“Discharge”(放电) } else { SDWA_Send_VAR(0x0100, 6); //“Standby”(待机) } } bAlarmFlagOld_slave = 0; SDWA_ClearAlarm(); } } else { SDWA_Send_VAR(0x0100, 2); //“Fault”(屏幕上的报警) //从机报警的跳转 if(bAlarmFlagOld_slave ==0) { bAlarmFlagOld_slave = 1; SDWA_JumpToAlarm(); } SDWA_ShowAlarm_Slave(); } //平衡状态 if((bmsMem_slave.balanceStatus & 0x01) !=0) { SDWA_Send_VAR(0x0110, 0); //"On"(开启) } else { SDWA_Send_VAR(0x0110, 1); //"Off"(关闭) } /**Wh版屏幕相关**/ export_P = voltage*current/100; //当前消耗功率=总电压x总电流,单位1W=100*(0.1V*0.1A) remain_W = capacity*(3.2*bmsMem.ucCellNum)/1000; //剩余能量=当前总容量x额定电压,单位0.1kWh=1000*(0.1Ah*1V) Ave_Temp = (bmsMem_slave.mcu_T1 + bmsMem_slave.mcu_T2 + bmsMem_slave.mcu_T3 + bmsMem_slave.mcu_T4)/4; SDWA_Send_VAR(0x0366,(export_P>>16) & 0xFFFF); //当前消耗功率,高16位 SDWA_Send_VAR(0x0367, export_P & 0xFFFF); //当前消耗功率,低16位 SDWA_Send_VAR(0x0361, remain_W); //剩余能量 SDWA_Send_VAR(0x0364, Ave_Temp - 2731); //平均温度 SDWA_Send_VAR(0x0365, bmsMem_slave.cycleCount); //循环次数 Progress = (voltage*current)/6000; //充放电进度条,100%对应6kW,1%对应0.06kW=6000*0.1V*0.1A if(Progress>100) { Progress = 100; } else if(Progress<(-100)) { Progress = -100; } if(bmsMem_slave.packCurrent > 100) //充电状态 { remain_T = (fcc - bmsMem_slave.rcc)/36000/current; //充电剩余时间=((额定总容量-当前总容量mAS)/36000)/总电流,单位0.1h=0.01Ah/0.1A } else if(bmsMem_slave.packCurrent < (-100)) //放电状态 { remain_T = bmsMem_slave.rcc/36000/(-current); //放电剩余时间=当前总容量mAS/36000/总电流,单位0.1h=0.01Ah/0.1A } if(bmsMem_slave.packCurrent > 100) //充电状态 { SDWA_Send_VAR(0x05AA, 0); //放电进度条隐去 SDWA_Send_VAR(0x05A9, Progress); //充电进度条 SDWA_Send_VAR(0x0362, remain_T); //充电剩余时间 SDWA_Send_VAR(0x0377, 0); //充放电剩余时间挡条不显示 } else if(bmsMem_slave.packCurrent < (-100)) //放电状态 { SDWA_Send_VAR(0x05A9, 0); //充电进度条隐去 SDWA_Send_VAR(0x05AA, -Progress); //放电进度条 SDWA_Send_VAR(0x0362, remain_T); //放电剩余时间 SDWA_Send_VAR(0x0377, 0); //充放电剩余时间挡条不显示 } else //待机状态 { SDWA_Send_VAR(0x05A9, 0); //充电进度条隐去 SDWA_Send_VAR(0x05AA, 0); //放电进度条隐去 SDWA_Send_VAR(0x0362, 0); //充放电剩余时间都为0 SDWA_Send_VAR(0x0377, 1); //充放电剩余时间挡条显示 } /**Wh版屏幕相关**/ } //更新屏幕数据,1s执行一次 void SDWA_UpdateData(void) { uint16_t scv,sct; //用于显示短路参数 /**** 时间显示 ****/ if(LSEErrFlag==1) SDWA_Send_Blank(0x0020); else SDWA_Send_Time(0x0020); //Time /**** 汇总信息 ****/ if(bmsMem.E2_485Addr == 1) { SDWA_Send_TotalInfo(); //无论并机还是单机,都对应canMem[0]的数据 } /**** 基本信息 ****/ if((bmsMem.E2_485Addr != 1) || (scr_RdData_Index == 1)) //当前是从机或主机自身,一直显示自身数据 { SDWA_Send_Self_BasicInfo(); } else //当前是主机,可显示自身数据或所选从机数据 { SDWA_Send_Slave_BasicInfo(); } /**** 可显示图标的控制 ****/ //报警记录的跳转按钮 if((bmsMem.E2_485Addr != 1) || (scr_RdData_Index == 1)) { SDWA_Send_VAR(0x0346, 1); //图标显示 } else { SDWA_Send_VAR(0x0346, 0); //图标隐藏 } //主页返回总数据页的跳转按钮 if(bmsMem.E2_485Addr == 1) { SDWA_Send_VAR(0x0345, 1); //图标显示 } else { SDWA_Send_VAR(0x0345, 0); //图标隐藏 } /**** 轮询在线从机页面 ****/ if(scr_RdData_Index == 1) { uint8_t i; if(bAlarmFlag == 1) { SDWA_Send_VAR(0x0250, 2); //主机报警 } else { SDWA_Send_VAR(0x0250, 1); //主机一定在线 } //从机 for(i=2;i<=paraMem.PACK_NUM;i++) { if(canMem[i].com != 0) { //根据汇总的标志位来显示报警(任何保护都算,急停、MOS故障不在屏上也算报警) if(canMem[i].soc<99) //在正常工作时,发生[总体/单体过压保护],正常显示 { if( ((canMem[i].status_byte1 & 0x077f)!=0) || ((canMem[i].status_byte2 & 0x00ff) !=0) || ((canMem[i].status_byte3 & 0x0008) !=0) || ((canMem[i].status_byte4 & 0x0f7f) !=0) ) { SDWA_Send_VAR(0x0250+i-1, 2); } else { SDWA_Send_VAR(0x0250+i-1, 1); } } else //在接近满电时,发生[总体/单体过压保护],则不会因此亮灯屏幕也不显示过压 { if( ((canMem[i].status_byte1 & 0x067e)!=0) || ((canMem[i].status_byte2 & 0x00ff) !=0) || ((canMem[i].status_byte3 & 0x0008) !=0) || ((canMem[i].status_byte4 & 0x0f7f) !=0) ) { SDWA_Send_VAR(0x0250+i-1, 2); } else { SDWA_Send_VAR(0x0250+i-1, 1); } } } else { SDWA_Send_VAR(0x0250+i-1, 0); } } //显示当前正在轮询还是正在分配 #if Addr_SetAuto if((assignAddr_State == 0) || (assignAddr_State == 1)) { SDWA_Send_VAR(0x01B3, 2 ); //分配 } else #endif if(ConfigData_Index == 1) //除了上位机读数据的其他时候 { SDWA_Send_VAR(0x01B3, 1 ); //轮询 } else { SDWA_Send_VAR(0x01B3, 0 ); //其他状态不显示 } } /**** 参数显示 ****/ //SN号,可上位机更新 SDWA_Send_VER_PACKSN(0x02C0, &VersionMem.PACK_SN[0]);//数字和字母的组合,不含符号,最大15位 SDWA_Send_VER_BMSSN(0x02CD, &VersionMem.BMS_SN[0]); //纯数字显示,只可9位 //版本号,不可修改 SDWA_Send_VER_SOFT(0x02DE, VersionMem.Software); //按照x.x.x.x来排布 SDWA_Send_VER_HARD(0x02D6, VersionMem.Hardware); //按照x.x.x来排布 SDWA_Send_VER_SCRN(0x02E9, VersionMem.Screen); //一共5位数,存放在1个字节里 //一屏多显,当前显示地址 SDWA_Send_VAR(0x0240, scr_RdData_Index ); //当前显示数据地址 //报警记录个数和最新记录对应序号 SDWA_Send_VAR(0x0130, soe.num ); //记录个数的显示 if((soe.index == 0) || (soe.index%100 != 0)) //最新记录所在 { SDWA_Send_VAR(0x0131, soe.index%100 ); } else { SDWA_Send_VAR(0x0131, 100 ); } //其他参数页面 // SDWA_Send_VAR(0x01A0, language); //语言 SDWA_Send_VAR(0x0209, paraMem.PACK_NUM ); //宁化时代4.16 增加显示并机总数 //系统校准页面 SDWA_Send_VAR(0x0126, bmsMem.soc); //电量 SDWA_Send_VAR(0x01AA, ncc_Ah); //额定容量 SDWA_Send_VAR(0x01A8, (bmsMem.packCurrent>>16) & 0xFFFF); SDWA_Send_VAR(0x01A9, bmsMem.packCurrent & 0xFFFF); SDWA_Send_VAR(0x01A1, (cali.current>>16) & 0xFFFF); SDWA_Send_VAR(0x01A2, cali.current & 0xFFFF); //配置参数页面 SDWA_Send_VAR(0x0145, 0); //参数修改成功 SDWA_Send_VAR(0x0124, bmsMem.inverter_chgVolLimit ); SDWA_Send_VAR(0x0212, bmsMem.inverter_dsgVolLimit ); SDWA_Send_VAR(0x0213, bmsMem.inverter_chgCurLimit ); SDWA_Send_VAR(0x0214, bmsMem.inverter_dsgCurLimit ); SDWA_Send_VAR(0x0215, bmsMem.mcu_occ ); SDWA_Send_VAR(0x0216, bmsMem.mcu_ocd ); SDWA_Send_VAR(0x0217, 5* (((bmsMem.ee_ovt_ldrt_ovh & 0x03)<<8) + bmsMem.ee_ovl) ); SDWA_Send_VAR(0x0218, 20* bmsMem.ee_uv ); SDWA_Send_VAR(0x0219, bmsMem.mcu_otc ); SDWA_Send_VAR(0x021A, bmsMem.mcu_utc ); SDWA_Send_VAR(0x021B, bmsMem.mcu_otd ); SDWA_Send_VAR(0x021C, bmsMem.mcu_utd ); SDWA_Send_VAR(0x0227, 5* (((bmsMem.ee_uvt_ovrh & 0x03)<<8) + bmsMem.ee_ovrl) ); SDWA_Send_VAR(0x0228, 20* bmsMem.ee_uvr ); SDWA_Send_VAR(0x0229, bmsMem.mcu_otcr ); SDWA_Send_VAR(0x022A, bmsMem.mcu_utcr ); SDWA_Send_VAR(0x022B, bmsMem.mcu_otdr ); SDWA_Send_VAR(0x022C, bmsMem.mcu_utdr ); SDWA_Send_VAR(0x0400, (paraMem.temp_disable & BIT0)>>0 ); //电池温度1失效 SDWA_Send_VAR(0x0401, (paraMem.temp_disable & BIT1)>>1 ); //电池温度2失效 SDWA_Send_VAR(0x0402, (paraMem.temp_disable & BIT2)>>2 ); //电池温度3失效 SDWA_Send_VAR(0x0403, (paraMem.temp_disable & BIT3)>>3 ); //电池温度4失效 //短路参数 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); SDWA_Send_VAR(0x021D, scv); //短路保护电压 SDWA_Send_VAR(0x021E, sct); //短路保护延时 /**** 若之前在总数据页,而地址变化,跳回数据页 ****/ if(bmsMem.E2_485Addr != 1) { if(sdwa_ExitTotal_Flg == 1) { sdwa_ExitTotal_Flg = 0; SDWA_JumpToHome(); } } /**** 屏幕修改地址的显示 ****/ if(sdwa_WrAddr_Flg == 1) //主机改从机地址的显示 { //显示0,正在修改 SDWA_Send_VAR(0x0210, 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; SDWA_Send_VAR(0x0210, scr_RdData_Index ); } else if(sdwa_WrAddr_Flg == 3) { //失败,显示原地址 sdwa_WrAddr_Flg = 0; SDWA_Send_VAR(0x0210, scr_RdData_Index ); } else { //正常 if((bmsMem.E2_485Addr != 1) || (scr_RdData_Index == 1)) { SDWA_Send_VAR(0x0210, bmsMem.E2_485Addr ); } else { SDWA_Send_VAR(0x0210, scr_RdData_Index ); } } /**** 地址释放控制的打勾显示 ****/ if(paraMem.addr_FREE_Flg == 1) { SDWA_Send_VAR(0x0294, 1); } else { SDWA_Send_VAR(0x0294, 0); } /**** 欠压保护恢复倒计时的显示 ****/ if((bmsMem.balanceStatus & 0x20) != 0) { //正常情况下,在RTC时钟里计算 if(LSEErrFlag == 0) SDWA_Send_TimeCount(0x02A0,uvofftime); //若RTC遇到问题,在定时器里计算 else SDWA_Send_TimeCount(0x02A0,uvoff_Moni_Count/100); } else { SDWA_Send_VAR(0x0290, 0); //按钮变黑 #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 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; SDWA_Send_Blank(0x02A0); //清除原有显示 SDWA_Send_LTE(0x02A0); //船用带4G版,用屏幕显示当前4G在什么阶段 } else { SDWA_Send_Blank(0x02A0); //清除显示 } #else SDWA_Send_Blank(0x02A0); //倒计时消失 #endif } /**** 延时显示完成操作 ****/ //初始化参数的显示 if(initFlag != 0) { SDWA_Send_VAR(0x01A4, 2); //初始化成功 initFlag++; if(initFlag > 3) { initFlag = 0; SDWA_Send_VAR(0x01A4, 0); //初始化按钮恢复正常 } } //零点校准按钮的显示 if(scr_WrZero_Flg == 2) { scr_WrZero_Flg = 0; SDWA_Send_VAR(0x012A, 0); } //增益校准按钮的显示 if(scr_WrGain_Flg == 2) { scr_WrGain_Flg = 0; SDWA_Send_VAR(0x012C, 0); } //删除记录的显示 if(clearFlag != 0) { SDWA_Send_VAR(0x0160, 0); SDWA_Send_VAR(0x0143, 1); clearFlag++; if(clearFlag > 3) { clearFlag = 0; SDWA_Send_VAR(0x0143, 0); scr_RdRecord_Flg = 1;//因为会展示成功标识,需要刷新屏幕并重新读记录 SCR_DispProcotol();//以更新报警页面 } } //清空EEPROM的显示 if(EE_clearFlag != 0) { EE_clearFlag++; if(EE_clearFlag > 3) //等待3s后按钮变白并执行软件复位 { EE_clearFlag = 0; SDWA_Send_VAR(0x0152, 0); delay_ms(1000); NVIC_SystemReset(); //软件复位,参数恢复默认 } } } /**接收屏幕报文的函数**/ //USART2中断接收 //如果在向外发送时,接收数据会怎么样? void SDWA_IT_Receive(void) { //接收数据 sdwaBuf[sdwaBufIndex] = USART_ReceiveData(USART2); sdwaBufIndex++; //防止数组溢出 if(sdwaBufIndex >= 19 ) { sdwaBufIndex = 0; } sdwaMoniCount = 10; } //一定时间没有接收到数据,初始化MODBUS通讯 void SDWA_TIM_Moni(void) { if(sdwaMoniCount!= 0xff) { sdwaMoniCount--; } if(sdwaMoniCount == 0) { sdwaMoniCount = 0xff; sdwaRecvFlag = 1; } } //SDWA写入数据:485地址、密码、协议选择、报警记录删除 void SDWA_RecvData(void) { uint8_t tmpWr[2]; uint8_t tmpRd[2]; uint16_t tmp; //屏幕参数相关 int16_t tmp_T;//温度是有符号型 uint8_t flashUpdateFlag = 0; //1:不需要算校验位 2:需要算校验位 3:初始化参数,也要算校验位 uint8_t protocol_Index; //屏幕写入增多,加一层判断以减少写入协议选择的次数 protocol_Index = protocol; if(sdwaRecvFlag == 1) { sdwaRecvFlag = 0; if((sdwaBuf[0] == 0xA5) && (sdwaBuf[1] == 0x5A)) { /**语言和地址设置**/ // //语言 // //A5 5A 06 83 01 27 01 00 00/01[中文/英文] // if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x01) && (sdwaBuf[5]==0x27)) // { // tmpWr[0] = sdwaBuf[8]; // EEPROM_WrMulByte(EE_LANG,&tmpWr[0]); // delay_ms(5); // EEPROM_RdMulByte(EE_LANG,&tmpRd[0]); // language = tmpRd[0]; // SDWA_Send_VAR(0x01A0, language); // // if((bmsMem.E2_485Addr != 1) || (scr_RdData_Index == 1)) //主机的地址和语言设置页 // { // if(language == 0) // { // SDWA_JumpToNumber(27); // } // else if(language == 1) // { // SDWA_JumpToNumber(51); // } // } // else //从机的地址和语言设置页 // { // if(language == 0) // { // SDWA_JumpToNumber(15); // } // else if(language == 1) // { // SDWA_JumpToNumber(36); // } // } // } //地址 //A5 5A 06 83 02 10 01 00 addr if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x10)) { if((sdwaBuf[8]>=1) && (sdwaBuf[8]<=AddrMax)) //范围判断 { if(bmsMem.E2_485Addr == 1) //作为主机 { if((scr_RdData_Index>=2) && (scr_RdData_Index<=paraMem.PACK_NUM)) //想修改从机地址 { if((sdwaBuf[8] != 1) && (sdwaBuf[8] <= paraMem.PACK_NUM)) //(不能修改成1) //宁化时代.不能修改到高于并机总数 { sdwa_WrAddr = sdwaBuf[8]; SDWA_Send_VAR(0x0210, 0 ); //正在修改,显示0 sdwa_WrAddr_Flg = 1; } } else //修改主机地址 { if(paraMem.addr_FREE_Flg != 0) { tmpWr[0] = sdwaBuf[8]; EEPROM_WrMulByte(EE_ADDR,&tmpWr[0]); delay_ms(5); EEPROM_RdMulByte(EE_ADDR,&tmpRd[0]); bmsMem.E2_485Addr = tmpRd[0]; SDWA_Send_VAR(0x0210, bmsMem.E2_485Addr ); 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(paraMem.addr_FREE_Flg != 0) { tmpWr[0] = sdwaBuf[8]; EEPROM_WrMulByte(EE_ADDR,&tmpWr[0]); delay_ms(5); EEPROM_RdMulByte(EE_ADDR,&tmpRd[0]); bmsMem.E2_485Addr = tmpRd[0]; SDWA_Send_VAR(0x0210, bmsMem.E2_485Addr ); 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(sdwaBuf[8] != 1) //(不能修改成1) { bmsMem.E2_485Addr = sdwaBuf[8]; SDWA_Send_VAR(0x0210, bmsMem.E2_485Addr ); scr_RdData_Index = bmsMem.E2_485Addr; } } } } } //并机总个数 //A5 5A 06 83 02 09 01 00 num if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x09)) { if((sdwaBuf[8]>=1) && (sdwaBuf[8]<=AddrMax)) //范围判断 { //更新并机总个数 paraMem.PACK_NUM = sdwaBuf[8]; SDWA_Send_VAR(0x0209, paraMem.PACK_NUM ); flashUpdateFlag = 1; //地址若溢出,变为1,初始化自动分配状态 //宁化时代.原则上应该只有主机能通过屏幕修改此值,所以该判断暂时保留 if(bmsMem.E2_485Addr > paraMem.PACK_NUM) { #if Addr_SetAuto assignAddr_State = 0; assignAddr_relay = 2;//变1后也有可能变回去 bmsMem.can_ArrayIndex = 0; tmpWr[0] = 0; tmpWr[1] = 0; EEPROM_WrMulByte(EE_ASSIGN,tmpWr); delay_ms(5); #endif bmsMem.E2_485Addr = 1; scr_RdData_Index = bmsMem.E2_485Addr; tmpWr[0] = bmsMem.E2_485Addr; EEPROM_WrMulByte(EE_ADDR,&tmpWr[0]); delay_ms(5); MODBUS_Init(); } } } /**页面跳转**/ //密码跳转设置页[0x07BD=1981] //接收界面密码指令: A5 5A 06 83 01 20 01 07 BD //跳转设置界面指令: A5 5A 04 80 03 00 05 if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x01) && (sdwaBuf[5]==0x20) && (sdwaBuf[7]==0x07) && (sdwaBuf[8]==0xBD)) { if((bmsMem.E2_485Addr != 1) || (scr_RdData_Index == 1)) //进入设置菜单 { // if(language == 0) // { SDWA_JumpToNumber(5); // } // else if(language == 1) // { // SDWA_JumpToNumber(42); // } } else //主机看从机时,只能进入地址和语言设置页 { // if(language == 0) // { SDWA_JumpToNumber(15); // } // else if(language == 1) // { // SDWA_JumpToNumber(36); // } } } //密码跳转限制参数页[0x07C3=1987] //接收界面密码指令: A5 5A 06 83 01 AD 01 07 C3 //跳转参数界面指令: A5 5A 04 80 03 00 0A if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x01) && (sdwaBuf[5]==0xAD) && (sdwaBuf[7]==0x07) && (sdwaBuf[8]==0xC3)) { // if(language == 0) // { SDWA_JumpToNumber(10); // } // else if(language == 1) // { // SDWA_JumpToNumber(45); // } } //密码跳转保护参数页[0x07C3=1987] //接收界面密码指令: A5 5A 06 83 01 AE 01 07 C3 //跳转参数界面指令: A5 5A 04 80 03 00 0A if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x01) && (sdwaBuf[5]==0xAE) && (sdwaBuf[7]==0x07) && (sdwaBuf[8]==0xC3)) { // if(language == 0) // { SDWA_JumpToNumber(12); // } // else if(language == 1) // { // SDWA_JumpToNumber(31); // } } //息屏跳转首页 //进入睡眠模式,此时不能有任何数据传来: A5 5A 04 81 01 01 00 //退出睡眠模式会自动发送:A5 5A 04 81 01 01 40 //跳转主页界面指令: A5 5A 04 80 03 00 01 if((sdwaBuf[2]==0x04) && (sdwaBuf[3]==0x81) && (sdwaBuf[6]==0x00)) //屏幕息屏,数据停止发送 { sdwa_sleep_flag = 1; sdwa_ExitTotal_Flg = 0; //不需要主动退出总数据页,因为亮屏自会跳转 scr_RdData_Index = bmsMem.E2_485Addr; //为了不影响轮询,地址返回原值 } else if((sdwaBuf[2]==0x04) && (sdwaBuf[3]==0x81) && ( (sdwaBuf[6]>=0x20) && (sdwaBuf[6]<=0x40) )) //摁亮退出息屏,数据正常发送 { sdwa_sleep_flag = 0; SDWA_JumpToHome(); } //主页跳转报警记录页面——只能看自身的报警记录,主机看从机不显示 if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x71)) { if((bmsMem.E2_485Addr != 1) || (scr_RdData_Index == 1)) { scr_RdRecord_Flg = 1; // if(language == 0) // { SDWA_JumpToNumber(28); // } // else if(language == 1) // { // SDWA_JumpToNumber(35); // } } } //主页跳转轮询页——只有主机可用;先将显示序号置1恢复轮询,然后跳转 if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x70)) { if(bmsMem.E2_485Addr == 1) { scr_RdData_Index = 1; sdwa_ExitTotal_Flg = 1;//可能要进行跳转 //不论语言,轮询页都是这一页 SDWA_JumpToNumber(13); } } //轮询页跳转总数据页——根据语言选择不同跳转页 if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x01) && (sdwaBuf[5]==0xA6)) { // if(language == 0) // { SDWA_JumpToNumber(23); // } // else if(language == 1) // { // SDWA_JumpToNumber(48); // } } //自身/主看从机的设置页跳转返回——自身都是返回上级菜单,主机看从机是返回主页 if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x01) && (sdwaBuf[5]==0xAC)) { if((bmsMem.E2_485Addr != 1) || (scr_RdData_Index == 1)) //进入设置菜单 { // if(language == 0) // { SDWA_JumpToNumber(5); // } // else if(language == 1) // { // SDWA_JumpToNumber(42); // } } else //主机看从机时,直接返回主页 { SDWA_JumpToHome(); } } /**参数改动**/ //系统值修改 //SOC:A5 5A 06 83 01 26 01 00 soc if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x01) && (sdwaBuf[5]==0x26)) { if(((int)sdwaBuf[8]>=0) && (sdwaBuf[8]<=100)) //范围判断 { tmpWr[0] = sdwaBuf[8]; EEPROM_WrMulByte(EE_SOC,&tmpWr[0]); delay_ms(5); //赋值SOC EEPROM_RdMulByte(EE_SOC,&tmpRd[0]); bmsMem.soc = tmpRd[0]; SDWA_Send_VAR(0x0126, bmsMem.soc); //赋值剩余容量=满充容量*新的SOC bmsMem.rcc = fcc/100 * bmsMem.soc; rcc_Ah = fcc_Ah * bmsMem.soc / 100; oldrcc_Ah = rcc_Ah; //在满放满充过程中,修改SOC会影响效果,不再执行 if(fcc_CaliStartFlag == 1) { fcc_CaliStartFlag = 0; if(LSEErrFlag == 0) { EEPROM_WrMulByte(EE_FCC_TIME,ClearEE); delay_ms(5); } } } } //额定容量:A5 5A 06 83 01 AA 01 00 capacity if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x01) && (sdwaBuf[5]==0xAA)) { tmp = sdwaBuf[7]<<8 | sdwaBuf[8]; if((tmp>0) && (tmp<=1000)) //范围判断 { tmpWr[0] = sdwaBuf[7]; tmpWr[1] = sdwaBuf[8]; EEPROM_WrMulByte(EE_NCC,tmpWr); delay_ms(5); //赋值额定容量 EEPROM_RdMulByte(EE_NCC,tmpRd); ncc_Ah = tmpRd[0]<<8 | tmpRd[1]; bmsMem.ncc = 3600 * 1000 * ncc_Ah; SDWA_Send_VAR(0x01AA, ncc_Ah); //赋值满充容量=额定容量 fcc = bmsMem.ncc; fcc_Ah = ncc_Ah; tmpWrFCC[0] = (fcc>>24) & 0xff; tmpWrFCC[1] = (fcc>>16) & 0xff; tmpWrFCC[2] = (fcc>> 8) & 0xff; tmpWrFCC[3] = (fcc>> 0) & 0xff; tmpWrFCC[4] = tmpWrFCC[0] ^ 0xff; tmpWrFCC[5] = tmpWrFCC[1] ^ 0xff; tmpWrFCC[6] = tmpWrFCC[2] ^ 0xff; tmpWrFCC[7] = tmpWrFCC[3] ^ 0xff; EEPROM_WrMulByte(EE_FCC,tmpWrFCC); delay_ms(20); //赋值剩余容量=新的满充容量*SOC bmsMem.rcc = fcc/100 * bmsMem.soc; rcc_Ah = fcc_Ah * bmsMem.soc / 100; oldrcc_Ah = rcc_Ah; //改额定容量不影响此前的满放满充过程 } } //增益校准系数:A5 5A 08 83 01 A1 02 dataHH dataHL dataLH dataLL if((sdwaBuf[2]==0x08) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x01) && (sdwaBuf[5]==0xA1)) { cali.current = sdwaBuf[7]<<24 | sdwaBuf[8]<<16 | sdwaBuf[9]<<8 | sdwaBuf[10]; } //零点校准:A5 5A 06 83 01 2B 01 00 01 if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x01) && (sdwaBuf[5]==0x2B)) { scr_WrZero_Flg = 1; cali.cmdZero = 1; SDWA_Send_VAR(0x012A, 1); } //增益校准:A5 5A 06 83 01 2D 01 00 01 if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x01) && (sdwaBuf[5]==0x2D)) { scr_WrGain_Flg = 1; cali.cmdGain = 1; SDWA_Send_VAR(0x012C, 1); } //配置参数修改 //恢复默认参数——150A参数 //Default按钮:A5 5A 06 83 01 A5 01 00 01 if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x01) && (sdwaBuf[5]==0xA5)) { //P1 bmsMem.ee_scv_sct = 0x10; //80mV 0us bmsMem.inverter_chgVolLimit = 576; //57.6V 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 = 0x9B; //充电过流 155A bmsMem.mcu_ocd = 0x9B; //放电过流 155A 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 SDWA_Send_VAR(0x01A4, 1); //初始化按钮变化颜色 flashUpdateFlag = 3; } //单个参数作用的 //修改短路电压:A5 5A 06 83 03 50 01 00 data if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x01) && (sdwaBuf[5]==0x22)) { tmp = sdwaBuf[8]; if(tmp <= 0x0F) //范围:0x00~0x0F { bmsMem.ee_scv_sct = (bmsMem.ee_scv_sct & 0x0F) + (tmp<<4); flashUpdateFlag = 2; } } //修改短路延时:A5 5A 06 83 03 60 01 00 data if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x01) && (sdwaBuf[5]==0x23)) { tmp = sdwaBuf[8]; if(tmp <= 0x0F) //范围:0x00~0x0F { bmsMem.ee_scv_sct = (bmsMem.ee_scv_sct & 0xF0) + tmp; flashUpdateFlag = 2; } } //修改逆变器充电限压:A5 5A 06 83 02 11 01 dataH dataL if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x01) && (sdwaBuf[5]==0x24)) { tmp = sdwaBuf[7]<<8 | sdwaBuf[8]; if((tmp>=540) && (tmp<=580)) //范围:54~58V,单位0.1V { bmsMem.inverter_chgVolLimit = tmp; flashUpdateFlag = 1; } } //修改逆变器放电限压:A5 5A 06 83 02 12 11 dataH dataL if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x12)) { tmp = sdwaBuf[7]<<8 | sdwaBuf[8]; bmsMem.inverter_dsgVolLimit = tmp; //(暂无范围) flashUpdateFlag = 1; } //修改逆变器充电限流:A5 5A 06 83 02 13 01 dataH dataL if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x13)) { tmp = sdwaBuf[7]<<8 | sdwaBuf[8]; bmsMem.inverter_chgCurLimit = tmp; //(暂无范围) flashUpdateFlag = 1; } //修改逆变器放电限流:A5 5A 06 83 02 14 01 dataH dataL if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x14)) { tmp = sdwaBuf[7]<<8 | sdwaBuf[8]; bmsMem.inverter_dsgCurLimit = tmp; //(暂无范围) flashUpdateFlag = 1; } //修改充电过流值:A5 5A 06 83 02 15 01 dataH dataL if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x15)) { tmp = sdwaBuf[7]<<8 | sdwaBuf[8]; if(tmp <= 0xFF) //范围:0x00~0xFF { bmsMem.mcu_occ = tmp; flashUpdateFlag = 2; } } //修改放电过流值:A5 5A 06 83 02 16 01 dataH dataL if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x16)) { tmp = sdwaBuf[7]<<8 | sdwaBuf[8]; if(tmp <= 0xFF) //范围:0x00~0xFF { bmsMem.mcu_ocd = tmp; flashUpdateFlag = 2; } } //保护和释放参数一起作用的 //修改单体过压值:A5 5A 06 83 02 17 01 dataH dataL if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x17)) { //单体过压 tmp = sdwaBuf[7]<<8 | sdwaBuf[8]; tmp = tmp/5; if((tmp <= 0x03FF) && (tmp >= 0x0029)) //范围:0x0029~0x03FF(考虑到释放值最小1,这里最小1+200/5) { bmsMem.ee_ovt_ldrt_ovh &= 0xfc;//~0x03 bmsMem.ee_ovt_ldrt_ovh += (tmp & 0x0300) >>8; bmsMem.ee_ovl = tmp & 0x00ff; //单体过压释放=-200mV tmp = tmp-200/5; bmsMem.ee_uvt_ovrh &= 0xfc;//~0x03 bmsMem.ee_uvt_ovrh += (tmp & 0x0300) >>8; bmsMem.ee_ovrl = tmp & 0x00ff; flashUpdateFlag = 2; } } //修改单体过压释放值:A5 5A 06 83 02 17 01 dataH dataL if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x27)) { tmp = sdwaBuf[7]<<8 | sdwaBuf[8]; tmp = tmp/5; if((tmp < ((bmsMem.ee_ovt_ldrt_ovh & 0x03)<<8 | bmsMem.ee_ovl)) && (tmp > 0)) //不超过保护值才能写入,范围:0x0001~0x03FF(如果是0会有问题) { bmsMem.ee_uvt_ovrh &= 0xfc;//~0x03 bmsMem.ee_uvt_ovrh += (tmp & 0x0300) >>8; bmsMem.ee_ovrl = tmp & 0x00ff; flashUpdateFlag = 2; } } //修改单体欠压值:A5 5A 06 83 02 18 01 dataH dataL if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x18)) { //单体欠压 tmp = sdwaBuf[7]<<8 | sdwaBuf[8]; tmp = tmp/20; if(tmp <= 0xF4) //范围:0x00~0xF4(考虑到释放值最大0xFE,这里0xFE-200/20) { bmsMem.ee_uv = tmp; //单体欠压释放=+200mV tmp = tmp+200/20; bmsMem.ee_uvr = tmp; flashUpdateFlag = 2; } } //修改单体欠压释放值:A5 5A 06 83 02 18 01 dataH dataL if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x28)) { tmp = sdwaBuf[7]<<8 | sdwaBuf[8]; tmp = tmp/20; if((tmp > bmsMem.ee_uv) && (tmp < 0xFF)) //不超过保护值才能写入,范围:0x00~0xFE(如果是0xff会有问题) { bmsMem.ee_uvr = tmp; flashUpdateFlag = 2; } } //修改充电高温保护值:A5 5A 06 83 02 19 01 dataH dataL if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x19)) { //充电高温 tmp_T = sdwaBuf[7]<<8 | sdwaBuf[8]; if((tmp_T >= -118) && (tmp_T <= 127)) //范围:-118~127(考虑到释放值最小-128,这里-128+10) { bmsMem.mcu_otc = tmp_T; //充电高温释放=-10℃ tmp_T = tmp_T-10; bmsMem.mcu_otcr = tmp_T; flashUpdateFlag = 2; } } //修改充电高温保护释放值:A5 5A 06 83 02 19 01 dataH dataL if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x29)) { tmp_T = sdwaBuf[7]<<8 | sdwaBuf[8]; if((tmp_T >= -128) && (tmp_T < bmsMem.mcu_otc)) //不超过保护值才能写入,范围:-128~127 { bmsMem.mcu_otcr = tmp_T; flashUpdateFlag = 2; } } //修改充电低温保护值:A5 5A 06 83 02 1A 01 dataH dataL if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x1A)) { //充电低温 tmp_T = sdwaBuf[7]<<8 | sdwaBuf[8]; if((tmp_T >= -128) && (tmp_T <= 124)) //范围:-128~124(考虑到释放值最大127,这里127-3) { bmsMem.mcu_utc = tmp_T; //充电低温释放=+3℃ tmp_T = tmp_T+3; bmsMem.mcu_utcr = tmp_T; flashUpdateFlag = 2; } } //修改充电低温保护释放值:A5 5A 06 83 02 1A 01 dataH dataL if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x2A)) { tmp_T = sdwaBuf[7]<<8 | sdwaBuf[8]; if((tmp_T > bmsMem.mcu_utc) && (tmp_T <= 127)) //不超过保护值才能写入,范围:-128~127 { bmsMem.mcu_utcr = tmp_T; flashUpdateFlag = 2; } } //修改放电高温保护值:A5 5A 06 83 02 1B 01 dataH dataL if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x1B)) { //放电高温 tmp_T = sdwaBuf[7]<<8 | sdwaBuf[8]; if((tmp_T >= -118) && (tmp_T <= 127)) //范围:-118~127(考虑到释放值最小-128,这里-128+10) { bmsMem.mcu_otd = tmp_T; //放电高温释放=-10℃ tmp_T = tmp_T-10; bmsMem.mcu_otdr = tmp_T; flashUpdateFlag = 2; } } //修改放电高温保护释放值:A5 5A 06 83 02 1B 01 dataH dataL if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x2B)) { tmp_T = sdwaBuf[7]<<8 | sdwaBuf[8]; if((tmp_T >= -128) && (tmp_T < bmsMem.mcu_otd)) //不超过保护值才能写入,范围:-128~127 { bmsMem.mcu_otdr = tmp_T; flashUpdateFlag = 2; } } //修改放电低温保护值:A5 5A 06 83 02 1C 01 dataH dataL if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x1C)) { //放电低温 tmp_T = sdwaBuf[7]<<8 | sdwaBuf[8]; if((tmp_T >= -128) && (tmp_T <= 124)) //范围:-128~124(考虑到释放值最大127,这里127-3) { bmsMem.mcu_utd = tmp_T; //放电低温释放=+3℃ tmp_T = tmp_T+3; bmsMem.mcu_utdr = tmp_T; flashUpdateFlag = 2; } } //修改放电低温保护释放值:A5 5A 06 83 02 1C 01 dataH dataL if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x2C)) { tmp_T = sdwaBuf[7]<<8 | sdwaBuf[8]; if((tmp_T > bmsMem.mcu_utd) && (tmp_T <= 127)) //不超过保护值才能写入,范围:-128~127 { bmsMem.mcu_utdr = tmp_T; flashUpdateFlag = 2; } } /**功能按钮**/ //释放地址限制的按钮 if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x95)) { if(paraMem.addr_FREE_Flg != 1) { paraMem.addr_FREE_Flg = 1; SDWA_Send_VAR(0x0294, 1); //若改为手动控制,则及时将当前地址写入EEPROM tmpWr[0] = bmsMem.E2_485Addr; EEPROM_WrMulByte(EE_ADDR,&tmpWr[0]); delay_ms(5); } else { paraMem.addr_FREE_Flg = 0; SDWA_Send_VAR(0x0294, 0); } flashUpdateFlag = 1; } //欠压强制复位按钮 if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x91)) { SDWA_Send_VAR(0x0290, 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; } SDWA_Send_VAR(0x0290, 2); //按钮变红 } //温度失效开关_T1 if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x04) && (sdwaBuf[5]==0x10)) { if((paraMem.temp_disable & BIT0) == 0) { paraMem.temp_disable |= BIT0; } else { paraMem.temp_disable &= ~BIT0; } flashUpdateFlag = 1; } //温度失效开关_T2 else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x04) && (sdwaBuf[5]==0x11)) { if((paraMem.temp_disable & BIT1) == 0) { paraMem.temp_disable |= BIT1; } else { paraMem.temp_disable &= ~BIT1; } flashUpdateFlag = 1; } //温度失效开关_T3 else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x04) && (sdwaBuf[5]==0x12)) { if((paraMem.temp_disable & BIT2) == 0) { paraMem.temp_disable |= BIT2; } else { paraMem.temp_disable &= ~BIT2; } flashUpdateFlag = 1; } //温度失效开关_T4 else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x04) && (sdwaBuf[5]==0x13)) { if((paraMem.temp_disable & BIT3) == 0) { paraMem.temp_disable |= BIT3; } else { paraMem.temp_disable &= ~BIT3; } flashUpdateFlag = 1; } //删除记录按钮 if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x01) && (sdwaBuf[5]==0x70)) //当按钮按下 { uint16_t i; uint16_t pc; //待写入地址 uint8_t adrh,adrl; uint8_t wrBuf[64]; SDWA_Send_VAR(0x0160, 1); if(soe.num != 0) //存在记录,才去删除记录 { //先清空具体内容 pc = 0x1000; for(i=0;i<64;i++) { wrBuf[i] = 0xff; } for(i=0;i<100;i++) { adrh = (pc>>8) & 0xff; adrl = pc & 0xff; EEPROM_WrMulByte(EE_SOE,wrBuf); delay_ms(10); pc += 0x40; } //再清空统计数据 soe.index = 0; //起始序号0 soe.pc = 0x1000; //起始地址0x1000 soe.num = 0; //起始数量0 wrBuf[0] = (soe.index >> 24) & 0xff ; wrBuf[1] = (soe.index >> 16) & 0xff ; wrBuf[2] = (soe.index >> 8) & 0xff ; wrBuf[3] = (soe.index >> 0) & 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; } //读取记录按钮——上下按键选择读取的地址 if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x01) && (sdwaBuf[5]==0x50) && (sdwaBuf[6]==0x01)) { if(read_index > 0) { scr_RdRecord_Flg = 1; read_index -= 3; //对应序号 } } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x01) && (sdwaBuf[5]==0x51) && (sdwaBuf[6]==0x01)) { if(read_index < 99) { scr_RdRecord_Flg = 1; read_index += 3; //对应序号 } } //初始化EEPROM按钮——地址范围0x0200~0x03FF(出厂前刷新内容) if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x01) && (sdwaBuf[5]==0x53)) //当按钮按下 { uint16_t i; uint16_t pc; //待写入地址 uint8_t adrh,adrl; uint8_t wrBuf[64]; SDWA_Send_VAR(0x0152, 1); //按钮变黄,正在执行 //485地址、IAP标志存在0x0000~0x01FF中,不更改 //电流校准值,已在初始化时进行判断转移,不再操作 //清空EEPROM地址0x0200-0x03FF,存放如容量和SOC一类参数 pc = 0x0200; for(i=0;i<64;i++) { wrBuf[i] = 0xff; } for(i=0;i<8;i++) { adrh = (pc>>8) & 0xff; adrl = pc & 0xff; EEPROM_WrMulByte(EE_CLEAR,wrBuf); delay_ms(10); pc += 0x40; } EE_clearFlag = 1; // } /**轮询页的选择——主机1肯定可选,其他要看是否在线**/ if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x60)) { scr_RdData_Index = 1; sdwa_ExitTotal_Flg = 0; //自己跳回了首页,那就不需要再跳转 SDWA_Send_VAR(0x0240, scr_RdData_Index ); SDWA_JumpToHome(); } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x61)) { if((canMem[2].com != 0) && (ConfigData_Index == 1)) //对应从机在线且上位机不在询问从机 { scr_RdData_Index = 2; SDWA_Send_VAR(0x0240, scr_RdData_Index ); SDWA_JumpToHome(); } } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x62)) { if((canMem[3].com != 0) && (ConfigData_Index == 1)) //对应从机在线且上位机不在询问从机 { scr_RdData_Index = 3; SDWA_Send_VAR(0x0240, scr_RdData_Index ); SDWA_JumpToHome(); } } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x63)) { if((canMem[4].com != 0) && (ConfigData_Index == 1)) //对应从机在线且上位机不在询问从机 { scr_RdData_Index = 4; SDWA_Send_VAR(0x0240, scr_RdData_Index ); SDWA_JumpToHome(); } } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x64)) { if((canMem[5].com != 0) && (ConfigData_Index == 1)) //对应从机在线且上位机不在询问从机 { scr_RdData_Index = 5; SDWA_Send_VAR(0x0240, scr_RdData_Index ); SDWA_JumpToHome(); } } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x65)) { if((canMem[6].com != 0) && (ConfigData_Index == 1)) //对应从机在线且上位机不在询问从机 { scr_RdData_Index = 6; SDWA_Send_VAR(0x0240, scr_RdData_Index ); SDWA_JumpToHome(); } } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x66)) { if((canMem[7].com != 0) && (ConfigData_Index == 1)) //对应从机在线且上位机不在询问从机 { scr_RdData_Index = 7; SDWA_Send_VAR(0x0240, scr_RdData_Index ); SDWA_JumpToHome(); } } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x67)) { if((canMem[8].com != 0) && (ConfigData_Index == 1)) //对应从机在线且上位机不在询问从机 { scr_RdData_Index = 8; SDWA_Send_VAR(0x0240, scr_RdData_Index ); SDWA_JumpToHome(); } } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x68)) { if((canMem[9].com != 0) && (ConfigData_Index == 1)) //对应从机在线且上位机不在询问从机 { scr_RdData_Index = 9; SDWA_Send_VAR(0x0240, scr_RdData_Index ); SDWA_JumpToHome(); } } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x69)) { if((canMem[10].com != 0) && (ConfigData_Index == 1)) //对应从机在线且上位机不在询问从机 { scr_RdData_Index = 10; SDWA_Send_VAR(0x0240, scr_RdData_Index ); SDWA_JumpToHome(); } } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x6A)) { if((canMem[11].com != 0) && (ConfigData_Index == 1)) //对应从机在线且上位机不在询问从机 { scr_RdData_Index = 11; SDWA_Send_VAR(0x0240, scr_RdData_Index ); SDWA_JumpToHome(); } } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x6B)) { if((canMem[12].com != 0) && (ConfigData_Index == 1)) //对应从机在线且上位机不在询问从机 { scr_RdData_Index = 12; SDWA_Send_VAR(0x0240, scr_RdData_Index ); SDWA_JumpToHome(); } } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x6C)) { if((canMem[13].com != 0) && (ConfigData_Index == 1)) //对应从机在线且上位机不在询问从机 { scr_RdData_Index = 13; SDWA_Send_VAR(0x0240, scr_RdData_Index ); SDWA_JumpToHome(); } } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x6D)) { if((canMem[14].com != 0) && (ConfigData_Index == 1)) //对应从机在线且上位机不在询问从机 { scr_RdData_Index = 14; SDWA_Send_VAR(0x0240, scr_RdData_Index ); SDWA_JumpToHome(); } } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x06E)) { if((canMem[15].com != 0) && (ConfigData_Index == 1)) //对应从机在线且上位机不在询问从机 { scr_RdData_Index = 15; SDWA_Send_VAR(0x0240, scr_RdData_Index ); SDWA_JumpToHome(); } } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x02) && (sdwaBuf[5]==0x6F)) { if((canMem[16].com != 0) && (ConfigData_Index == 1)) //对应从机在线且上位机不在询问从机 { scr_RdData_Index = 16; SDWA_Send_VAR(0x0240, scr_RdData_Index ); SDWA_JumpToHome(); } } /**协议选择——共42项**/ //A5 5A 06 83 03 10 01 00 01 勾选 //A5 5A 06 83 03 10 01 00 00 取消勾选 //A5 5A 05 82 03 00 00 01 显示勾选 //A5 5A 05 82 03 00 00 00 显示取消勾选 if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x10)) { if(protocol_Index !=1) protocol_Index = 1; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x11)) { if(protocol_Index !=2) protocol_Index = 2; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x12)) { if(protocol_Index !=3) protocol_Index = 3; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x13)) { if(protocol_Index !=4) protocol_Index = 4; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x14)) { if(protocol_Index !=5) protocol_Index = 5; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x15)) { if(protocol_Index !=6) protocol_Index = 6; else protocol_Index = 0; } //第2页相关 else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x16)) { if(protocol_Index !=7) protocol_Index = 7; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x17)) { if(protocol_Index !=8) protocol_Index = 8; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x18)) { if(protocol_Index !=9) protocol_Index = 9; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x19)) { if(protocol_Index !=10) protocol_Index = 10; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x1A)) { if(protocol_Index !=11) protocol_Index = 11; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x1B)) { if(protocol_Index !=12) protocol_Index = 12; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x1C)) { if(protocol_Index !=13) protocol_Index = 13; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x1D)) { if(protocol_Index !=14) protocol_Index = 14; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x1E)) { if(protocol_Index !=15) protocol_Index = 15; else protocol_Index = 0; } //第3页相关 else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x1F)) { if(protocol_Index !=16) protocol_Index = 16; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x30)) { if(protocol_Index !=17) protocol_Index = 17; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x31)) { if(protocol_Index !=18) protocol_Index = 18; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x32)) { if(protocol_Index !=19) protocol_Index = 19; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x33)) { if(protocol_Index !=20) protocol_Index = 20; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x34)) { if(protocol_Index !=21) protocol_Index = 21; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x35)) { if(protocol_Index !=22) protocol_Index = 22; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x36)) { if(protocol_Index !=23) protocol_Index = 23; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x37)) { if(protocol_Index !=24) protocol_Index = 24; else protocol_Index = 0; } //第4页相关 else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x38)) { if(protocol_Index !=25) protocol_Index = 25; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x39)) { if(protocol_Index !=26) protocol_Index = 26; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x3A)) { if(protocol_Index !=27) protocol_Index = 27; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x3B)) { if(protocol_Index !=28) protocol_Index = 28; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x3C)) { if(protocol_Index !=29) protocol_Index = 29; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x3D)) { if(protocol_Index !=30) protocol_Index = 30; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x3E)) { if(protocol_Index !=31) protocol_Index = 31; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x3F)) { if(protocol_Index !=32) protocol_Index = 32; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x50)) { if(protocol_Index !=33) protocol_Index = 33; else protocol_Index = 0; } //第5页相关 else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x51)) { if(protocol_Index !=34) protocol_Index = 34; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x52)) { if(protocol_Index !=35) protocol_Index = 35; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x53)) { if(protocol_Index !=36) protocol_Index = 36; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x54)) { if(protocol_Index !=37) protocol_Index = 37; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x57)) //在这里跳过2个地址 { if(protocol_Index !=38) protocol_Index = 38; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x58)) { if(protocol_Index !=39) protocol_Index = 39; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x59)) { if(protocol_Index !=40) protocol_Index = 40; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x5A)) { if(protocol_Index !=41) protocol_Index = 41; else protocol_Index = 0; } else if((sdwaBuf[2]==0x06) && (sdwaBuf[3]==0x83) && (sdwaBuf[4]==0x03) && (sdwaBuf[5]==0x5B)) { if(protocol_Index !=42) protocol_Index = 42; else protocol_Index = 0; } uf_CAN1_Init(); if(protocol != protocol_Index) { protocol = protocol_Index; EEPROM_WrMulByte(EE_PROTOCOL,&protocol); delay_ms(5); } } /**屏幕配置参数的写入**/ if(flashUpdateFlag != 0) //配置参数的CRC校验码计算和写入 { uint8_t i; uint8_t* data; uint8_t temp[26]; //要计算校验码 if(flashUpdateFlag >= 2) //2代表修改单个参数,3代表初始化所有参数 》》但都需要计算CRC值 { SDWA_Send_VAR(0x0145, 1); //显示请等待 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; //初始化参数成功后,要显示一段时间后恢复正常 if(flashUpdateFlag == 3) { initFlag = 1; SDWA_Send_VAR(0x01A4, 2); //初始化成功 } //清空值 flashUpdateFlag = 0; } /**除了屏幕亮度的程序外,其他默认都会初始化**/ if(sdwa_sleep_flag != 1) { SCR_DispProcotol(); if(sleep_flag == 1) { //有屏幕操作/摁亮屏幕,退出休眠且更新计时起点 sleep_flag = 0; SLEEP_Refresh(); SLEEP2_Refresh(); } } else { sdwaBufIndex = 0; } } }