#include "pch.h" #include "KMachine.h" KMachine::KMachine() { StartTime = GetTimemS(); } KMachine::~KMachine() { } double KMachine::GetTimemS() { LARGE_INTEGER perfreq; LARGE_INTEGER percounter1; QueryPerformanceFrequency(&perfreq); QueryPerformanceCounter(&percounter1); double time1 = (double)percounter1.QuadPart / perfreq.QuadPart; return (time1 * 1000); }; int KMachine::GetTick100uS() { int thistime = int((GetTimemS() - StartTime) * 10); return thistime; } int KMachine::Init() { return 0; } int KMachine::Download(stBinProg1 * pBinrog, int nBinSteps) { for (int i = 0; i < nBinSteps; i++) { BinProgs[i] = pBinrog[i]; } nBinProgSteps = nBinSteps; return 0; } int KMachine::ProcPLC() { ProcessPLCBinProg(BinProgs, nBinProgSteps); return 0; } int KMachine::StartPLC() { for (int i = 0; i < KLDataWXCount; i++) { KMem.WX[i] = 0; } for (int i = 0; i < KLDataWYCount; i++) { KMem.WY[i] = 0; } for (int i = 0; i < KLDataWRCount; i++) { KMem.WR[i] = 0; } for (int i = 0; i < KLDataDTCount; i++) { KMem.DT[i] = 0; } for (int i = 0; i < TOTALTIMERS; i++) { KMem.Timers[i] = { 0 }; } nScanCount = 0; m_bPlcRunning = 1; return 0; } int KMachine::StopPLC() { m_bPlcRunning = 0; return 0; } const unsigned short bitMasks[16] = { 0x1 << 0, 0x1 << 1, 0x1 << 2, 0x1 << 3, 0x1 << 4, 0x1 << 5, 0x1 << 6, 0x1 << 7, 0x1 << 8, 0x1 << 9, 0x1 << 10, 0x1 << 11, 0x1 << 12, 0x1 << 13, 0x1 << 14, 0x1 << 15, }; inline void SetAddrBit(unsigned short * pW, unsigned char bitAddr) { (*pW) |= bitMasks[bitAddr & 0xf]; } inline void ResetBit(unsigned short * pW, unsigned char bitAddr) { (*pW) &= ~bitMasks[bitAddr & 0xf]; } static inline void SetBitValue(unsigned short * pW, unsigned char bitAddr, unsigned char Value) { if (Value) { SetAddrBit(pW, bitAddr); } else { ResetBit(pW, bitAddr); } } static inline unsigned char GetBitValue(unsigned short W, unsigned char bitAddr) { if (W&bitMasks[bitAddr & 0xf]) return 1; else return 0; } int KMachine::GetCoilValue(int nCoilType, int nCoilAddr) { // TODO: ÔÚ´Ë´¦Ìí¼ÓʵÏÖ´úÂë. int nWordAddr = nCoilAddr >> 4; int nBitAddr = nCoilAddr & 0x0F; switch (nCoilType) { case KLCoilTypeX: if (nCoilAddr >= KLCoilXCount) return 0; return GetBitValue(KMem.WX[nWordAddr], nBitAddr); break; case KLCoilTypeY: if (nCoilAddr >= KLCoilYCount) return 0; return GetBitValue(KMem.WY[nWordAddr], nBitAddr); break; case KLCoilTypeR: if (nCoilAddr >= KLCoilRCount) return 0; return GetBitValue(KMem.WR[nWordAddr], nBitAddr); break; case KLCoilTypeLX: if (nCoilAddr >= KLCoilLXCount) return 0; return GetBitValue(KMem.WLX[nWordAddr], nBitAddr); break; case KLCoilTypeLY: if (nCoilAddr >= KLCoilLYCount) return 0; return GetBitValue(KMem.WLY[nWordAddr], nBitAddr); break; case KLCoilTypeT: if (nCoilAddr >= KLCoilTCount) return 0; return GetBitValue(KMem.WT[nWordAddr], nBitAddr); break; case KLCoilTypeC: if (nCoilAddr >= KLCoilCCount) return 0; return GetBitValue(KMem.WC[nWordAddr], nBitAddr); break; case KLCoilTypeLR: if (nCoilAddr >= KLCoilLRCount) return 0; return GetBitValue(KMem.WLR[nWordAddr], nBitAddr); break; case KLCoilTypeSR: if (nCoilAddr >= KLCoilSRCount) return 0; return GetBitValue(KMem.WSR[nWordAddr], nBitAddr); break; } return 0; } int KMachine::SetCoilValue(int nCoilType, int nCoilAddr, int nCoilValue) { // TODO: ÔÚ´Ë´¦Ìí¼ÓʵÏÖ´úÂë. int nWordAddr = nCoilAddr >> 4; int nBitAddr = nCoilAddr & 0x0F; switch (nCoilType) { case KLCoilTypeX: if (nCoilAddr >= KLCoilXCount) return 0; SetBitValue(&KMem.WX[nWordAddr], nBitAddr, nCoilValue); break; case KLCoilTypeY: if (nCoilAddr >= KLCoilYCount) return 0; SetBitValue(&KMem.WY[nWordAddr], nBitAddr, nCoilValue); break; case KLCoilTypeR: if (nCoilAddr >= KLCoilRCount) return 0; SetBitValue(&KMem.WR[nWordAddr], nBitAddr, nCoilValue); break; case KLCoilTypeLX: if (nCoilAddr >= KLCoilLXCount) return 0; SetBitValue(&KMem.WLX[nWordAddr], nBitAddr, nCoilValue); break; case KLCoilTypeLY: if (nCoilAddr >= KLCoilLYCount) return 0; SetBitValue(&KMem.WLY[nWordAddr], nBitAddr, nCoilValue); break; case KLCoilTypeT: if (nCoilAddr >= KLCoilTCount) return 0; SetBitValue(&KMem.WT[nWordAddr], nBitAddr, nCoilValue); break; case KLCoilTypeC: if (nCoilAddr >= KLCoilCCount) return 0; SetBitValue(&KMem.WC[nWordAddr], nBitAddr, nCoilValue); break; case KLCoilTypeLR: if (nCoilAddr >= KLCoilLRCount) return 0; SetBitValue(&KMem.WLR[nWordAddr], nBitAddr, nCoilValue); break; case KLCoilTypeSR: if (nCoilAddr >= KLCoilSRCount) return 0; SetBitValue(&KMem.WSR[nWordAddr], nBitAddr, nCoilValue); break; } return 0; } int KMachine::GetVarData(int nDataType, int nDataAddr) { // TODO: ÔÚ´Ë´¦Ìí¼ÓʵÏÖ´úÂë. switch (nDataType) { case KLDataTypeDEC: case KLDataTypeHEX: return nDataAddr; break; case KLDataTypeWX: if (nDataAddr >= KLDataWXCount) return 0; return KMem.WX[nDataAddr]; break; case KLDataTypeWY: if (nDataAddr >= KLDataWYCount) return 0; return KMem.WY[nDataAddr]; break; case KLDataTypeWR: if (nDataAddr >= KLDataWRCount) return 0; return KMem.WR[nDataAddr]; break; case KLDataTypeWLX: if (nDataAddr >= KLDataWLCount) return 0; return KMem.WLX[nDataAddr]; break; case KLDataTypeWLY: if (nDataAddr >= KLDataWLCount) return 0; return KMem.WLY[nDataAddr]; break; case KLDataTypeDT: if (nDataAddr >= KLDataDTCount) return 0; return (signed short)KMem.DT[nDataAddr]; break; case KLDataTypeSDT: if (nDataAddr >= KLDataSDTCount) return 0; return KMem.SDT[nDataAddr]; break; case KLDataTypeWSR: if (nDataAddr >= KLCoilLRCount) return 0; return KMem.WSR[nDataAddr]; break; case KLDataTypeSV: if (nDataAddr >= KLDataSVCount) return 0; return KMem.SV[nDataAddr]; break; case KLDataTypeEV: if (nDataAddr >= KLDataEVCount) return 0; return KMem.EV[nDataAddr]; break; case KLDataTypeLD: if (nDataAddr >= KLDataLDCount) return 0; return KMem.DT[nDataAddr]; break; case KLDataSysCfg: if (nDataAddr >= KLCoilSRCount) return 0; return KMem.SDT[nDataAddr]; break; case KLDataTypeFlash: if (nDataAddr >= KLCoilSRCount) return 0; return KMem.SDT[nDataAddr]; break; case KLDataTypeTest: if (nDataAddr >= KLCoilSRCount) return 0; return KMem.SDT[nDataAddr]; break; } return 0; } int KMachine::SetVarData(int nDataType, int nDataAddr, int nDataValue) { // TODO: ÔÚ´Ë´¦Ìí¼ÓʵÏÖ´úÂë. switch (nDataType) { // case KLDataTypeDEC: // case KLDataTypeHEX: // break; case KLDataTypeWX: if (nDataAddr >= KLDataWXCount) return 0; KMem.WX[nDataAddr] = nDataValue; break; case KLDataTypeWY: if (nDataAddr >= KLDataWYCount) return 0; KMem.WY[nDataAddr] = nDataValue; break; case KLDataTypeWR: if (nDataAddr >= KLDataWRCount) return 0; KMem.WR[nDataAddr] = nDataValue; break; case KLDataTypeWLX: if (nDataAddr >= KLDataWLCount) return 0; KMem.WLX[nDataAddr] = nDataValue; break; case KLDataTypeWLY: if (nDataAddr >= KLDataWLCount) return 0; KMem.WLY[nDataAddr] = nDataValue; break; case KLDataTypeDT: if (nDataAddr >= KLDataDTCount) return 0; KMem.DT[nDataAddr] = nDataValue; break; case KLDataTypeSDT: if (nDataAddr >= KLDataSDTCount) return 0; KMem.SDT[nDataAddr] = nDataValue; break; case KLDataTypeWSR: if (nDataAddr >= KLCoilLRCount) return 0; KMem.WSR[nDataAddr] = nDataValue; break; case KLDataTypeSV: if (nDataAddr >= KLDataSVCount) return 0; KMem.SV[nDataAddr] = nDataValue; break; case KLDataTypeEV: if (nDataAddr >= KLDataEVCount) return 0; KMem.EV[nDataAddr] = nDataValue; break; case KLDataTypeLD: if (nDataAddr >= KLDataLDCount) return 0; KMem.DT[nDataAddr] = nDataValue; break; case KLDataSysCfg: if (nDataAddr >= KLCoilSRCount) return 0; KMem.SDT[nDataAddr] = nDataValue; break; case KLDataTypeFlash: if (nDataAddr >= KLCoilSRCount) return 0; KMem.SDT[nDataAddr] = nDataValue; break; case KLDataTypeTest: if (nDataAddr >= KLCoilSRCount) return 0; KMem.SDT[nDataAddr] = nDataValue; break; } return 0; } int KMachine::InitTimer(int nIndex, int nType) { if (nIndex >= TOTALTIMERS) return -1; KMem.Timers[nIndex].StatByte = 0x0010 | nType; // Timers[nIndex].nType = 0; KMem.SV[nIndex] = 0; KMem.EV[nIndex] = 0; KMem.Timers[nIndex].LastActTime = GetTick100uS(); return 0; } int KMachine::RunTimer(int nIndex, int SV) { if (nIndex >= TOTALTIMERS) return -1; if (!KMem.Timers[nIndex].bSet) { KMem.SV[nIndex] = SV; KMem.EV[nIndex] = 0; KMem.Timers[nIndex].LastActTime = GetTick100uS(); KMem.Timers[nIndex].bSet = 1; } return 0; } int KMachine::StopTimer(int nIndex) { if (nIndex >= TOTALTIMERS) return -1; if (KMem.Timers[nIndex].bSet) { KMem.EV[nIndex] = 0; KMem.Timers[nIndex].LastActTime = GetTick100uS(); KMem.Timers[nIndex].bSet = 0; } return 0; } int KMachine::ResetTimer(int nIndex) { if (nIndex >= TOTALTIMERS) return -1; KMem.EV[nIndex] = 0; KMem.Timers[nIndex].bTon = 0; KMem.Timers[nIndex].LastActTime = GetTick100uS(); return 0; } int KMachine::SetTimerValue(int nIndex, int bSet, int SV) { if (nIndex >= TOTALTIMERS) return -1; if (bSet) { RunTimer(nIndex, SV); } else { StopTimer(nIndex); } return KMem.Timers[nIndex].bTon; } int KMachine::ProcessTimer(int nIndex) { if (nIndex >= TOTALTIMERS) return -1; if (!KMem.Timers[nIndex].nInited) return 0; if (KMem.Timers[nIndex].bSet) // bSet =1; { if (!KMem.Timers[nIndex].bTon) { int TimeDiff = GetTick100uS() - KMem.Timers[nIndex].LastActTime; int nScale = TICK_OF_MS; if (KMem.Timers[nIndex].nScale == 0) { nScale = TICK_OF_MS; } else if (KMem.Timers[nIndex].nScale == 1) { nScale = TICK_OF_RS; } else if (KMem.Timers[nIndex].nScale == 2) { nScale = TICK_OF_XS; } else if (KMem.Timers[nIndex].nScale == 3) { nScale = TICK_OF_YS; } else {} //if (TimeDiff >= nScale) { int TimeDiffmS = TimeDiff / nScale; unsigned short NextEV = KMem.EV[nIndex] + TimeDiffmS; KMem.Timers[nIndex].LastActTime += TimeDiffmS * nScale; if (NextEV >= KMem.SV[nIndex]) { NextEV = KMem.SV[nIndex]; KMem.Timers[nIndex].bTon = 1; } KMem.EV[nIndex] = NextEV; } } } else //bSet=0; { if (KMem.Timers[nIndex].bTon) { KMem.Timers[nIndex].bTon = 0; } KMem.EV[nIndex] = 0; } SetCoilValue(KLCoilTypeT, nIndex, KMem.Timers[nIndex].bTon); return KMem.Timers[nIndex].bTon; } int KMachine::IsTimerOn(int nIndex) { if (nIndex >= TOTALTIMERS) return 0; ProcessTimer(nIndex); return KMem.Timers[nIndex].bTon; } int KMachine::GetTimerSV(int nIndex) { if (nIndex >= TOTALTIMERS) return 0; // ProcessTimer(nIndex); return KMem.SV[nIndex]; // return 0; } int KMachine::GetTimerEV(int nIndex) { if (nIndex >= TOTALTIMERS) return 0; // ProcessTimer(nIndex); return KMem.EV[nIndex]; // return 0; } int KMachine::PushInVal(void) { for (int i = TOTAL_CurVAL - 1; i > 0; i--) { KMem.CurVALs[i] = KMem.CurVALs[i - 1]; } KMem.CurVALs[0] = KMem.CurVAL ? '1' : '0'; return KMem.CurVAL; } int KMachine::PopOutVal(void) { unsigned char theVAL = (KMem.CurVALs[0] == '1'); for (int i = 0; i < TOTAL_CurVAL - 1; i++) { KMem.CurVALs[i] = KMem.CurVALs[i + 1]; } return theVAL; } int KMachine::ProcessPLCBinProg(const stBinProg1 * pBinprog, int nProgSteps) { if (nScanCount == 0) { SetCoilValue(KLCoilTypeSR, 13, 1); SetCoilValue(KLCoilTypeSR, 0, 0); SetCoilValue(KLCoilTypeSR, 1, 1); } else { SetCoilValue(KLCoilTypeSR, 13, 0); SetCoilValue(KLCoilTypeSR, 0, 0); SetCoilValue(KLCoilTypeSR, 1, 1); } for (int i = 0; i < TOTAL_CurVAL; i++) { KMem.CurVALs[i] = '0'; } int CurPos = 0; // stBinProg1 * pBinProg1; stBinProg15 * pBinProg15; stBinProg2 * pBinProg2; stBinProg3 * pBinProg3; // unsigned int AddrType2 ; // unsigned short Addr2 ; // unsigned int AddrType3 ; // unsigned short Addr3 ; // pBinProg15 = (stBinProg15 *)&pBinprog[CurPos]; // pBinProg2 = (stBinProg2 *)&pBinprog[CurPos]; // pBinProg3 = (stBinProg3 *)&pBinprog[CurPos]; int lastScanInputVal = 1;//ÉϸöɨÃèÖÜÆÚ£¬µ±Ç°Ö¸ÁîÊäÈë״̬£¬Îª ΢·Ö ×ö²Î¿¼ while (CurPos < nProgSteps) { unsigned int nNextPos = 1; unsigned int thisOP = pBinprog[CurPos].nOp; // unsigned int nParamCount = 0 unsigned char thisAddrType = pBinprog[CurPos].nParamType; unsigned short thisAddr = pBinprog[CurPos].nParamAddr; switch (thisOP) { case OP_NONE: break; // case OP_NOP: break; //ÎÞ²ÎÊý Ö¸Áî case OP_END: nNextPos = nProgSteps; break; case OP_NOT: case OP_ANS: case OP_ORS: case OP_PSHS: case OP_RDS: case OP_POPS: case OP_DF: case OP_DF_: switch (thisOP) { case OP_NOT: KMem.CurVAL = !KMem.CurVAL; break; case OP_ANS: KMem.CurVAL = PopOutVal() && KMem.CurVAL; break; case OP_ORS: KMem.CurVAL = PopOutVal() || KMem.CurVAL; break; case OP_PSHS: PushInVal(); break; case OP_RDS: KMem.CurVAL = KMem.CurVALs[0] == '1'; break; case OP_POPS: KMem.CurVAL = PopOutVal(); break; case OP_DF: KMem.CurVAL = KMem.CurVAL && !lastScanInputVal; break; case OP_DF_: KMem.CurVAL = !KMem.CurVAL && lastScanInputVal; break; default: break; } break; // 1²ÎÊýÖ¸Áî case OP_ST: case OP_ST_: case OP_AN: case OP_AN_: case OP_OR: case OP_OR_: switch (thisOP) { case OP_ST: PushInVal(); KMem.CurVAL = GetCoilValue(thisAddrType, thisAddr); break; case OP_ST_: PushInVal(); KMem.CurVAL = !GetCoilValue(thisAddrType, thisAddr); break; case OP_AN: KMem.CurVAL = KMem.CurVAL&&GetCoilValue(thisAddrType, thisAddr); break; case OP_AN_: KMem.CurVAL = KMem.CurVAL && (!GetCoilValue(thisAddrType, thisAddr)); break; case OP_OR: KMem.CurVAL = KMem.CurVAL || GetCoilValue(thisAddrType, thisAddr); break; case OP_OR_: KMem.CurVAL = KMem.CurVAL || (!GetCoilValue(thisAddrType, thisAddr)); break; default: break; } break; // 1 ²ÎÊý Êä³ö case OP_OUT: case OP_SET: case OP_RESET: switch (thisOP) { case OP_OUT: SetCoilValue(thisAddrType, thisAddr, KMem.CurVAL); break; case OP_SET: if (KMem.CurVAL) SetCoilValue(thisAddrType, thisAddr, 1); break; case OP_RESET: if (KMem.CurVAL) SetCoilValue(thisAddrType, thisAddr, 0); break; default: break; } break; // ±È½ÏÖ¸Áî case OP_ST_EQ: case OP_ST_NE: case OP_ST_LT: case OP_ST_GT: case OP_ST_LE: case OP_ST_GE: case OP_AN_EQ: case OP_AN_NE: case OP_AN_LT: case OP_AN_GT: case OP_AN_LE: case OP_AN_GE: case OP_OR_EQ: case OP_OR_NE: case OP_OR_LT: case OP_OR_GT: case OP_OR_LE: case OP_OR_GE: pBinProg2 = (stBinProg2 *)&pBinprog[CurPos]; thisAddrType = pBinProg2->nParamType1; switch (thisOP) { case OP_ST_EQ: PushInVal(); KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) == GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2)); break; case OP_ST_NE: PushInVal(); KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) != GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2)); break; case OP_ST_LT: PushInVal(); KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) < GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2)); break; case OP_ST_GT: PushInVal(); KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) > GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2)); break; case OP_ST_LE: PushInVal(); KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) <= GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2)); break; case OP_ST_GE: PushInVal(); KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) >= GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2)); break; case OP_AN_EQ: KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) == GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2)); break; case OP_AN_NE: KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) != GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2)); break; case OP_AN_LT: KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) < GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2)); break; case OP_AN_GT: KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) > GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2)); break; case OP_AN_LE: KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) <= GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2)); break; case OP_AN_GE: KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) >= GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2)); break; case OP_OR_EQ: KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) == GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2)); break; case OP_OR_NE: KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) != GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2)); break; case OP_OR_LT: KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) < GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2)); break; case OP_OR_GT: KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) > GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2)); break; case OP_OR_LE: KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) <= GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2)); break; case OP_OR_GE: KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) >= GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2)); break; default: break; } nNextPos = 2; break; // ¶¨Ê±Æ÷ case OP_TML: case OP_TMR: case OP_TMX: case OP_TMY: pBinProg15 = (stBinProg15 *)(&pBinprog[CurPos]); { unsigned char thisNum = pBinProg15->nOpNum; thisAddrType = pBinProg15->nParamType1; thisAddr = pBinProg15->nParamAddr1; switch (thisOP) { case OP_TML: if (!KMem.Timers[thisNum].nInited) InitTimer(thisNum, 0); if (KMem.CurVAL) RunTimer(thisNum, GetVarData(thisAddrType, thisAddr)); else StopTimer(thisNum); KMem.CurVAL = ProcessTimer(thisNum); break; case OP_TMR: if (!KMem.Timers[thisNum].nInited) InitTimer(thisNum, 1); if (KMem.CurVAL) RunTimer(thisNum, GetVarData(thisAddrType, thisAddr)); else StopTimer(thisNum); KMem.CurVAL = ProcessTimer(thisNum); break; case OP_TMX: if (!KMem.Timers[thisNum].nInited) InitTimer(thisNum, 2); if (KMem.CurVAL) RunTimer(thisNum, GetVarData(thisAddrType, thisAddr)); else StopTimer(thisNum); KMem.CurVAL = ProcessTimer(thisNum); break; case OP_TMY: if (!KMem.Timers[thisNum].nInited) InitTimer(thisNum, 3); if (KMem.CurVAL) RunTimer(thisNum, GetVarData(thisAddrType, thisAddr)); else StopTimer(thisNum); KMem.CurVAL = ProcessTimer(thisNum); break; default: break; } } nNextPos = 2; break; // 1 ²ÎÊý¸ß¼¶Ö¸Áî case OP_INC: case OP_DEC: pBinProg15 = (stBinProg15 *)(&pBinprog[CurPos]); thisAddrType = pBinProg15->nParamType1; thisAddr = pBinProg15->nParamAddr1; nNextPos = 2; switch (thisOP) { case OP_INC: if (KMem.CurVAL) SetVarData(thisAddrType, thisAddr, GetVarData(thisAddrType, thisAddr) + 1); break; case OP_DEC: if (KMem.CurVAL) SetVarData(thisAddrType, thisAddr, GetVarData(thisAddrType, thisAddr) - 1); break; default: break; } break; // 2²ÎÊý¸ß¼¶Ö¸Áî case OP_MV: case OP_ADD2: case OP_SUB2: pBinProg2 = (stBinProg2 *)(&pBinprog[CurPos]); { int nParamType2, nParamAddr2; thisAddrType = pBinProg2->nParamType1; thisAddr = pBinProg2->nParamAddr1; nParamType2 = pBinProg2->nParamType2; nParamAddr2 = pBinProg2->nParamAddr2; switch (thisOP) { case OP_MV: if (KMem.CurVAL) SetVarData(nParamType2, nParamAddr2, GetVarData(thisAddrType, thisAddr)); break; case OP_ADD2: if (KMem.CurVAL) SetVarData(nParamType2, nParamAddr2, GetVarData(thisAddrType, thisAddr) + GetVarData(nParamType2, nParamAddr2)); break; case OP_SUB2: if (KMem.CurVAL) SetVarData(nParamType2, nParamAddr2, GetVarData(nParamType2, nParamAddr2) - GetVarData(thisAddrType, thisAddr)); break; default: break; } } nNextPos = 2; break; // 3 ²ÎÊý¸ß¼¶Ö¸Áî case OP_ADD3: case OP_SUB3: case OP_MUL: case OP_DIV: pBinProg3 = (stBinProg3 *)(&pBinprog[CurPos]); int nParamType2, nParamAddr2; int nParamType3, nParamAddr3; thisAddrType = pBinProg3->nParamType1; thisAddr = pBinProg3->nParamAddr1; nParamType2 = pBinProg3->nParamType2; nParamAddr2 = pBinProg3->nParamAddr2; nParamType3 = pBinProg3->nParamType3; nParamAddr3 = pBinProg3->nParamAddr3; switch (thisOP) { case OP_ADD3: if (KMem.CurVAL) SetVarData(nParamType3, nParamAddr3, GetVarData(thisAddrType, thisAddr) + GetVarData(nParamType2, nParamAddr2)); break; case OP_SUB3: if (KMem.CurVAL) SetVarData(nParamType3, nParamAddr3, GetVarData(thisAddrType, thisAddr) - GetVarData(nParamType2, nParamAddr2)); break; case OP_MUL: if (KMem.CurVAL) { short multiplicand = GetVarData(thisAddrType, thisAddr); short multiplier = GetVarData(nParamType2, nParamAddr2); int product = multiplicand * multiplier; SetVarData(nParamType3, nParamAddr3, product); SetVarData(nParamType3, nParamAddr3 + 1, product >> 16); } break; case OP_DIV: if (KMem.CurVAL) { short dividend = GetVarData(thisAddrType, thisAddr); short divisor = GetVarData(nParamType2, nParamAddr2); short quotient = dividend / divisor; short remainder = dividend % divisor; SetVarData(nParamType3, nParamAddr3, quotient); SetVarData(nParamType3, nParamAddr3 + 1, remainder); } break; default: break; } nNextPos = 3; break; default: break; } lastScanInputVal = ProgTrace[CurPos]; ProgTrace[CurPos] = KMem.CurVAL; CurPos += nNextPos; } nScanCount++; return 0; } /* int KMachine::ProcessPLCProg(const stProg * prog, int nSize) { if (nScanCount == 0) { SetCoilValue(KLCoilTypeSR, 13, 1); SetCoilValue(KLCoilTypeSR, 0, 0); SetCoilValue(KLCoilTypeSR, 1, 1); } else { SetCoilValue(KLCoilTypeSR, 13, 0); SetCoilValue(KLCoilTypeSR, 0, 0); SetCoilValue(KLCoilTypeSR, 1, 1); } for (int i = 0; i < TOTAL_CurVAL; i++) { KMem.CurVALs[i] = '0'; } int lastScanInputVal = 1;//ÉϸöɨÃèÖÜÆÚ£¬µ±Ç°Ö¸ÁîÊäÈë״̬£¬Îª ΢·Ö ×ö²Î¿¼ for (int i = 0; i < nSize; i++) { unsigned int thisOP = prog[i].nOpType1; unsigned int nParamCount = prog[i].nParamCount; unsigned int thisAddrType = prog[i].Params[0].nParamType; unsigned short thisAddr = prog[i].Params[0].nParamAddr; unsigned int AddrType2 = prog[i].Params[1].nParamType; unsigned short Addr2 = prog[i].Params[1].nParamAddr; unsigned int AddrType3 = prog[i].Params[2].nParamType; unsigned short Addr3 = prog[i].Params[2].nParamAddr; switch (thisOP) { case OP_NOP: break; case OP_ST: PushInVal(); KMem.CurVAL = GetCoilValue(thisAddrType, thisAddr); break; case OP_ST_: PushInVal(); KMem.CurVAL = !GetCoilValue(thisAddrType, thisAddr); break; case OP_AN: KMem.CurVAL = KMem.CurVAL&&GetCoilValue(thisAddrType, thisAddr); break; case OP_AN_: KMem.CurVAL = KMem.CurVAL && (!GetCoilValue(thisAddrType, thisAddr)); break; case OP_OR: KMem.CurVAL = KMem.CurVAL || GetCoilValue(thisAddrType, thisAddr); break; case OP_OR_: KMem.CurVAL = KMem.CurVAL || (!GetCoilValue(thisAddrType, thisAddr)); break; case OP_NOT: KMem.CurVAL = !KMem.CurVAL; break; case OP_ANS: KMem.CurVAL = PopOutVal() && KMem.CurVAL; break; case OP_ORS: KMem.CurVAL = PopOutVal() || KMem.CurVAL; break; case OP_PSHS: PushInVal(); break; case OP_RDS: KMem.CurVAL = KMem.CurVALs[0] == '1'; break; case OP_POPS: KMem.CurVAL = PopOutVal(); break; case OP_OUT: SetCoilValue(thisAddrType, thisAddr, KMem.CurVAL); break; case OP_SET: if (KMem.CurVAL) SetCoilValue(thisAddrType, thisAddr, 1); break; case OP_RESET: if (KMem.CurVAL) SetCoilValue(thisAddrType, thisAddr, 0); break; case OP_DF: KMem.CurVAL = KMem.CurVAL && !lastScanInputVal; break; case OP_DF_: KMem.CurVAL = !KMem.CurVAL && lastScanInputVal; break; case OP_ST_EQ: PushInVal(); KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) == GetVarData(AddrType2, Addr2)); break; case OP_ST_NE: PushInVal(); KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) != GetVarData(AddrType2, Addr2)); break; case OP_ST_LT: PushInVal(); KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) < GetVarData(AddrType2, Addr2)); break; case OP_ST_GT: PushInVal(); KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) > GetVarData(AddrType2, Addr2)); break; case OP_ST_LE: PushInVal(); KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) <= GetVarData(AddrType2, Addr2)); break; case OP_ST_GE: PushInVal(); KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) >= GetVarData(AddrType2, Addr2)); break; case OP_AN_EQ: KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) == GetVarData(AddrType2, Addr2)); break; case OP_AN_NE: KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) != GetVarData(AddrType2, Addr2)); break; case OP_AN_LT: KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) < GetVarData(AddrType2, Addr2)); break; case OP_AN_GT: KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) > GetVarData(AddrType2, Addr2)); break; case OP_AN_LE: KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) <= GetVarData(AddrType2, Addr2)); break; case OP_AN_GE: KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) >= GetVarData(AddrType2, Addr2)); break; case OP_OR_EQ: KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) == GetVarData(AddrType2, Addr2)); break; case OP_OR_NE: KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) != GetVarData(AddrType2, Addr2)); break; case OP_OR_LT: KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) < GetVarData(AddrType2, Addr2)); break; case OP_OR_GT: KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) > GetVarData(AddrType2, Addr2)); break; case OP_OR_LE: KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) <= GetVarData(AddrType2, Addr2)); break; case OP_OR_GE: KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) >= GetVarData(AddrType2, Addr2)); break; case OP_TML: if (!KMem.Timers[thisAddr].nInited) InitTimer(thisAddr, 0); if (KMem.CurVAL) RunTimer(thisAddr, GetVarData(AddrType2, Addr2)); else StopTimer(thisAddr); KMem.CurVAL = ProcessTimer(thisAddr); break; case OP_TMR: if (!KMem.Timers[thisAddr].nInited) InitTimer(thisAddr, 1); if (KMem.CurVAL) RunTimer(thisAddr, GetVarData(AddrType2, Addr2)); else StopTimer(thisAddr); KMem.CurVAL = ProcessTimer(thisAddr); break; case OP_TMX: if (!KMem.Timers[thisAddr].nInited) InitTimer(thisAddr, 2); if (KMem.CurVAL) RunTimer(thisAddr, GetVarData(AddrType2, Addr2)); else StopTimer(thisAddr); KMem.CurVAL = ProcessTimer(thisAddr); break; case OP_TMY: if (!KMem.Timers[thisAddr].nInited) InitTimer(thisAddr, 3); if (KMem.CurVAL) RunTimer(thisAddr, GetVarData(AddrType2, Addr2)); else StopTimer(thisAddr); KMem.CurVAL = ProcessTimer(thisAddr); break; case OP_MV: if (KMem.CurVAL) SetVarData(AddrType2, Addr2, GetVarData(thisAddrType, thisAddr)); break; case OP_INC: if (KMem.CurVAL) SetVarData(thisAddrType, thisAddr, GetVarData(thisAddrType, thisAddr) + 1); break; case OP_DEC: if (KMem.CurVAL) SetVarData(thisAddrType, thisAddr, GetVarData(thisAddrType, thisAddr) - 1); break; case OP_ADD2: if (KMem.CurVAL) SetVarData(AddrType2, Addr2, GetVarData(thisAddrType, thisAddr) + GetVarData(AddrType2, Addr2)); break; case OP_SUB2: if (KMem.CurVAL) SetVarData(AddrType2, Addr2, GetVarData(AddrType2, Addr2) - GetVarData(thisAddrType, thisAddr)); break; case OP_ADD3: if (KMem.CurVAL) SetVarData(AddrType3, Addr3, GetVarData(thisAddrType, thisAddr) + GetVarData(AddrType2, Addr2)); break; case OP_SUB3: if (KMem.CurVAL) SetVarData(AddrType3, Addr3, GetVarData(thisAddrType, thisAddr) - GetVarData(AddrType2, Addr2)); break; case OP_MUL: if (KMem.CurVAL) SetVarData(AddrType3, Addr3, GetVarData(thisAddrType, thisAddr) * GetVarData(AddrType2, Addr2)); break; case OP_DIV: if (KMem.CurVAL) SetVarData(AddrType3, Addr3, GetVarData(thisAddrType, thisAddr) / GetVarData(AddrType2, Addr2)); break; // OP_BKMV = 60, // OP_COPY = 61, // OP_CLR = 62, default: break; } lastScanInputVal = ProgTrace[i]; ProgTrace[i] = KMem.CurVAL; } nScanCount++; return 0; } */