//--------------------------------------------------------------------- #include #include #include /*标准输入输出定义*/ #include /*标准函数库定义*/ #include #include /*Unix 标准函数定义*/ #include #include #include /*文件控制定义*/ #include /*PPSIX 终端控制定义*/ #include /*错误号定义*/ #include "slavepc.h" #include "crc16.h" #include "filemanage.h" #include "classxml.h" #define SYSCODE 0xAAAAAAAA #define Version 12 #define ADJ_VOL 0 #define ADJ_DIS 1 #define ADJ_CHR 2 //#define EN_THREAD_WORK_DEBUG #ifdef EN_THREAD_WORK_DEBUG #define THREAD_WORK_DEBUG qDebug #else #define THREAD_WORK_DEBUG(...) #endif SlavePC::SlavePC(Working_Page *page) { work_page = page; RUN_EN = false; this->OpenDev(PCCommPort); this->SetDevAttr(19200,8,1,'N'); connect(this,SIGNAL(SendInterface(int)),work_page->work_thread,SLOT(RecvInterface(int))); connect(this,SIGNAL(sendParam(int)),work_page,SLOT(operatorCMD_Work(int))); } SlavePC::~SlavePC() { RUN_EN = false; quit(); wait(); } //--------------------------------------------------------------------- //--------------------------------------------------------------------- /** *@brief 设置串口通信速率 *@param fd 类型 int 打开串口的文件句柄 *@param speed 类型 int 串口速度 *@return void */ //--------------------------------------------------------------------- //--------------------------------------------------------------------- static int speed_arr[] = { B115200, B57600, B38400, B19200, B9600}; static int name_arr[] = { 115200, 57600, 38400, 19200, 9600}; void SlavePC::set_speed(int fd, int speed) { int status; struct termios Opt; tcgetattr(fd, &Opt); for ( unsigned int i= 0; i < sizeof(speed_arr) / sizeof(int); i++) { if(speed == name_arr[i]) { tcflush(fd, TCIOFLUSH); cfsetispeed(&Opt, speed_arr[i]); cfsetospeed(&Opt, speed_arr[i]); status = tcsetattr(fd, TCSANOW, &Opt); if(status != 0) { perror("tcsetattr fd1"); return; } tcflush(fd,TCIOFLUSH); } } } //--------------------------------------------------------------------- /** *@brief 设置串口数据位,停止位和效验位 *@param fd 类型 int 打开的串口文件句柄 *@param databits 类型 int 数据位 取值 为 7 或者8 *@param stopbits 类型 int 停止位 取值为 1 或者2 *@param parity 类型 int 效验类型 取值为N,E,O,,S */ //--------------------------------------------------------------------- int SlavePC::set_Parity(int fd,int databits,int stopbits,int parity) { struct termios options; if(tcgetattr(fd, &options) != 0) { perror("SetupSerial 1"); return(-1); } //--------------- 二进制传输模式 ------------------------- options.c_iflag = 0; options.c_oflag = 0; //------------------------------------------------------ options.c_cflag &= ~CSIZE; options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);/*Input*/ options.c_oflag &= ~OPOST;/*Output*/ switch (databits) /*设置数据位数*/ { case 7: options.c_cflag |= CS7; break; case 8: options.c_cflag |= CS8; break; default: fprintf(stderr,"Unsupported data size\n"); return (-1); } switch (parity) { case 'n': case 'N': options.c_cflag &= ~PARENB; /* Clear parity enable */ options.c_iflag &= ~INPCK; /* Enable parity checking */ break; case 'o': case 'O': options.c_cflag |= (PARODD | PARENB); /* 设置为奇效验*/ options.c_iflag |= INPCK; /* Disnable parity checking */ break; case 'e': case 'E': options.c_cflag |= PARENB; /* Enable parity */ options.c_cflag &= ~PARODD; /* 转换为偶效验*/ options.c_iflag |= INPCK; /* Disnable parity checking */ break; case 'S': case 's': /*as no parity*/ options.c_cflag &= ~PARENB; options.c_cflag &= ~CSTOPB; break; default: fprintf(stderr,"Unsupported parity\n"); return (-1); } /* 设置停止位*/ switch (stopbits) { case 1: options.c_cflag &= ~CSTOPB; break; case 2: options.c_cflag |= CSTOPB; break; default: fprintf(stderr,"Unsupported stop bits\n"); return (-1); } /* Set input parity option */ if (parity != 'n') options.c_iflag |= INPCK; tcflush(fd, TCIFLUSH); options.c_cc[VTIME] = 0; /* 0.1S */ options.c_cc[VMIN] = 0; /* Update the options and do it NOW */ if (tcsetattr(fd,TCSANOW,&options) != 0) { perror("SetupSerial 3"); return (-1); } return (0); } //--------------------------------------------------------------------- int SlavePC::OpenDev(const char *Dev) { FD = open(Dev, O_RDWR|O_NOCTTY|O_NDELAY); return FD; } //--------------------------------------------------------------------- void SlavePC::SetDevAttr(int bitrate, char bitlen, char stopbitlen, char checktype) { if(FD < 0) return; set_speed(FD, bitrate); if(set_Parity(FD, bitlen, stopbitlen, checktype) < 0) { qDebug("Set Parity Error\n"); } if(fcntl(FD, F_SETFL, FNDELAY) < 0)//非阻塞,覆盖前面open的属性 { qDebug("fcntl failed\n"); } } //--------------------------------------------------------------------- int SlavePC::WriteDev(void *buf, int len) { if(FD < 0) return 0; return write(FD, (char *)buf, len); } //--------------------------------------------------------------------- int SlavePC::ReadDev(void *buf, int len) { if(FD < 0) return 0; char *pbuff = (char *)buf; return (read(FD, pbuff, len)); } bool SlavePC::CheckLen(FRAME_DATA *recv) { if(recv->Len >= 18) { return true; } return false; } bool SlavePC::CheckSYNCode(FRAME_DATA *recv) { if(recv->SYNCode == SYSCODE) { return true; } return false; } bool SlavePC::CheckCRC(FRAME_DATA *recv) { unsigned short Temp = recv->CRC; recv->CRC =0; recv->CRC = CRC16::CalCRC16(recv,recv->Len); if(recv->CRC == Temp) { return true; } return false; } bool SlavePC::WriteFrameData(FRAME_DATA *Sent) { if(Sent->Len == WriteDev(Sent,Sent->Len)) return true; else return false; } bool SlavePC::ReadFrameHead(FRAME_DATA *recv, FRAME_DATA *Sent) { if(ReadDev(recv,18)==18) { if(CheckSYNCode(recv) == true) { if(CheckLen(recv) == false) { Sent->RecState = LEN_ERR; } return true; } } return false; } bool SlavePC::ReadFrameData(FRAME_DATA &recv, FRAME_DATA &Sent) { if(ReadFrameHead(&recv,&Sent) == true) { if(Sent.RecState == SUCCEED) { if(CheckCRC(&recv) == false) { Sent.RecState = CRC_ERR; } } return true; } return false; } //---------------------------------------------------------------------------------- quint16 SlavePC::getMonData(quint8 *info,quint16 MonNum) { static quint8 cnt = 0; static quint8 bak_state = 0; MON_DATA mondata; memset(&mondata,0,sizeof(MON_DATA)); for(int i=0;i<4;i++) { mondata.GroupVol[i] = work_page->work_thread->fboData.SumVoltage; mondata.GroupCur[i] = work_page->work_thread->fboData.SubCurrent[i]; mondata.reserved[0] = work_page->work_thread->fboData.OnlineVol; if(work_page->work_thread->DATAVERSION == 0x05) mondata.reserved[3] = work_page->work_thread->DATAVERSION<<8; if(work_page->work_thread->localData.SysWorkState == Discharging || work_page->work_thread->localData.SysWorkState == Paused_Dischg) { bak_state = work_page->work_thread->localData.SysWorkState; cnt = 5; } else cnt = 0; if((cnt > 0) && (work_page->work_thread->localData.SysWorkState == WorkStopped)) { cnt--; mondata.BattStatus[0] = bak_state + 0x80; mondata.GroupCur[0] = 0; } else { mondata.BattStatus[0] = work_page->work_thread->localData.SysWorkState + 0x80; bak_state = work_page->work_thread->localData.SysWorkState; if(work_page->work_thread->localData.SysWorkState == WorkStopped/* && work_page->work_thread->localData.deviceTestType != TYPE_ON_LINE*/) mondata.GroupCur[0] = 0; } } mondata.BattStatus[1] = 0x80; mondata.BattStatus[2] = 0x80; mondata.BattStatus[3] = 0x80; if(MonNum>300) MonNum = 100; memcpy(mondata.MonomerVol,work_page->work_thread->fboData.SingleVol,MonNum*2); memcpy(info,&mondata,32 + MonNum*2); return 32 + MonNum*2; } //quint16 SlaveCtrl::getAdjData(quint8 *info) //{ // ADJ_DATA adjdata; // memset(&adjdata,0,sizeof(adjdata)); // adjdata.OnlineVol = work_page->work_thread->fboData.OnlineVol; // adjdata.GroupVol = 0.1*work_page->work_thread->fboData.SumVoltage; // adjdata.dis_cur = 0.1*work_page->work_thread->fboData.SumCurrent; // adjdata.chr_cur = 0.1*work_page->work_thread->fboData.SumCurrent; // adjdata.out_cur = 0; // memcpy(info,&adjdata,sizeof(ADJ_DATA)); // return sizeof(ADJ_DATA); //} quint16 SlavePC::getTestData(quint8 *info) { TEST_DATA testdata; memset(&testdata,0,sizeof(testdata)); testdata.OnlineVol = work_page->work_thread->fboData.OnlineVol; testdata.GroupVol = work_page->work_thread->fboData.SumVoltage; testdata.CurrTime = work_page->work_thread->getTestFileTime(); testdata.testtime = work_page->work_thread->fboData.m_TestTime; if(work_page->work_thread->localData.SysWorkState == Paused_Dischg || work_page->work_thread->localData.SysWorkState == Paused_charge) { testdata.KeyState = 1; } else if(work_page->work_thread->localData.SysWorkState == Charging || work_page->work_thread->localData.SysWorkState == WaitForCharging) { testdata.KeyState = work_page->work_thread->localData.SysWorkState-1; } else { testdata.KeyState = work_page->work_thread->localData.SysWorkState; } if(work_page->work_thread->localData.SysWorkState == Discharging) testdata.monomerCount = work_page->work_thread->localData.monomerLowCount; // else if(work_page->work_thread->localData.SysWorkState == Charging) // testdata.monomerCount = work_page->work_thread->localData.monomerHighCount; testdata.curr_cur = work_page->work_thread->fboData.SumCurrent;//*0.1 testdata.AllCap = work_page->work_thread->fboData.AllCap; testdata.SMaxIndex = work_page->work_thread->localData.SMaxIndex[0]; testdata.SMaxVol = work_page->work_thread->localData.SMaxVol[0]; testdata.SMinIndex = work_page->work_thread->localData.SMinIndex[0]; testdata.SMinVol = work_page->work_thread->localData.SMinVol[0]; testdata.dischgTimes = work_page->work_thread->localData.dischgTimes; //testdata.HighTemp = work_page->work_thread->GetBYDInfo()->temp_hight; //testdata.LowTTemp = work_page->work_thread->GetBYDInfo()->temp_low; if(work_page->work_thread->localData.SysWorkState == WorkStopped/* && work_page->work_thread->localData.deviceTestType != TYPE_ON_LINE*/) testdata.curr_cur = 0; if(work_page->work_thread->fboData.SumVoltagework_thread->localData.RLY_OK&(~IGBT_VALUE); } else testdata.reserved[0] = work_page->work_thread->localData.RLY_OK; memcpy(info,&testdata,sizeof(TEST_DATA)); return sizeof(TEST_DATA); } quint8 *SlavePC::getFileDataHead(FILE_LIST_DATA &data,TEST_DATA_INFO &test_info,quint8 total,quint8 Index) { data.TotalFileNum = total; data.CurrFileIndex = Index; data.TestStartTime = test_info.fbo_data_head_start.TestStartTime; data.TestTimeLong = test_info.fbo_data_head_stop.TestTimeLong; data.DataType = test_info.fbo_data_head_start.DataType; data.TestCur = test_info.fbo_data_head_start.TestCur; data.TestCap = test_info.fbo_data_head_stop.TestCap; data.STDCap = test_info.fbo_data_head_start.STDCap; data.MVLLimit = test_info.fbo_data_head_start.MVLLimit; data.SumVLLimit = test_info.fbo_data_head_start.SumVLLimit; data.BattSum = test_info.fbo_data_head_start.BattSum; data.BattGroup = test_info.fbo_data_head_start.BattGroup; data.StopType = test_info.fbo_data_head_stop.StopType; data.MonomerVol = test_info.fbo_data_head_start.MonomerVol; return (quint8 *)&data; } quint16 SlavePC::getPageFileData(FRAME_DATA &recv, FRAME_DATA &Sent) { quint8 i; quint8 page = recv.Db1; quint16 j=0; FileManage fileManage; QStringList nameList = fileManage.getFiles(work_page->batteryName+"/",".FBO"); TEST_DATA_INFO test_info; FILE_LIST_DATA file_data; if(page*8 > nameList.count()) { Sent.RecState = FILE_DATA_ERR; return 0; } for(i=0;i<8 && i+page*8batteryName+"/"+nameList.at(i+page*8),test_info)) { getFileDataHead(file_data,test_info,nameList.count(),i+page*8); memcpy(Sent.info+j,&file_data,sizeof(FILE_LIST_DATA)); j += sizeof(FILE_LIST_DATA); } } return j; } quint16 SlavePC::getFileSmallBlock(FRAME_DATA &recv, FRAME_DATA &Sent) { quint16 Cnt_len=0; quint16 total_block=0; quint16 file_index = recv.RecState*256+recv.type; quint16 smallBlock = recv.workState*256+recv.Alarm; FileManage fileManage; QStringList nameList = fileManage.getFiles(work_page->batteryName+"/",".FBO"); if(file_index >= nameList.count()) { Sent.RecState = FILE_DATA_ERR; return 0; } if(ClassXML::ReadsmallBlockDataFBO(dataDir+work_page->batteryName+"/"+nameList.at(file_index), Sent.info,Cnt_len,total_block,smallBlock)) { Sent.Db1 = (total_block>>8)&0xFF; Sent.Db2 = (total_block)&0xFF; Sent.Db3 = (smallBlock>>8)&0xFF; Sent.Db4 = (smallBlock)&0xFF; return Cnt_len; } return 0; } quint16 SlavePC::getBattName(FRAME_DATA &recv, FRAME_DATA &Sent) { quint16 batt_index = recv.RecState*256+recv.type; QStringList batt_list = FileManage::getDirs(); quint16 batt_total = batt_list.count(); if(batt_index >= batt_total) { Sent.RecState = FILE_DATA_ERR; return 0; } Sent.Db1 = (batt_total>>8)&0xFF; Sent.Db2 = batt_total&0xFF; Sent.Db3 = recv.RecState; Sent.Db4 = recv.type; QString battname = batt_list.at(batt_index); memcpy(Sent.info,battname.toUtf8().data(),battname.toUtf8().length()); return battname.toUtf8().length(); } quint16 SlavePC::getfileName(FRAME_DATA &recv, FRAME_DATA &Sent) { quint16 batt_index = recv.RecState*256+recv.type; quint16 file_index = recv.workState*256+recv.Alarm; QStringList batt_list = FileManage::getDirs(); QStringList file_List = FileManage::getFiles(batt_list.at(batt_index)+"/",".FBO"); quint16 batt_total = batt_list.count(); quint16 file_total = file_List.count(); if(batt_index >= batt_total || file_index >= file_total) { if(file_index > 0) { Sent.RecState = FILE_DATA_ERR; } return 0; } Sent.Db1 = (file_total>>8)&0xFF; Sent.Db2 = file_total&0xFF; Sent.Db3 = recv.workState; Sent.Db4 = recv.Alarm; QString filename = file_List.at(file_index); memcpy(Sent.info,filename.toUtf8().data(),filename.toUtf8().length()); return filename.toUtf8().length(); } quint16 SlavePC::getSelectFile(FRAME_DATA &recv, FRAME_DATA &Sent) { QString path_name = QString::fromUtf8((const char *)recv.info,recv.Len-18); //qDebug()<<"111111"<= total_block) { Sent.RecState = FILE_DATA_ERR; } Sent.Db1 = (total_block>>8)&0xFF; Sent.Db2 = (total_block)&0xFF; Sent.Db3 = (smallBlock>>8)&0xFF; Sent.Db4 = (smallBlock)&0xFF; return Cnt_len; } Sent.RecState = OTHER_ERR; return 0; } quint16 SlavePC::getVersion(FRAME_DATA &recv, FRAME_DATA &Sent) { Sent.RecState = recv.RecState; QString battname = phoneVersion; memcpy(Sent.info,battname.toUtf8().data(),battname.toUtf8().length()); return battname.toUtf8().length(); } void SlavePC::SaveTestParam(const QString &fname,TEST_PARAM_XML &test_param) { if(ClassXML::CreateTestParamXml(fname,test_param)) //新建的 { } else //原有的 { ClassXML::ModifyTestParamXml(fname,test_param); } } void SlavePC::NewBattFile(quint8 *info) { QString newname((const char *)info); if(work_page->batteryName != newname) { ClassXML::ModifyNewestPNameXml(newname); work_page->batteryName = newname; SaveTestParam(newname,work_page->test_param_xml); } } bool SlavePC::SelectBatt(quint8 *info) { QString newname((const char *)info); TEST_PARAM_XML testParam; if(true == ClassXML::ReadTestParamXml(newname, testParam)) { ClassXML::ModifyNewestPNameXml(newname); work_page->batteryName = newname; emit sendParam(PARAM_PAGE_CMD_PARAM); return true; } return false; } void SlavePC::DeleteBatt(quint8 *info) { QString newname((const char *)info); FileManage fileManage; if(newname == Default_Battery) { fileManage.clearDirectoryFiles(Default_Battery,fileManage.getFiles(Default_Battery,".FBO")); } else { fileManage.removeDir(dataDir+newname); } if(work_page->batteryName == newname) { newname = Default_Battery; ClassXML::ModifyNewestPNameXml(newname); work_page->batteryName = newname; emit sendParam(PARAM_PAGE_CMD_PARAM); } } //---------------------------------------------------------------------------------- void SlavePC::SlaveClearHeart() { work_page->work_thread->localData.rs485_pc.heart_cnt = 0; } void SlavePC::SlaveDisposeCMD(FRAME_DATA &recv, FRAME_DATA &Sent) { if((work_page->work_thread->localData.rs485_pc.Enter_ctrl == 0)&&(recv.CMD != EnterSlave)) { Sent.RecState = SLAVEMODE_ERR; return; } switch (recv.CMD) { case Heartbea: //SlaveClearHeart(dev); break; case ExitSlave: work_page->work_thread->localData.rs485_pc.Enter_ctrl = 0; break; case EnterSlave: if(work_page->work_thread->localData.rs485_pc.Enter_ctrl) { break; } qDebug("get CMD = %x",recv.CMD); work_page->work_thread->localData.rs485_pc.Enter_ctrl = 1; if(work_page->work_thread->localData.SysWorkState == WorkStopped && work_page->work_thread->localData.pauseBtnState == 0) { emit SendInterface(FACE_HOME); } else { Sent.RecState = SLAVEMODE_ERR; } break; case StartDischarge: if((work_page->work_thread->localData.SysWorkState == WorkStopped||work_page->work_thread->localData.SysWorkState == Paused_Dischg)&& work_page->work_thread->localData.pauseBtnState!=2) emit sendParam(PARAM_PAGE_CMD_START_DIS);//emit sendStart(work_page->work_thread->CMD_StartDischarge,work_page->batteryName); else Sent.RecState = START_ERR; break; case PausetDischarge: if(work_page->work_thread->localData.SysWorkState == Discharging || work_page->work_thread->localData.SysWorkState == Paused_Dischg) emit sendParam(PARAM_PAGE_CMD_PAUSE);//emit sendStart(work_page->work_thread->CMD_PauseDischarge,work_page->batteryName); else Sent.RecState = START_ERR; break; case StopDischarge: if(work_page->work_thread->localData.SysWorkState == Paused_Dischg || work_page->work_thread->localData.SysWorkState == Discharging) emit sendParam(PARAM_PAGE_CMD_STOP);//emit sendStart(work_page->work_thread->CMD_StopDischarge,work_page->batteryName); else Sent.RecState = START_ERR; break; case StartCharge: if(work_page->work_thread->localData.SysWorkState == WorkStopped ||work_page->work_thread->localData.SysWorkState == Paused_charge) emit sendParam(PARAM_PAGE_CMD_START_CHR);//emit sendStart(work_page->work_thread->CMD_StartCharge,work_page->batteryName); else Sent.RecState = START_ERR; break; case PauseCharge: if(work_page->work_thread->localData.SysWorkState == Charging) emit sendParam(PARAM_PAGE_CMD_PAUSE);//emit sendStart(work_page->work_thread->CMD_PauseCharge,work_page->batteryName); else Sent.RecState = START_ERR; break; case StopCharge: if(work_page->work_thread->localData.SysWorkState == Paused_charge || work_page->work_thread->localData.SysWorkState == Charging) emit sendParam(PARAM_PAGE_CMD_STOP);//emit sendStart(work_page->work_thread->CMD_StopCharge,work_page->batteryName); else Sent.RecState = START_ERR; break; // case StartCycle: // if(work_page->work_thread->localData.SysWorkState == WorkStopped && work_page->work_thread->localData.deviceTestType == TYPE_CYCLE_TEST) // { // if(START_DISCHG == testParam.cycle_start) // emit sendParam(PARAM_PAGE_CMD_START_DIS); // else if(START_CHARGE == testParam.cycle_start) // emit sendParam(PARAM_PAGE_CMD_START_CHR); // else // Sent.RecState = START_ERR; // } // else // Sent.RecState = START_ERR; // break; // case PauseCycle: // if(work_page->work_thread->localData.SysWorkState != WorkStopped && work_page->work_thread->localData.deviceTestType == TYPE_CYCLE_TEST) // emit sendParam(PARAM_PAGE_CMD_PAUSE); // else // Sent.RecState = START_ERR; // break; // case StopCycle: // if(work_page->work_thread->localData.SysWorkState != WorkStopped && work_page->work_thread->localData.deviceTestType == TYPE_CYCLE_TEST) // emit sendParam(PARAM_PAGE_CMD_STOP); // else // Sent.RecState = START_ERR; // break; // case Adjust_StartDischarge: // if(work_page->work_thread->localData.SysWorkState == WorkStopped) // emit sendStart(work_page->work_thread->CMD_Adj_StartDis,work_page->batteryName); // else // Sent.RecState = START_ERR; // break; // case Adjust_StartCharge: // if(work_page->work_thread->localData.SysWorkState == WorkStopped) // emit sendStart(work_page->work_thread->CMD_Adj_StartChr,work_page->batteryName); // else // Sent.RecState = START_ERR; // break; // case Adjust_Stop: // if(work_page->work_thread->localData.SysWorkState == Discharging) // emit sendStart(work_page->work_thread->CMD_Adj_StopDis,work_page->batteryName); // else if(work_page->work_thread->localData.SysWorkState == Charging) // emit sendStart(work_page->work_thread->CMD_Adj_StopChr,work_page->batteryName); // else // Sent.RecState = START_ERR; // break; // case SetAdjustParm: // if(recv.RecState == ADJ_VOL) // emit SendCurrAdjCMD(work_page->work_thread->CMD_SetGroupVol, // (recv.type*256+recv.workState-work_page->work_thread->localData.sim_buf.ADCVdin)); // else if(recv.RecState == ADJ_DIS) // emit SendCurrAdjCMD(work_page->work_thread->CMD_SetDisChargCur, // (recv.type*256+recv.workState-work_page->work_thread->localData.sim_buf.ADCId)); // else if(recv.RecState == ADJ_CHR) // emit SendCurrAdjCMD(work_page->work_thread->CMD_SetChargCur, // (recv.type*256+recv.workState-work_page->work_thread->localData.sim_buf.ADCIc)); // else // Sent.RecState = START_ERR; // break; case SetDischargeParam: case SetChargeParam: case SetCycleParam: if(sizeof(COMM_TEST_PARAM) == (recv.Len - 18)) { TEST_PARAM_XML testParam; setTestCommParam(testParam,recv.info); //memcpy(addr,recv.info,sizeof(testParam)); SaveTestParam(work_page->batteryName,testParam); emit sendParam(PARAM_PAGE_CMD_PARAM); } break; case EnterHome: { quint8 pageIndex = 0; if(recv.Len > 18) { pageIndex = recv.info[0]; } else { pageIndex = recv.RecState; } //qDebug("pageIndex = %d,work_page->work_thread->localData.Interface=%d",pageIndex,work_page->work_thread->localData.Interface); if(pageIndex != work_page->work_thread->localData.Interface) { if(work_page->work_thread->localData.SysWorkState == Paused_Dischg || work_page->work_thread->localData.SysWorkState == Paused_charge || work_page->work_thread->localData.SysWorkState == Discharging || work_page->work_thread->localData.SysWorkState == Charging || work_page->work_thread->localData.SysWorkState == WaitForCharging) Sent.RecState = SYSTEM_WORKING; else { emit SendInterface(pageIndex); } } break; } case NewBatt: NewBattFile(recv.info); break; case ChangedBatt: if(!SelectBatt(recv.info)) Sent.RecState = OTHER_ERR; break; case DelBatt: DeleteBatt(recv.info); break; case ClearAlarm: work_page->work_thread->localData.popBox = 0; emit sendParam(PARAM_PAGE_CLOSE_BOX); break; case SetTKQState: emit sendParam(PARAM_PAGE_CMD_START_PSW); break; case SetFanState: emit sendParam(PARAM_PAGE_CMD_START_FAN); break; case GetBattName: case GetFileName: case GetSelectFile: case GetCellData: case GetDischargeParam: case GetChargeParam: case GetDischargeData: case GetChargeData: case GetCycleParam: case GetAdjustData: case GetFileInfo: case GetFile: default: break; } } void SlavePC::SlaveSentFrame(FRAME_DATA &recv, FRAME_DATA &Sent) { static quint8 cnt = 0; static quint8 bak_state = 0; Sent.SYNCode = SYSCODE; Sent.CMD = recv.CMD; Sent.Len = 18; Sent.type = work_page->work_thread->localData.Interface + 0x80; if(work_page->work_thread->localData.SysWorkState == Discharging || work_page->work_thread->localData.SysWorkState == Paused_Dischg) { bak_state = work_page->work_thread->localData.SysWorkState; cnt = 5; } else cnt = 0; if((cnt > 0) && (work_page->work_thread->localData.SysWorkState == WorkStopped)) { cnt--; Sent.workState = bak_state; work_page->work_thread->fboData.SubCurrent[0] = 0; work_page->work_thread->fboData.SumCurrent = 0; } else { Sent.workState = work_page->work_thread->localData.SysWorkState; bak_state = work_page->work_thread->localData.SysWorkState; } if(work_page->work_thread->localData.TestType == TestTypeCharge) Sent.Alarm = work_page->work_thread->localData.WPAlarmState + work_page->work_thread->localData.popBox + 0x40; else Sent.Alarm = work_page->work_thread->localData.WPAlarmState + work_page->work_thread->localData.popBox; switch (recv.CMD) { case Heartbea: Sent.Db1 = 0;//work_page->work_thread->localData.rs485_pc.ID; memcpy(Sent.info,work_page->batteryName.toUtf8().data(),work_page->batteryName.toUtf8().length()); Sent.Len += work_page->batteryName.toUtf8().length(); break; case ExitSlave: case StartDischarge: case PausetDischarge: case StartCharge: case PauseCharge: case SetAdjustParm: case Adjust_StartDischarge: case Adjust_StartCharge: case Adjust_Stop: case NewBatt: case ChangedBatt: case DelBatt: case StopDischarge: case StopCharge: case ClearAlarm: case StartCycle: case PauseCycle: case StopCycle: case EnterHome: break; case EnterSlave: Sent.Db1 = Version; Sent.Db2 = 0; Sent.Db3 = 0xF4; break; case GetDischargeParam: case GetChargeParam: case GetCycleParam: // Sent.info = (quint8 *)&testParam; // Sent.Len += sizeof(testParam); getTestCommParam(work_page->test_param_xml,Sent.info); Sent.Len += sizeof(COMM_TEST_PARAM); break; case GetCellData: Sent.Db1 = work_page->test_param_xml.mon_number>>8; Sent.Db2 = work_page->test_param_xml.mon_number & 0xFF; Sent.Len += getMonData(Sent.info,work_page->work_thread->fboData.BattSum); break; case SetDischargeParam: case SetChargeParam: case SetCycleParam: Sent.Db1 = recv.Db1; break; case GetDischargeData: case GetChargeData: if(work_page->work_thread->localData.waitTimeCount) { Sent.Db2 = 1; quint16 timesec = work_page->work_thread->localData.waitTimeCount; Sent.Db3 = timesec/256; Sent.Db4 = timesec%256; } else if(((work_page->work_thread->localData.SysWorkState == Charging)&&(recv.CMD == GetDischargeData)) ||((work_page->work_thread->localData.SysWorkState == Discharging)&&(recv.CMD == GetChargeData))) { Sent.Db2 = 2; } Sent.Len += getTestData(Sent.info); break; // case GetAdjustData: // Sent.Len += getAdjData(Sent.info); // break; case GetFileInfo: Sent.Len += getPageFileData(recv, Sent); break; case GetFile: Sent.Len += getFileSmallBlock(recv,Sent); break; case GetBattName: Sent.Len += getBattName(recv,Sent); break; case GetFileName: Sent.Len += getfileName(recv,Sent); break; case GetSelectFile: Sent.Len += getSelectFile(recv,Sent); break; case GetVersion: Sent.Len += getVersion(recv,Sent); default: break; } Sent.CRC = CRC16::CalCRC16(&Sent,Sent.Len); WriteFrameData(&Sent); } void SlavePC::SlaveResponse(FRAME_DATA &recv,FRAME_DATA &Sent) { if(Sent.RecState == SUCCEED) { SlaveClearHeart();//任何有效指令都当作心跳指令 SlaveDisposeCMD(recv,Sent); } SlaveSentFrame(recv,Sent); } //--------------------------------------------------------------------- void SlavePC::SlaveMode(FRAME_DATA &recv,FRAME_DATA &Sent) { if(ReadFrameData(recv,Sent) == true) { SlaveResponse(recv,Sent); } } /******************************************************************************************/ void SlavePC::setTestCommParam(TEST_PARAM_XML &test_param,void *comm_param) { if(PageType == IDCE48CT) test_param.test_mode = OFFline_working; else if(PageType == FBI48CT) test_param.test_mode = ONline_working; else test_param.test_mode = ((COMM_TEST_PARAM *)comm_param)->test_mode; test_param.acstop_op = ((COMM_TEST_PARAM *)comm_param)->acstop_op; test_param.nominal_cap = ((COMM_TEST_PARAM *)comm_param)->nominal_cap; test_param.hourly_rate = ((COMM_TEST_PARAM *)comm_param)->hourly_rate; test_param.preset_cur = ((COMM_TEST_PARAM *)comm_param)->preset_cur; test_param.preset_cap = ((COMM_TEST_PARAM *)comm_param)->preset_cap; test_param.preset_time = ((COMM_TEST_PARAM *)comm_param)->preset_time; test_param.mon_lower = ((COMM_TEST_PARAM *)comm_param)->mon_lower; test_param.group_lower = ((COMM_TEST_PARAM *)comm_param)->group_lower; test_param.mon_number = ((COMM_TEST_PARAM *)comm_param)->mon_number; test_param.group_number = ((COMM_TEST_PARAM *)comm_param)->group_number; test_param.lower_number = ((COMM_TEST_PARAM *)comm_param)->lower_number; test_param.mon_vol = ((COMM_TEST_PARAM *)comm_param)->mon_vol; if(PageType == FBO48CT || TYPE_FBI_10480 || TYPE_FBI_4548 || TYPE_FBI_20240) test_param.onlinevol_lowlimit = ((COMM_TEST_PARAM *)comm_param)->Reserved[0]; else test_param.onlinevol_lowlimit = onlinevollow; test_param.booster_ceiling = ((COMM_TEST_PARAM *)comm_param)->Reserved[1]; test_param.charge_limit = ((COMM_TEST_PARAM *)comm_param)->chrg_curr; test_param.temp_High = ((COMM_TEST_PARAM *)comm_param)->chrg_temp; test_param.discharge_mode = ((COMM_TEST_PARAM *)comm_param)->dischg_mode; test_param.preset_power = ((COMM_TEST_PARAM *)comm_param)->pre_power; if(test_param.group_number*test_param.mon_number > 300) test_param.mon_number = 300/test_param.group_number; if(test_param.group_number>4) test_param.group_number = 4; if(test_param.group_number*test_param.mon_number > 300) test_param.mon_number = 300/test_param.group_number; if(test_param.lower_number<=0) test_param.lower_number = 1; if(test_param.preset_time<=0) test_param.preset_time = 1; if(!(test_param.mon_vol == 20 || test_param.mon_vol == 40 || test_param.mon_vol == 60 || test_param.mon_vol == 120 || test_param.mon_vol == 12)) { test_param.mon_vol = work_page->test_param_xml.mon_vol; } } void SlavePC::getTestCommParam(TEST_PARAM_XML &test_param, void *comm_param) { memset(comm_param,0x00,sizeof(COMM_TEST_PARAM)); ((COMM_TEST_PARAM *)comm_param)->test_mode = test_param.test_mode; ((COMM_TEST_PARAM *)comm_param)->acstop_op = test_param.acstop_op; ((COMM_TEST_PARAM *)comm_param)->nominal_cap = test_param.nominal_cap; ((COMM_TEST_PARAM *)comm_param)->hourly_rate = test_param.hourly_rate; ((COMM_TEST_PARAM *)comm_param)->preset_cur = test_param.preset_cur; ((COMM_TEST_PARAM *)comm_param)->preset_cap = test_param.preset_cap; ((COMM_TEST_PARAM *)comm_param)->preset_time = test_param.preset_time; ((COMM_TEST_PARAM *)comm_param)->mon_lower = test_param.mon_lower; ((COMM_TEST_PARAM *)comm_param)->group_lower = test_param.group_lower; ((COMM_TEST_PARAM *)comm_param)->mon_number = test_param.mon_number; ((COMM_TEST_PARAM *)comm_param)->group_number = test_param.group_number; ((COMM_TEST_PARAM *)comm_param)->lower_number = test_param.lower_number; ((COMM_TEST_PARAM *)comm_param)->mon_vol = test_param.mon_vol; ((COMM_TEST_PARAM *)comm_param)->Reserved[0] = test_param.onlinevol_lowlimit;//在线阈值 ((COMM_TEST_PARAM *)comm_param)->Reserved[1] = test_param.booster_ceiling;//升压上限 ((COMM_TEST_PARAM *)comm_param)->chrg_curr = test_param.charge_limit; ((COMM_TEST_PARAM *)comm_param)->chrg_temp = test_param.temp_High; ((COMM_TEST_PARAM *)comm_param)->dischg_mode = test_param.discharge_mode; ((COMM_TEST_PARAM *)comm_param)->pre_power = test_param.preset_power; } void SlavePC::run() { RUN_EN = true; if(FD < 0) RUN_EN = false; FRAME_DATA frame_sent; FRAME_DATA frame_recv; while(RUN_EN) { memset(&frame_recv,0,sizeof(frame_recv)); memset(&frame_sent,0,sizeof(frame_sent)); SlaveMode(frame_recv,frame_sent); msleep(50); } } //***********************************************************************************