/** ****************************************************************************** * @file : PLCfunctions.c * @brief : PLC funcstions program body ****************************************************************************** */ //#include "globaldef.h" #include "PLCfunctions.h" #include "string.h" #include "stm32f0xx_hal.h" #include 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; KMem.Timers[nIndex].StatByte = 0x0010 | nType; // Timers[nIndex].nType = 0; KMem.SV[nIndex] = 0; KMem.EV[nIndex] = 0; KMem.Timers[nIndex].LastActTime = GetTick(); return 0; } int 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 = GetTick(); KMem.Timers[nIndex].bSet = 1; } return 0; } int StopTimer(int nIndex) { if (nIndex >= TOTALTIMERS) return -1; if (KMem.Timers[nIndex].bSet) { KMem.EV[nIndex] = 0; KMem.Timers[nIndex].LastActTime = GetTick(); KMem.Timers[nIndex].bSet = 0; } return 0; } int ResetTimer(int nIndex) { if (nIndex >= TOTALTIMERS) return -1; KMem.EV[nIndex] = 0; KMem.Timers[nIndex].bTon = 0; KMem.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 KMem.Timers[nIndex].bTon; } int 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 = GetTick() - 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; } } SetCoilValue(KLCoilTypeT, nIndex, KMem.Timers[nIndex].bTon); return KMem.Timers[nIndex].bTon; } int IsTimerOn(int nIndex) { if (nIndex >= TOTALTIMERS) return 0; ProcessTimer(nIndex); return KMem.Timers[nIndex].bTon; } int GetTimerSV(int nIndex) { if (nIndex >= TOTALTIMERS) return 0; // ProcessTimer(nIndex); return KMem.SV[nIndex]; // return 0; } int GetTimerEV(int nIndex) { if (nIndex >= TOTALTIMERS) return 0; // ProcessTimer(nIndex); return KMem.EV[nIndex]; // return 0; } int PushInVal(void) { for (int i=TOTAL_CurVAL -1 ;i>0;i--) { KMem.CurVALs[i]=KMem.CurVALs[i-1]; } KMem.CurVALs[0]=KMem.CurVAL; return KMem.CurVAL; } int PopOutVal(void) { unsigned char theVAL=KMem.CurVALs[0]; for (int i=0;inParamType1; 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 = PLCMem.ProgTrace[CurPos]; PLCMem.ProgTrace[CurPos] = KMem.CurVAL; CurPos += nNextPos; } PLCMem.nScanCount++; return 0; }