#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;
|
}
|
|
*/
|
|