QuakeGod
2023-01-28 16eeda8e1e205da3395f6933f6f82b22da63c76b
提交 | 用户 | age
bfc108 1 /**
Q 2   ******************************************************************************
3   * @file           : PLCfunctions.c
4   * @brief          : PLC funcstions program body
5   ******************************************************************************
6     */
7 //#include "globaldef.h"
8 #include "PLCfunctions.h"
9 #include "string.h"
10 #include "stm32f0xx_hal.h"
11 #include <core_cmInstr.h>
12
13 extern __IO uint32_t uwTick;
14
15 //unsigned short WDFs[TOTAL_WDFS];
16
17 inline unsigned int GetTick(void)
18 {
19 //    unsigned short Clk1=SysTick->VAL;
20         return uwTick;
21 }
22
23 //unsigned char CurVAL;
24 //unsigned char CurVALs[TOTAL_CurVAL];
25 //stTimer Timers[TOTALTIMERS];
26
27 //unsigned short WX[13];
28 //unsigned short WY[13];
29 //unsigned short WR[64];
30 //unsigned short DT[256];
31
32 //unsigned short SDT[256];
33
34 stPLCMem PLCMem;
35
36 int InitTimer(int nIndex, int nType)
37 {
38     if (nIndex >= TOTALTIMERS) return -1;
85d591 39     KMem.Timers[nIndex].StatByte = 0x0010 | nType;
bfc108 40 //    Timers[nIndex].nType = 0;
85d591 41     KMem.SV[nIndex] = 0;
Q 42     KMem.EV[nIndex] = 0;
43     KMem.Timers[nIndex].LastActTime = GetTick();
bfc108 44     return 0;
Q 45 }
46
85d591 47 int RunTimer(int nIndex , int SV)
bfc108 48 {
Q 49     if (nIndex >= TOTALTIMERS) return -1;    
85d591 50     if (!KMem.Timers[nIndex].bSet)
bfc108 51     {
85d591 52         KMem.SV[nIndex] = SV;
Q 53         KMem.EV[nIndex]= 0;
54         KMem.Timers[nIndex].LastActTime = GetTick();        
55         KMem.Timers[nIndex].bSet = 1;
bfc108 56     }
Q 57     return 0;
58 }
59
60 int StopTimer(int nIndex)
61 {
62     if (nIndex >= TOTALTIMERS) return -1;    
85d591 63     if (KMem.Timers[nIndex].bSet)
bfc108 64     {
85d591 65         KMem.EV[nIndex] = 0;
Q 66         KMem.Timers[nIndex].LastActTime = GetTick();        
67         KMem.Timers[nIndex].bSet = 0;        
bfc108 68     }
Q 69     return 0;
70 }
71 int ResetTimer(int nIndex)
72 {
73     if (nIndex >= TOTALTIMERS) return -1;
85d591 74     KMem.EV[nIndex] = 0;
Q 75     KMem.Timers[nIndex].bTon = 0;
76     KMem.Timers[nIndex].LastActTime=GetTick();
bfc108 77     return 0;
Q 78 }
79
80 int SetTimerValue(int nIndex, int bSet, int SV)
81 {
82     if (nIndex >= TOTALTIMERS) return -1;    
85d591 83     if (bSet) {RunTimer(nIndex, SV);}
bfc108 84     else {StopTimer(nIndex);}
85d591 85     return KMem.Timers[nIndex].bTon;
bfc108 86 }
Q 87
88 int ProcessTimer(int nIndex)
89 {
90     if (nIndex >= TOTALTIMERS) return -1;
85d591 91     if (!KMem.Timers[nIndex].nInited) return 0;
Q 92     if (KMem.Timers[nIndex].bSet)        // bSet =1;
bfc108 93     {
85d591 94         if (!KMem.Timers[nIndex].bTon)
bfc108 95         {
85d591 96             int TimeDiff = GetTick() - KMem.Timers[nIndex].LastActTime;
bfc108 97             int nScale = TICK_OF_MS;
85d591 98             if (KMem.Timers[nIndex].nScale == 0)
bfc108 99             {nScale = TICK_OF_MS;
85d591 100             }else if (KMem.Timers[nIndex].nScale == 1)
bfc108 101             {nScale = TICK_OF_RS;
85d591 102             }else if (KMem.Timers[nIndex].nScale == 2)
bfc108 103             {nScale = TICK_OF_XS;
85d591 104             }else if (KMem.Timers[nIndex].nScale == 3)
bfc108 105             {nScale = TICK_OF_YS;
Q 106             }else {}
107             
108             
109             if (TimeDiff >= nScale)
110             {
111                 int TimeDiffmS = TimeDiff / nScale;
85d591 112                 unsigned short NextEV = KMem.EV[nIndex] + TimeDiffmS;
Q 113                 KMem.Timers[nIndex].LastActTime += TimeDiffmS*nScale;
bfc108 114                 
85d591 115                 if (NextEV >= KMem.SV[nIndex]) 
bfc108 116                 {
85d591 117                     NextEV = KMem.SV[nIndex];
Q 118                     KMem.Timers[nIndex].bTon =1;
bfc108 119                 }
85d591 120                 KMem.EV[nIndex] = NextEV;
bfc108 121             }
Q 122         }
123     }else         //bSet=0;
124     {
85d591 125         if(KMem.Timers[nIndex].bTon) 
bfc108 126         {
85d591 127             KMem.Timers[nIndex].bTon =    0;
bfc108 128         }
Q 129     }
85d591 130     SetCoilValue(KLCoilTypeT, nIndex, KMem.Timers[nIndex].bTon);    
Q 131     return KMem.Timers[nIndex].bTon;
bfc108 132 }
Q 133
134 int IsTimerOn(int nIndex)
135 {
136     if (nIndex >= TOTALTIMERS) return 0;
137     ProcessTimer(nIndex);
85d591 138     return KMem.Timers[nIndex].bTon;
bfc108 139
Q 140 }
141
142 int GetTimerSV(int nIndex)
143 {
144     if (nIndex >= TOTALTIMERS) return 0;
145 //    ProcessTimer(nIndex);    
85d591 146     return KMem.SV[nIndex];
bfc108 147 //    return 0;    
Q 148 }
149 int GetTimerEV(int nIndex)
150 {
151     if (nIndex >= TOTALTIMERS) return 0;
152 //    ProcessTimer(nIndex);    
85d591 153     return KMem.EV[nIndex];
bfc108 154 //    return 0;
Q 155 }
156
157 int PushInVal(void)
158 {
85d591 159     for (int i=TOTAL_CurVAL -1 ;i>0;i--)
bfc108 160     {
85d591 161         KMem.CurVALs[i]=KMem.CurVALs[i-1];
bfc108 162     }
85d591 163     KMem.CurVALs[0]=KMem.CurVAL;
Q 164     return KMem.CurVAL;
bfc108 165 }
Q 166
167 int PopOutVal(void)
168 {
85d591 169     unsigned char theVAL=KMem.CurVALs[0];
bfc108 170     for (int i=0;i<TOTAL_CurVAL-1;i++)
Q 171     {
85d591 172         KMem.CurVALs[i]=KMem.CurVALs[i+1];
bfc108 173     }
Q 174     return theVAL;
175 }
176
85d591 177 stBinProg1 const  prog1[]= //__attribute__((at(0X8008000)))
bfc108 178 {
85d591 179     {OP_ST,KLCoilTypeSR,13},
Q 180     {OP_MV,0,50},    {KLDataTypeDEC,KLDataTypeDT,1},
181     {OP_MV,0,20},    {KLDataTypeDEC,KLDataTypeDT,2},
182     {OP_MV,0,30},    {KLDataTypeDEC,KLDataTypeDT,3},
183     {OP_MV,0,40},    {KLDataTypeDEC,KLDataTypeDT,4},
184     {OP_SET,KLCoilTypeR,0},
185 //    {OP_SET,KLCoilTypeY,0},
bfc108 186     
85d591 187     {OP_ST,KLCoilTypeR,0},
Q 188         {OP_TMX,1,1},    {KLDataTypeDT,0,0},
189         {OP_DF},
190         {OP_SET,KLCoilTypeR,10},
191         
192     {OP_ST,KLCoilTypeX,0},
193     {OP_DF},
194     {OP_SET,KLCoilTypeR,10},
bfc108 195
85d591 196     {OP_ST,KLCoilTypeX,1},
Q 197     {OP_DF},
198     {OP_RESET,KLCoilTypeR,10},
199 /*    
200     {OP_ST,KLCoilTypeR,10},
201     {OP_AN,KLCoilTypeR,51},    
202     {OP_AN,KLCoilTypeR,52},    
203     {OP_AN,KLCoilTypeR,53},    
204     {OP_ADD3,0,21},        {KLDataTypeDT,KLDataTypeDT,31},        {0,KLDataTypeDT,32},    
205
206     {OP_ST,KLCoilTypeR,10},
207     {OP_AN,KLCoilTypeR,54},    
208     {OP_AN,KLCoilTypeR,55},    
209     {OP_AN,KLCoilTypeR,56},    
210     {OP_ADD3,0,23},        {KLDataTypeDT,KLDataTypeDT,33},        {0,KLDataTypeDT,34},    
211 */
212     {OP_ST,KLCoilTypeSR,1},
213     {OP_PSHS},    
214     {OP_AN,KLCoilTypeR,51},    
215     {OP_OUT,KLCoilTypeY,1},    
216     {OP_RDS},    
217     {OP_AN,KLCoilTypeR,52},    
218     {OP_OUT,KLCoilTypeY,2},    
219     {OP_RDS},    
220     {OP_AN,KLCoilTypeR,53},    
221     {OP_OUT,KLCoilTypeY,3},    
222     {OP_RDS},    
223     {OP_AN,KLCoilTypeR,54},    
224     {OP_OUT,KLCoilTypeY,4},    
225     {OP_RDS},    
226     {OP_AN,KLCoilTypeR,55},    
227     {OP_OUT,KLCoilTypeY,5},    
228     {OP_POPS},    
229     {OP_AN,KLCoilTypeR,56},    
230     {OP_OUT,KLCoilTypeY,6},    
231
232     {OP_ST,KLCoilTypeR,10},
233     {OP_DF},
234     {OP_PSHS},    
235     {OP_MV,0,150},    {KLDataTypeDEC,KLDataTypeDT,11},
236     {OP_MV,0,30},    {KLDataTypeDEC,KLDataTypeDT,12},
237     {OP_RDS},    
238     {OP_MV,0,150},    {KLDataTypeDEC,KLDataTypeDT,13},
239     {OP_MV,0,30},    {KLDataTypeDEC,KLDataTypeDT,14},
240     {OP_POPS},    
241     {OP_AN_,KLCoilTypeR,11},    
242     {OP_AN_,KLCoilTypeR,12},    
243     {OP_AN_,KLCoilTypeR,13},    
244     {OP_AN_,KLCoilTypeR,14},    
245     {OP_SET,KLCoilTypeR,14},
246
247     {OP_ST,KLCoilTypeR,10},
248     {OP_PSHS},    
249     {OP_AN,KLCoilTypeR,11},    
250     {OP_DF},
251     {OP_SET,KLCoilTypeR,51},
252     {OP_RESET,KLCoilTypeR,52},
253     {OP_RESET,KLCoilTypeR,53},
254     {OP_RESET,KLCoilTypeR,54},
255     {OP_RESET,KLCoilTypeR,55},
256     {OP_SET,KLCoilTypeR,56},
257
258     {OP_RDS},    
259     {OP_AN,KLCoilTypeR,11},    
260
261         {OP_PSHS},    
262         {OP_TMX,11,11},    {KLDataTypeDT,0,0},
263             {OP_RESET,KLCoilTypeR,11},
264             {OP_SET,KLCoilTypeR,12},
265         {OP_POPS},
266             {OP_SUB3,0,11},        {KLDataTypeSV,KLDataTypeEV,11},        {0,KLDataTypeDT,21},        
267             {OP_AN_LE,0,21},{KLDataTypeDT,KLDataTypeDEC,30},
268             {OP_PSHS},    
269                 {OP_DIV,0,21},        {KLDataTypeDT,KLDataTypeDEC,10},        {0,KLDataTypeDT,31},        
270             {OP_RDS},    
271                 {OP_AN_GE,0,32},{KLDataTypeDT,KLDataTypeDEC,5},
272                 {OP_SET,KLCoilTypeR,51},
273             {OP_POPS},
274                 {OP_AN_LT,0,32},{KLDataTypeDT,KLDataTypeDEC,5},
275                 {OP_RESET,KLCoilTypeR,51},
276     {OP_RDS},            
277     {OP_AN,KLCoilTypeR,12},    
278     {OP_DF},
279     {OP_RESET,KLCoilTypeR,51},
280     {OP_SET,KLCoilTypeR,52},
281     {OP_RDS},            
282     {OP_AN,KLCoilTypeR,12},    
283         {OP_TMX,12,12},    {KLDataTypeDT,0,0},
284             {OP_RESET,KLCoilTypeR,12},
285             {OP_SET,KLCoilTypeR,13},
286     {OP_POPS},
287     {OP_AN,KLCoilTypeR,12},    
288     {OP_OUT,KLCoilTypeR,52},    
bfc108 289     
85d591 290     {OP_ST,KLCoilTypeR,10},
Q 291     {OP_PSHS},    
292     {OP_AN,KLCoilTypeR,13},    
293     {OP_DF},
294     {OP_RESET,KLCoilTypeR,52},
295     {OP_SET,KLCoilTypeR,53},
296     {OP_SET,KLCoilTypeR,54},
297     {OP_RESET,KLCoilTypeR,56},
298     {OP_RDS},    
299     {OP_AN,KLCoilTypeR,13},    
300         {OP_TMX,13,13},    {KLDataTypeDT,0,0},
301             {OP_RESET,KLCoilTypeR,13},
302             {OP_SET,KLCoilTypeR,14},
303     {OP_RDS},    
304     {OP_AN,KLCoilTypeR,13},    
305             {OP_SUB3,0,13},        {KLDataTypeSV,KLDataTypeEV,13},        {0,KLDataTypeDT,23},        
306             {OP_AN_LE,0,23},{KLDataTypeDT,KLDataTypeDEC,30},
307             {OP_PSHS},    
308                 {OP_DIV,0,23},        {KLDataTypeDT,KLDataTypeDEC,10},        {0,KLDataTypeDT,33},        
309             {OP_RDS},    
310                 {OP_AN_GE,0,34},{KLDataTypeDT,KLDataTypeDEC,5},
311                 {OP_SET,KLCoilTypeR,54},
312             {OP_POPS},
313                 {OP_AN_LT,0,34},{KLDataTypeDT,KLDataTypeDEC,5},
314                 {OP_RESET,KLCoilTypeR,54},
315     {OP_RDS},    
316     {OP_AN,KLCoilTypeR,14},    
317     {OP_DF},
318     {OP_RESET,KLCoilTypeR,54},
319     {OP_SET,KLCoilTypeR,55},
320     {OP_POPS},
321     {OP_AN,KLCoilTypeR,14},    
322         {OP_TMX,14,14},    {KLDataTypeDT,0,0},
323             {OP_RESET,KLCoilTypeR,14},
324             {OP_SET,KLCoilTypeR,11},
bfc108 325 };
Q 326
327 /*
328
329     {OP_ST,Addr_R,1},
330     {OP_PSHS,0,0},
331     {OP_AN_,Addr_Y,1},
332     {OP_TMR,5,200},
333     {OP_SET,Addr_Y,1},
334     {OP_POPS,0,0},
335     {OP_AN,Addr_Y,1},
336     {OP_TMR,6,200},
337     {OP_RESET,Addr_Y,1},
338
339 */
85d591 340 int nSizeProg1=sizeof(prog1)/sizeof(stBinProg1);
bfc108 341
85d591 342 int InitPLC()
bfc108 343 {
85d591 344     PLCMem.nScanCount=0;
Q 345     for (int i=0;i<1024;i++){PLCMem.ProgTrace[i]=0;}
346     for (int i=0;i<16;i++)    {
347         KMem.WR[i]=0;
348     }
349     for (int i=0;i<256;i++)    {
350         KMem.DT[i]=0;
351     }
bfc108 352     return 0;
Q 353 }
354
85d591 355 int StartPLC()
bfc108 356 {
85d591 357     PLCMem.nScanCount = 0;
Q 358     for (int i=0;i<1024;i++){PLCMem.ProgTrace[i]=0;}
359     for (int i=0;i<16;i++)    {
360         KMem.WR[i]=0;
361     }
362     for (int i=0;i<256;i++)    {
363         KMem.DT[i]=0;
364     }
365     PLCMem.bPLCRunning=1;
366     return 0;
bfc108 367 }
85d591 368
Q 369 int StopPLC()
bfc108 370 {
85d591 371     PLCMem.bPLCRunning=0;
Q 372     return 0;
bfc108 373 }
85d591 374
Q 375 int ProcessPLCBinProg(const stBinProg1 * pBinprog, int nStepSize)
bfc108 376 {
85d591 377     if (!PLCMem.bPLCRunning) return 0;
Q 378     
379     if (PLCMem.nScanCount == 0) {
380         SetCoilValue(KLCoilTypeSR, 13, 1);
381         SetCoilValue(KLCoilTypeSR, 0, 0);
382         SetCoilValue(KLCoilTypeSR, 1, 1);
383     }
384     else
bfc108 385     {
85d591 386         SetCoilValue(KLCoilTypeSR, 13, 0);
Q 387         SetCoilValue(KLCoilTypeSR, 0, 0);
388         SetCoilValue(KLCoilTypeSR, 1, 1);
389     }
390     for (int i = 0; i < TOTAL_CurVAL; i++) {
391         KMem.CurVALs[i] = 0;
392     }
393     int CurPos = 0;
394 //    stBinProg1 * pBinProg1;
395     stBinProg15 * pBinProg15;
396     stBinProg2 * pBinProg2;
397     stBinProg3 * pBinProg3;
398
399     int lastScanInputVal = 1;//??????,????????,? ?? ???
400
401     while (CurPos < nStepSize)
402     {
403         unsigned int nNextPos = 1;
404         unsigned int thisOP = pBinprog[CurPos].nOp;
405 //        unsigned int nParamCount = 0
406         unsigned char thisAddrType = pBinprog[CurPos].nParamType;
407         unsigned short thisAddr = pBinprog[CurPos].nParamAddr;
408
409
bfc108 410         switch (thisOP)
Q 411         {
85d591 412 //        case OP_NONE:
Q 413 //            break;
414         case OP_NOP:
415             break;
416             //??? ??
417         case OP_NOT:
418         case OP_ANS:
419         case OP_ORS:
420         case OP_PSHS:
421         case OP_RDS:
422         case OP_POPS:
423         case OP_DF:
424         case OP_DF_:
425             switch (thisOP)
426             {
bfc108 427             case OP_NOT:
85d591 428                 KMem.CurVAL = !KMem.CurVAL;
Q 429                 break;
430             case OP_ANS:
431                 KMem.CurVAL = PopOutVal() && KMem.CurVAL;
432                 break;
433             case OP_ORS:
434                 KMem.CurVAL = PopOutVal() || KMem.CurVAL;
bfc108 435                 break;
Q 436             case OP_PSHS:
437                 PushInVal();
438                 break;
85d591 439             case OP_RDS:
Q 440                 KMem.CurVAL = KMem.CurVALs[0] != 0;
441                 break;
bfc108 442             case OP_POPS:
85d591 443                 KMem.CurVAL = PopOutVal();
bfc108 444                 break;
85d591 445             case OP_DF:
Q 446                 KMem.CurVAL = KMem.CurVAL && !lastScanInputVal;
bfc108 447                 break;
85d591 448             case OP_DF_:
Q 449                 KMem.CurVAL = !KMem.CurVAL && lastScanInputVal;
bfc108 450                 break;
Q 451
452             default:
453                 break;
85d591 454             }
Q 455             break;
456             // 1????
457         case OP_ST:
458         case OP_ST_:
459         case OP_AN:
460         case OP_AN_:
461         case OP_OR:
462         case OP_OR_:
463             switch (thisOP)
464             {
465             case OP_ST:
466                 PushInVal();
467                 KMem.CurVAL = GetCoilValue(thisAddrType, thisAddr);
468                 break;
469             case OP_ST_:
470                 PushInVal();
471                 KMem.CurVAL = !GetCoilValue(thisAddrType, thisAddr);
472                 break;
473             case OP_AN:
474                 KMem.CurVAL = KMem.CurVAL&&GetCoilValue(thisAddrType, thisAddr);
475                 break;
476             case OP_AN_:
477                 KMem.CurVAL = KMem.CurVAL && (!GetCoilValue(thisAddrType, thisAddr));
478                 break;
479             case OP_OR:
480                 KMem.CurVAL = KMem.CurVAL || GetCoilValue(thisAddrType, thisAddr);
481                 break;
482             case OP_OR_:
483                 KMem.CurVAL = KMem.CurVAL || (!GetCoilValue(thisAddrType, thisAddr));
484                 break;
485             default:
486                 break;
487             }
488             break;
489             // 1 ?? ??
490         case OP_OUT:
491         case OP_SET:
492         case OP_RESET:
493             switch (thisOP)
494             {
495             case OP_OUT:
496                 SetCoilValue(thisAddrType, thisAddr, KMem.CurVAL);
497                 break;
498             case OP_SET:
499                 if (KMem.CurVAL) SetCoilValue(thisAddrType, thisAddr, 1);
500                 break;
501             case OP_RESET:
502                 if (KMem.CurVAL) SetCoilValue(thisAddrType, thisAddr, 0);
503                 break;
504             default:
505                 break;
506             }
507             break;
508             // ????
509         case OP_ST_EQ:
510         case OP_ST_NE:
511         case OP_ST_LT:
512         case OP_ST_GT:
513         case OP_ST_LE:
514         case OP_ST_GE:
515         case OP_AN_EQ:
516         case OP_AN_NE:
517         case OP_AN_LT:
518         case OP_AN_GT:
519         case OP_AN_LE:
520         case OP_AN_GE:
521         case OP_OR_EQ:
522         case OP_OR_NE:
523         case OP_OR_LT:
524         case OP_OR_GT:
525         case OP_OR_LE:
526         case OP_OR_GE:
527             pBinProg2 = (stBinProg2 *)&pBinprog[CurPos];
528             thisAddrType = pBinProg2->nParamType1;
529
530             switch (thisOP)
531             {
532             case OP_ST_EQ:
533                 PushInVal();
534                 KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) == GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
535                 break;
536             case OP_ST_NE:
537                 PushInVal();
538                 KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) != GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
539                 break;
540             case OP_ST_LT:
541                 PushInVal();
542                 KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) < GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
543                 break;
544             case OP_ST_GT:
545                 PushInVal();
546                 KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) > GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
547                 break;
548             case OP_ST_LE:
549                 PushInVal();
550                 KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) <= GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
551                 break;
552             case OP_ST_GE:
553                 PushInVal();
554                 KMem.CurVAL = (GetVarData(thisAddrType, thisAddr) >= GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
555                 break;
556             case OP_AN_EQ:
557                 KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) == GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
558                 break;
559             case OP_AN_NE:
560                 KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) != GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
561                 break;
562             case OP_AN_LT:
563                 KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) < GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
564                 break;
565             case OP_AN_GT:
566                 KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) > GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
567                 break;
568             case OP_AN_LE:
569                 KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) <= GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
570                 break;
571             case OP_AN_GE:
572                 KMem.CurVAL = KMem.CurVAL && (GetVarData(thisAddrType, thisAddr) >= GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
573                 break;
574
575             case OP_OR_EQ:
576                 KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) == GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
577                 break;
578             case OP_OR_NE:
579                 KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) != GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
580                 break;
581             case OP_OR_LT:
582                 KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) < GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
583                 break;
584             case OP_OR_GT:
585                 KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) > GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
586                 break;
587             case OP_OR_LE:
588                 KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) <= GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
589                 break;
590             case OP_OR_GE:
591                 KMem.CurVAL = KMem.CurVAL || (GetVarData(thisAddrType, thisAddr) >= GetVarData(pBinProg2->nParamType2, pBinProg2->nParamAddr2));
592                 break;
593
594             default:
595                 break;
596             }
597             nNextPos = 2;
598             break;
599             // ???
600         case OP_TML:
601         case OP_TMR:
602         case OP_TMX:
603         case OP_TMY:
604             pBinProg15 = (stBinProg15 *)(&pBinprog[CurPos]);
605             {
606                 unsigned char thisNum= pBinProg15->nOpNum;
607                 thisAddrType = pBinProg15->nParamType1;
608                 thisAddr = pBinProg15->nParamAddr1;
609                 switch (thisOP)
610                 {
611                 case OP_TML:
612                     if (!KMem.Timers[thisNum].nInited) InitTimer(thisNum, 0);
613                     if (KMem.CurVAL) RunTimer(thisNum, GetVarData(thisAddrType, thisAddr));
614                     else StopTimer(thisNum);
615                     KMem.CurVAL = ProcessTimer(thisNum);
616
617                     break;
618                 case OP_TMR:
619                     if (!KMem.Timers[thisNum].nInited) InitTimer(thisNum, 1);
620                     if (KMem.CurVAL) RunTimer(thisNum, GetVarData(thisAddrType, thisAddr));
621                     else StopTimer(thisNum);
622                     KMem.CurVAL = ProcessTimer(thisNum);
623                     break;
624                 case OP_TMX:
625                     if (!KMem.Timers[thisNum].nInited) InitTimer(thisNum, 2);
626                     if (KMem.CurVAL) RunTimer(thisNum, GetVarData(thisAddrType, thisAddr));
627                     else StopTimer(thisNum);
628                     KMem.CurVAL = ProcessTimer(thisNum);
629
630                     break;
631                 case OP_TMY:
632                     if (!KMem.Timers[thisNum].nInited) InitTimer(thisNum, 3);
633                     if (KMem.CurVAL) RunTimer(thisNum, GetVarData(thisAddrType, thisAddr));
634                     else StopTimer(thisNum);
635                     KMem.CurVAL = ProcessTimer(thisNum);
636                     break;
637                 default:
638                     break;
639                 }
640
641             }
642             nNextPos = 2;
643             break;
644             // 1 ??????
645         case OP_INC:
646         case OP_DEC:
647             pBinProg15 = (stBinProg15 *)(&pBinprog[CurPos]);
648             thisAddrType = pBinProg15->nParamType1;
649             thisAddr = pBinProg15->nParamAddr1;
650             nNextPos = 2;
651             switch (thisOP)
652             {
653             case OP_INC:
654                 if (KMem.CurVAL) SetVarData(thisAddrType, thisAddr, GetVarData(thisAddrType, thisAddr) + 1);
655                 break;
656             case OP_DEC:
657                 if (KMem.CurVAL) SetVarData(thisAddrType, thisAddr, GetVarData(thisAddrType, thisAddr) - 1);
658                 break;
659
660             default:
661                 break;
662             }
663             break;
664             // 2??????
665         case OP_MV:
666         case OP_ADD2:
667         case OP_SUB2:
668             pBinProg2 = (stBinProg2 *)(&pBinprog[CurPos]);
669             {
670                 int nParamType2, nParamAddr2;
671                 thisAddrType = pBinProg2->nParamType1;
672                 thisAddr = pBinProg2->nParamAddr1;
673                 nParamType2 = pBinProg2->nParamType2;
674                 nParamAddr2 = pBinProg2->nParamAddr2;
675
676                 switch (thisOP)
677                 {
678                 case OP_MV:
679                     if (KMem.CurVAL) SetVarData(nParamType2, nParamAddr2, GetVarData(thisAddrType, thisAddr));
680                     break;
681                 case OP_ADD2:
682                     if (KMem.CurVAL) SetVarData(nParamType2, nParamAddr2, GetVarData(thisAddrType, thisAddr) + GetVarData(nParamType2, nParamAddr2));
683                     break;
684                 case OP_SUB2:
685                     if (KMem.CurVAL) SetVarData(nParamType2, nParamAddr2, GetVarData(nParamType2, nParamAddr2) - GetVarData(thisAddrType, thisAddr));
686                     break;
687
688                 default:
689                     break;
690                 }
691
692             }
693             nNextPos = 2;
694             break;
695             // 3 ??????
696         case OP_ADD3:
697         case OP_SUB3:
698         case OP_MUL:
699         case OP_DIV:
700             pBinProg3 = (stBinProg3 *)(&pBinprog[CurPos]);
701             int nParamType2, nParamAddr2;
702             int nParamType3, nParamAddr3;
703             thisAddrType = pBinProg3->nParamType1;
704             thisAddr = pBinProg3->nParamAddr1;
705             nParamType2 = pBinProg3->nParamType2;
706             nParamAddr2 = pBinProg3->nParamAddr2;
707             nParamType3 = pBinProg3->nParamType3;
708             nParamAddr3 = pBinProg3->nParamAddr3;
709             switch (thisOP)
710             {
711             case OP_ADD3:
712                 if (KMem.CurVAL) SetVarData(nParamType3, nParamAddr3, GetVarData(thisAddrType, thisAddr) + GetVarData(nParamType2, nParamAddr2));
713                 break;
714             case OP_SUB3:
715                 if (KMem.CurVAL) SetVarData(nParamType3, nParamAddr3, GetVarData(thisAddrType, thisAddr) - GetVarData(nParamType2, nParamAddr2));
716                 break;
717             case OP_MUL:
718                 if (KMem.CurVAL) {
719                     short multiplicand = GetVarData(thisAddrType, thisAddr);
720                     short multiplier = GetVarData(nParamType2, nParamAddr2);
721                     int product = multiplicand * multiplier;
722                     SetVarData(nParamType3, nParamAddr3, product);
723                     SetVarData(nParamType3, nParamAddr3 + 1, product >> 16);
724                 }
725                 break;
726             case OP_DIV:
727                 if (KMem.CurVAL) {
728                     short dividend = GetVarData(thisAddrType, thisAddr);
729                     short divisor = GetVarData(nParamType2, nParamAddr2);
730                     short quotient = dividend / divisor;
731                     short remainder = dividend % divisor;
732                     SetVarData(nParamType3, nParamAddr3, quotient);
733                     SetVarData(nParamType3, nParamAddr3 + 1, remainder);
734                 }
735                 break;
736
737             default:
738                 break;
739             }
740             nNextPos = 3;
741             break;
742
743         default:
744             break;
bfc108 745         }
85d591 746
Q 747         lastScanInputVal = PLCMem.ProgTrace[CurPos];
748         PLCMem.ProgTrace[CurPos] = KMem.CurVAL;
749         CurPos += nNextPos;
bfc108 750     }
85d591 751     PLCMem.nScanCount++;
bfc108 752     return 0;
Q 753 }