/** ****************************************************************************** * @file : PLCfunctions.c * @brief : PLC funcstions program body ****************************************************************************** */ //#include "globaldef.h" #include "PLCfunctions.h" #include "string.h" #include "stm32f0xx_hal.h" #include #if (ENABLE_PLC) extern __IO uint32_t uwTick; //unsigned short WDFs[TOTAL_WDFS]; inline unsigned int GetTick(void) { // unsigned short Clk1=SysTick->VAL; return uwTick; } //unsigned char CurVAL; //unsigned char CurVALs[TOTAL_CurVAL]; //stTimer Timers[TOTALTIMERS]; //unsigned short WX[13]; //unsigned short WY[13]; //unsigned short WR[64]; //unsigned short DT[256]; //unsigned short SDT[256]; stPLCMem PLCMem; int InitTimer(int nIndex, int nType) { if (nIndex >= TOTALTIMERS) return -1; PLCMem.Timers[nIndex].StatByte = 0x0010 | nType; // Timers[nIndex].nType = 0; PLCMem.SV[nIndex] = 0; PLCMem.EV[nIndex] = 0; PLCMem.Timers[nIndex].LastActTime = GetTick(); return 0; } int RunTimer(int nIndex , int SV) { if (nIndex >= TOTALTIMERS) return -1; if (!PLCMem.Timers[nIndex].bSet) { PLCMem.SV[nIndex] = SV; PLCMem.EV[nIndex]= 0; PLCMem.Timers[nIndex].LastActTime = GetTick(); PLCMem.Timers[nIndex].bSet = 1; } return 0; } int StopTimer(int nIndex) { if (nIndex >= TOTALTIMERS) return -1; if (PLCMem.Timers[nIndex].bSet) { PLCMem.EV[nIndex] = 0; PLCMem.Timers[nIndex].LastActTime = GetTick(); PLCMem.Timers[nIndex].bSet = 0; } return 0; } int ResetTimer(int nIndex) { if (nIndex >= TOTALTIMERS) return -1; PLCMem.EV[nIndex] = 0; PLCMem.Timers[nIndex].bTon = 0; PLCMem.Timers[nIndex].LastActTime=GetTick(); return 0; } int SetTimerValue(int nIndex, int bSet, int SV) { if (nIndex >= TOTALTIMERS) return -1; if (bSet) {RunTimer(nIndex, SV);} else {StopTimer(nIndex);} return PLCMem.Timers[nIndex].bTon; } int ProcessTimer(int nIndex) { if (nIndex >= TOTALTIMERS) return -1; if (!PLCMem.Timers[nIndex].nInited) return 0; if (PLCMem.Timers[nIndex].bSet) // bSet =1; { if (!PLCMem.Timers[nIndex].bTon) { int nScale = TICK_OF_MS; if (PLCMem.Timers[nIndex].nScale == 0) {nScale = TICK_OF_MS; }else if (PLCMem.Timers[nIndex].nScale == 1) {nScale = TICK_OF_RS; }else if (PLCMem.Timers[nIndex].nScale == 2) {nScale = TICK_OF_XS; }else if (PLCMem.Timers[nIndex].nScale == 3) {nScale = TICK_OF_YS; }else {} int TimeDiff = GetTick() - PLCMem.Timers[nIndex].LastActTime; if (TimeDiff < 0) { TimeDiff = nScale;} if (TimeDiff >= nScale) { int TimeDiffmS = TimeDiff / nScale; unsigned short NextEV = PLCMem.EV[nIndex] + TimeDiffmS; PLCMem.Timers[nIndex].LastActTime += TimeDiffmS*nScale; if (NextEV >= PLCMem.SV[nIndex]) { NextEV = PLCMem.SV[nIndex]; PLCMem.Timers[nIndex].bTon =1; } PLCMem.EV[nIndex] = NextEV; } } }else //bSet=0; { if(PLCMem.Timers[nIndex].bTon) { PLCMem.Timers[nIndex].bTon = 0; } } SetCoilValue(KLCoilTypeT, nIndex, PLCMem.Timers[nIndex].bTon); return PLCMem.Timers[nIndex].bTon; } int IsTimerOn(int nIndex) { if (nIndex >= TOTALTIMERS) return 0; ProcessTimer(nIndex); return PLCMem.Timers[nIndex].bTon; } int GetTimerSV(int nIndex) { if (nIndex >= TOTALTIMERS) return 0; // ProcessTimer(nIndex); return PLCMem.SV[nIndex]; // return 0; } int GetTimerEV(int nIndex) { if (nIndex >= TOTALTIMERS) return 0; // ProcessTimer(nIndex); return PLCMem.EV[nIndex]; // return 0; } int PushInVal(void) { for (int i=TOTAL_CurVAL -1 ;i>0;i--) { PLCMem.CurVALs[i]=PLCMem.CurVALs[i-1]; } PLCMem.CurVALs[0]=PLCMem.CurVAL; return PLCMem.CurVAL; } int PopOutVal(void) { unsigned char theVAL=PLCMem.CurVALs[0]; for (int i=0;inParamType1; switch (thisOP) { case OP_ST_EQ: PushInVal(); PLCMem.CurVAL = (GetVarData(thisAddrType, thisAddr) == GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2)); break; case OP_ST_NE: PushInVal(); PLCMem.CurVAL = (GetVarData(thisAddrType, thisAddr) != GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2)); break; case OP_ST_LT: PushInVal(); PLCMem.CurVAL = (GetVarData(thisAddrType, thisAddr) < GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2)); break; case OP_ST_GT: PushInVal(); PLCMem.CurVAL = (GetVarData(thisAddrType, thisAddr) > GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2)); break; case OP_ST_LE: PushInVal(); PLCMem.CurVAL = (GetVarData(thisAddrType, thisAddr) <= GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2)); break; case OP_ST_GE: PushInVal(); PLCMem.CurVAL = (GetVarData(thisAddrType, thisAddr) >= GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2)); break; case OP_AN_EQ: PLCMem.CurVAL = PLCMem.CurVAL && (GetVarData(thisAddrType, thisAddr) == GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2)); break; case OP_AN_NE: PLCMem.CurVAL = PLCMem.CurVAL && (GetVarData(thisAddrType, thisAddr) != GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2)); break; case OP_AN_LT: PLCMem.CurVAL = PLCMem.CurVAL && (GetVarData(thisAddrType, thisAddr) < GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2)); break; case OP_AN_GT: PLCMem.CurVAL = PLCMem.CurVAL && (GetVarData(thisAddrType, thisAddr) > GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2)); break; case OP_AN_LE: PLCMem.CurVAL = PLCMem.CurVAL && (GetVarData(thisAddrType, thisAddr) <= GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2)); break; case OP_AN_GE: PLCMem.CurVAL = PLCMem.CurVAL && (GetVarData(thisAddrType, thisAddr) >= GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2)); break; case OP_OR_EQ: PLCMem.CurVAL = PLCMem.CurVAL || (GetVarData(thisAddrType, thisAddr) == GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2)); break; case OP_OR_NE: PLCMem.CurVAL = PLCMem.CurVAL || (GetVarData(thisAddrType, thisAddr) != GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2)); break; case OP_OR_LT: PLCMem.CurVAL = PLCMem.CurVAL || (GetVarData(thisAddrType, thisAddr) < GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2)); break; case OP_OR_GT: PLCMem.CurVAL = PLCMem.CurVAL || (GetVarData(thisAddrType, thisAddr) > GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2)); break; case OP_OR_LE: PLCMem.CurVAL = PLCMem.CurVAL || (GetVarData(thisAddrType, thisAddr) <= GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2)); break; case OP_OR_GE: PLCMem.CurVAL = PLCMem.CurVAL || (GetVarData(thisAddrType, thisAddr) >= GetVarData(pBinInstrcn2->nParamType2, pBinInstrcn2->nParamAddr2)); break; default: break; } nNextPos = 2; break; // ??? case OP_TML: case OP_TMR: case OP_TMX: case OP_TMY: pBinInstrcn15 = (stBinInstrcn15 *)(&pBinInstrcn[CurPos]); { unsigned char thisNum= pBinInstrcn15->nOpNum; thisAddrType = pBinInstrcn15->nParamType1; thisAddr = pBinInstrcn15->nParamAddr1; switch (thisOP) { case OP_TML: if (!PLCMem.Timers[thisNum].nInited) InitTimer(thisNum, 0); if (PLCMem.CurVAL) RunTimer(thisNum, GetVarData(thisAddrType, thisAddr)); else StopTimer(thisNum); PLCMem.CurVAL = ProcessTimer(thisNum); break; case OP_TMR: if (!PLCMem.Timers[thisNum].nInited) InitTimer(thisNum, 1); if (PLCMem.CurVAL) RunTimer(thisNum, GetVarData(thisAddrType, thisAddr)); else StopTimer(thisNum); PLCMem.CurVAL = ProcessTimer(thisNum); break; case OP_TMX: if (!PLCMem.Timers[thisNum].nInited) InitTimer(thisNum, 2); if (PLCMem.CurVAL) RunTimer(thisNum, GetVarData(thisAddrType, thisAddr)); else StopTimer(thisNum); PLCMem.CurVAL = ProcessTimer(thisNum); break; case OP_TMY: if (!PLCMem.Timers[thisNum].nInited) InitTimer(thisNum, 3); if (PLCMem.CurVAL) RunTimer(thisNum, GetVarData(thisAddrType, thisAddr)); else StopTimer(thisNum); PLCMem.CurVAL = ProcessTimer(thisNum); break; default: break; } } nNextPos = 2; break; // 1 ?????? case OP_INC: case OP_DEC: pBinInstrcn15 = (stBinInstrcn15 *)(&pBinInstrcn[CurPos]); thisAddrType = pBinInstrcn15->nParamType1; thisAddr = pBinInstrcn15->nParamAddr1; nNextPos = 2; switch (thisOP) { case OP_INC: if (PLCMem.CurVAL) SetVarData(thisAddrType, thisAddr, GetVarData(thisAddrType, thisAddr) + 1); break; case OP_DEC: if (PLCMem.CurVAL) SetVarData(thisAddrType, thisAddr, GetVarData(thisAddrType, thisAddr) - 1); break; default: break; } break; // 2?????? case OP_MV: case OP_ADD2: case OP_SUB2: pBinInstrcn2 = (stBinInstrcn2 *)(&pBinInstrcn[CurPos]); { int nParamType2, nParamAddr2; thisAddrType = pBinInstrcn2->nParamType1; thisAddr = pBinInstrcn2->nParamAddr1; nParamType2 = pBinInstrcn2->nParamType2; nParamAddr2 = pBinInstrcn2->nParamAddr2; switch (thisOP) { case OP_MV: if (PLCMem.CurVAL) SetVarData(nParamType2, nParamAddr2, GetVarData(thisAddrType, thisAddr)); break; case OP_ADD2: if (PLCMem.CurVAL) SetVarData(nParamType2, nParamAddr2, GetVarData(thisAddrType, thisAddr) + GetVarData(nParamType2, nParamAddr2)); break; case OP_SUB2: if (PLCMem.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: pBinInstrcn3 = (stBinInstrcn3 *)(&pBinInstrcn[CurPos]); int nParamType2, nParamAddr2; int nParamType3, nParamAddr3; thisAddrType = pBinInstrcn3->nParamType1; thisAddr = pBinInstrcn3->nParamAddr1; nParamType2 = pBinInstrcn3->nParamType2; nParamAddr2 = pBinInstrcn3->nParamAddr2; nParamType3 = pBinInstrcn3->nParamType3; nParamAddr3 = pBinInstrcn3->nParamAddr3; switch (thisOP) { case OP_ADD3: if (PLCMem.CurVAL) SetVarData(nParamType3, nParamAddr3, GetVarData(thisAddrType, thisAddr) + GetVarData(nParamType2, nParamAddr2)); break; case OP_SUB3: if (PLCMem.CurVAL) SetVarData(nParamType3, nParamAddr3, GetVarData(thisAddrType, thisAddr) - GetVarData(nParamType2, nParamAddr2)); break; case OP_MUL: if (PLCMem.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 (PLCMem.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 = GetBitValue( PLCMem.ProgTrace[CurPos>>4],CurPos&0xf); //GetBitValue(PLCMem.WDFs); SetBitValue( &PLCMem.ProgTrace[CurPos>>4],CurPos&0xf, PLCMem.CurVAL); // lastScanInputVal = PLCMem.ProgTrace[CurPos]; //GetBitValue(PLCMem.WDFs); // PLCMem.ProgTrace[CurPos] = PLCMem.CurVAL; CurPos += nNextPos; } PLCMem.nScanCount++; return CurPos; } #endif // ENABLE_PLC