QuakeGod
2021-07-29 0aeaad0dbccc7c72fba93cb82b6f350c9126451a
提交 | 用户 | 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;
39     PLCMem.Timers[nIndex].StatByte = 0x0010 | nType;
40 //    Timers[nIndex].nType = 0;
41     PLCMem.Timers[nIndex].SV = 0;
42     PLCMem.Timers[nIndex].EV = 0;
43     PLCMem.Timers[nIndex].LastActTime = GetTick();
44     return 0;
45 }
46
47 int StartTimer(int nIndex , int SV)
48 {
49     if (nIndex >= TOTALTIMERS) return -1;    
50     if (!PLCMem.Timers[nIndex].bSet)
51     {
52         PLCMem.Timers[nIndex].SV = SV;
53         PLCMem.Timers[nIndex].EV = 0;
54         PLCMem.Timers[nIndex].LastActTime = GetTick();        
55         PLCMem.Timers[nIndex].bSet = 1;
56     }
57     return 0;
58 }
59
60 int StopTimer(int nIndex)
61 {
62     if (nIndex >= TOTALTIMERS) return -1;    
63     if (PLCMem.Timers[nIndex].bSet)
64     {
65         PLCMem.Timers[nIndex].EV = 0;
66         PLCMem.Timers[nIndex].LastActTime = GetTick();        
67         PLCMem.Timers[nIndex].bSet = 0;        
68     }
69     return 0;
70 }
71 int ResetTimer(int nIndex)
72 {
73     if (nIndex >= TOTALTIMERS) return -1;
74     PLCMem.Timers[nIndex].EV = 0;
75     PLCMem.Timers[nIndex].bTon = 0;
76     PLCMem.Timers[nIndex].LastActTime=GetTick();
77     return 0;
78 }
79
80 int SetTimerValue(int nIndex, int bSet, int SV)
81 {
82     if (nIndex >= TOTALTIMERS) return -1;    
83     if (bSet) {StartTimer(nIndex, SV);}
84     else {StopTimer(nIndex);}
85     return PLCMem.Timers[nIndex].bTon;
86 }
87
88 int ProcessTimer(int nIndex)
89 {
90     if (nIndex >= TOTALTIMERS) return -1;
91     if (!PLCMem.Timers[nIndex].nInited) return 0;
92     if (PLCMem.Timers[nIndex].bSet)        // bSet =1;
93     {
94         if (!PLCMem.Timers[nIndex].bTon)
95         {
96             int TimeDiff = GetTick() - PLCMem.Timers[nIndex].LastActTime;
97             int nScale = TICK_OF_MS;
98             if (PLCMem.Timers[nIndex].nScale == 0)
99             {nScale = TICK_OF_MS;
100             }else if (PLCMem.Timers[nIndex].nScale == 1)
101             {nScale = TICK_OF_RS;
102             }else if (PLCMem.Timers[nIndex].nScale == 2)
103             {nScale = TICK_OF_XS;
104             }else if (PLCMem.Timers[nIndex].nScale == 3)
105             {nScale = TICK_OF_YS;
106             }else {}
107             
108             
109             if (TimeDiff >= nScale)
110             {
111                 int TimeDiffmS = TimeDiff / nScale;
112                 unsigned short NextEV = PLCMem.Timers[nIndex].EV + TimeDiffmS;
113                 PLCMem.Timers[nIndex].LastActTime += TimeDiffmS*nScale;
114                 
115                 if (NextEV >= PLCMem.Timers[nIndex].SV) 
116                 {
117                     NextEV = PLCMem.Timers[nIndex].SV;
118                     PLCMem.Timers[nIndex].bTon =1;
119                 }
120                 PLCMem.Timers[nIndex].EV = NextEV;
121             }
122         }
123     }else         //bSet=0;
124     {
125         if(PLCMem.Timers[nIndex].bTon) 
126         {
127             PLCMem.Timers[nIndex].bTon =    0;
128         }
129     }
130     return PLCMem.Timers[nIndex].bTon;
131 }
132
133 int IsTimerOn(int nIndex)
134 {
135     if (nIndex >= TOTALTIMERS) return 0;
136     ProcessTimer(nIndex);
137     return PLCMem.Timers[nIndex].bTon;
138
139 }
140
141 int GetTimerSV(int nIndex)
142 {
143     if (nIndex >= TOTALTIMERS) return 0;
144 //    ProcessTimer(nIndex);    
145     return PLCMem.Timers[nIndex].SV;
146 //    return 0;    
147 }
148 int GetTimerEV(int nIndex)
149 {
150     if (nIndex >= TOTALTIMERS) return 0;
151 //    ProcessTimer(nIndex);    
152     return PLCMem.Timers[nIndex].EV;
153 //    return 0;
154 }
155 const unsigned short bitMasks[16]=
156 {
157     0x1<<0,
158     0x1<<1,
159     0x1<<2,
160     0x1<<3,
161     0x1<<4,
162     0x1<<5,
163     0x1<<6,
164     0x1<<7,
165     0x1<<8,
166     0x1<<9,
167     0x1<<10,
168     0x1<<11,
169     0x1<<12,
170     0x1<<13,
171     0x1<<14,
172     0x1<<15,
173     
174 };
175
176 inline void SetAddrBit(unsigned short * pW, unsigned char bitAddr)
177 {
178     (*pW)|=bitMasks[bitAddr&0xf];
179 }
180
181 inline void ResetBit(unsigned short * pW, unsigned char bitAddr)
182 {
183     (*pW)&=~bitMasks[bitAddr&0xf];
184 }
185
186 static inline void SetBitValue(unsigned short * pW, unsigned char bitAddr, unsigned char Value)
187 {
188     if (Value)    {    SetAddrBit(pW, bitAddr);}
189     else {ResetBit(pW, bitAddr);}
190 }
191
192 static inline unsigned char GetBitValue(unsigned short W, unsigned char bitAddr)
193 {
194     if (W&bitMasks[bitAddr&0xf]) return 1;
195     else return 0;
196 }
197
198 int InitAllDFs()
199 {
200     for (int i=0;i<TOTAL_WDFS;i++)
201     {
202         PLCMem.WDFs[i]=0;
203     }
204     return TOTAL_WDFS;
205 }
206
207 int IsDF(int nIndex, int bSet)
208 {
209     unsigned short addr1 = (nIndex&0xff0)>>4;
210     unsigned char bitAddr=nIndex&0xf;
211     
212     if (addr1 >= TOTAL_WDFS) return 0;
213     if (!GetBitValue( PLCMem.WDFs[addr1],bitAddr) && bSet)
214     {
215         SetBitValue(&PLCMem.WDFs[addr1],bitAddr,1);
216         return 1;
217     }else
218     {
219         SetBitValue(&PLCMem.WDFs[addr1],bitAddr,bSet);
220     }
221     return 0;
222 }
223
224 int PushInVal(void)
225 {
226     for (int i=TOTAL_CurVAL;i>0;i--)
227     {
228         PLCMem.CurVALs[i]=PLCMem.CurVALs[i-1];
229     }
230     PLCMem.CurVALs[0]=PLCMem.CurVAL;
231     return PLCMem.CurVAL;
232 }
233
234 int PopOutVal(void)
235 {
236     unsigned char theVAL=PLCMem.CurVALs[0];
237     for (int i=0;i<TOTAL_CurVAL-1;i++)
238     {
239         PLCMem.CurVALs[i]=PLCMem.CurVALs[i+1];
240     }
241     return theVAL;
242 }
243
244 int ANS(int bValue)
245 {
246     return PLCMem.CurVAL;
247 }
248 int ORS(int bValue)
249 {
250     return PLCMem.CurVAL;
251 }
252
253 int ST(int nAddr)
254 {
255     return 0;
256 }
257
258 int AN(int nAddr)
259 {
260     return 0;
261 }
262
263 int OR(int nAddr)
264 {
265     return 0;
266 }
267
268 int AN_(int nAddr)
269 {
270     return 0;
271 }
272
273 int OR_(int nAddr)
274 {
275     return 0;
276 }
277
278 stPLCPROG const  prog1[]= //__attribute__((at(0X8008000)))
279 {
280     {OP_ST,Addr_X,0},
281     {OP_OR,Addr_Y,0},
282     {OP_AN_,Addr_X,1},
283     {OP_OUT,Addr_Y,0},
284     
285     {OP_ST,Addr_X,2},
286     {OP_SET,Addr_R,1},
287     {OP_ST,Addr_X,3},
288     {OP_RESET,Addr_R,1},
289     
290     {OP_ST,Addr_R,1},
291     {OP_PSHS,0,0},    
292     {OP_AN_,Addr_Y,1},    
293     {OP_TML,5,25},
294     {OP_SET,Addr_Y,1},    
295     {OP_RESET,Addr_Y,2},    
296
297     {OP_POPS,0,0},
298     {OP_AN,Addr_Y,1},
299     {OP_TML,6,25},
300     {OP_RESET,Addr_Y,1},
301     {OP_SET,Addr_Y,2},
302     
303 };
304
305 /*
306
307     {OP_ST,Addr_R,1},
308     {OP_PSHS,0,0},
309     {OP_AN_,Addr_Y,1},
310     {OP_TMR,5,200},
311     {OP_SET,Addr_Y,1},
312     {OP_POPS,0,0},
313     {OP_AN,Addr_Y,1},
314     {OP_TMR,6,200},
315     {OP_RESET,Addr_Y,1},
316
317 */
318 int nSizeProg1=sizeof(prog1)/sizeof(stPLCPROG);
319
320 char * PLCPRG=
321 {
322     "ST X0\n\
323     AN X1\n\
324     ST Y0\n\
325     AN Y1\n\
326     ORS\n\
327     AN/ X2\n\
328     AN/ X3\n\
329     OT Y0\n\
330     OT Y1\n\
331     "
332 };
333
334 int InitPLCPROGStat()
335 {
336     return 0;
337 }
338
339 unsigned char GetAddrValue(unsigned char AddrType, unsigned short Addr)
340 {
341         unsigned char thisValue;
342         unsigned short Addr1=(Addr&0xff0)>>4;
343         unsigned char bitAddr=Addr&0xf;
344         switch(AddrType)
345         {
346             case Addr_None:
347                 break;
348             case Addr_X:
349                 thisValue=GetBitValue( KMem.WX[Addr1],bitAddr);
350                 break;
351             case Addr_Y:
352                 thisValue=GetBitValue( KMem.WY[Addr1],bitAddr);
353                 break;
354             case Addr_R:
355                 thisValue=GetBitValue( KMem.WR[Addr1],bitAddr);
356                 break;
357             case Addr_T:
358                 thisValue=PLCMem.Timers[Addr].bTon;
359                 break;
360             case Addr_L:
361                 break;
362             default:
363                 break;
364         }    
365         return thisValue;
366 }
367 int SetAddrValue(unsigned char AddrType, unsigned short Addr, unsigned char Value)
368 {
369         unsigned short Addr1=(Addr&0xff0)>>4;
370         unsigned char bitAddr=Addr&0xf;
371         switch(AddrType)
372         {
373             case Addr_None:
374                 break;
375             case Addr_X:
376                 SetBitValue(&KMem.WX[Addr1],bitAddr,Value);
377                 break;
378             case Addr_Y:
379                 SetBitValue(&KMem.WY[Addr1],bitAddr,Value);
380             break;
381             case Addr_R:
382                 SetBitValue(&KMem.WR[Addr1],bitAddr,Value);
383             break;
384             case Addr_T:
385                 PLCMem.Timers[Addr].bTon=Value;
386                 break;
387             case Addr_L:
388                 break;
389             default:
390                 break;
391         }    
392         return Value;
393 }
394 int ProcessPLCPROG(const stPLCPROG * prog,int nSize)
395 {
396     for (int i=0;i<nSize;i++)
397     {
398         unsigned char thisOP=prog[i].OP;
399         unsigned char thisAddrType=prog[i].AddrType;
400         unsigned short thisAddr=prog[i].Addr;
401         switch (thisOP)
402         {
403             case OP_None:
404                 break;
405             case OP_ST:
406                 PushInVal();
407                 PLCMem.CurVAL=GetAddrValue(thisAddrType, thisAddr);
408                 break;
409             case OP_ST_:
410                 PushInVal();
411                 PLCMem.CurVAL=!GetAddrValue(thisAddrType, thisAddr);
412                 break;
413             case OP_AN:
414               PLCMem.CurVAL = PLCMem.CurVAL&&GetAddrValue(thisAddrType, thisAddr);
415                 break;
416             case OP_AN_:
417                 PLCMem.CurVAL = PLCMem.CurVAL && (!GetAddrValue(thisAddrType, thisAddr));
418                 break;
419             case OP_OR:
420                 PLCMem.CurVAL = PLCMem.CurVAL || GetAddrValue(thisAddrType, thisAddr);
421                 break;
422             case OP_OR_:
423                 PLCMem.CurVAL = PLCMem.CurVAL || (!GetAddrValue(thisAddrType, thisAddr));
424                 break;
425             case OP_NOT:
426                 PLCMem.CurVAL = ! PLCMem.CurVAL;
427                 break;
428             case OP_PSHS:
429                 PushInVal();
430                 break;
431             case OP_POPS:
432                 PLCMem.CurVAL = PopOutVal();
433                 break;
434             case OP_ANS:
435                 PLCMem.CurVAL = PLCMem.CurVAL && PopOutVal();
436                 break;
437             case OP_ORS:
438                 PLCMem.CurVAL = PLCMem.CurVAL || PopOutVal();
439                 break;
440
441             case OP_OUT:
442                 SetAddrValue(thisAddrType,thisAddr,PLCMem.CurVAL);
443                 break;
444             case OP_SET:
445                 if (PLCMem.CurVAL) SetAddrValue(thisAddrType,thisAddr,1);
446                 break;
447             case OP_RESET:
448                 if (PLCMem.CurVAL) SetAddrValue(thisAddrType,thisAddr,0);
449                 break;
450             case OP_DF:        
451                 break;
452             case OP_TML:
453                 if (!PLCMem.Timers[thisAddrType].nInited) InitTimer(thisAddrType,0);
454                 if (PLCMem.CurVAL) StartTimer(thisAddrType,thisAddr);
455                 else StopTimer(thisAddrType);
456                 PLCMem.CurVAL = ProcessTimer(thisAddrType);
457             
458                 break;
459             case OP_TMR:
460                 if (!PLCMem.Timers[thisAddrType].nInited) InitTimer(thisAddrType,1);
461                 if (PLCMem.CurVAL) StartTimer(thisAddrType,thisAddr);
462                 else StopTimer(thisAddrType);
463                 PLCMem.CurVAL = ProcessTimer(thisAddrType);
464                 
465                 break;
466             
467             
468             default:
469                 break;
470         }
471     }
472     return 0;
473 }