-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathanalog.cpp
497 lines (428 loc) · 13.6 KB
/
analog.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
//----------------------------------------------------------------------------
//Ìîäóëü óïðàâëåíèÿ îáîðóäîâàíèåì
//----------------------- Èñïîëüçóåìûå ðåñóðñû: ------------------------------
//Êëàññ TAnalog ÿâëÿåòñÿ èíòåðôåéñîì äëÿ àíàëîãîâîé ÷àñòè ñõåìû.
//Îí ïðîèçâîäèò ïðåîáðàçîâàíèå êîäà ÖÀÏ è ÀÖÏ â çíà÷åíèå è îáðàòíî
//ñîãëàñíî òåêóùåé êàëèáðîâêå. Âûïîëíÿåò ïðîöåññ ôèëüòðàöèè äàííûõ ÀÖÏ.
//Îñóùåñòâëÿåò óïðàâëåíèå âêëþ÷åíèåì âûõîäà èñòî÷íèêà OUT ON/OFF.
//Âûïîëíÿåò ïðîöåññ èçìåðåíèÿ òåìïåðàòóðû ñ ïîìîùüþ ìîäóëÿ Therm è
//óïðàâëÿåò âåíòèëÿòîðîì.
//----------------------------------------------------------------------------
#include "main.h"
#include "analog.h"
#include "display.h"
#include "sound.h"
//----------------------------------------------------------------------------
//----------------------------- Êëàññ TScaler: -------------------------------
//----------------------------------------------------------------------------
#define SCALE ((1LL << (64 - 16 - 1)) / VMAX) //ìàñøòàá êîýôôèöèåíòîâ
//---------- Âû÷èñëåíèå êàëèáðîâî÷íûõ êîýôôèöèåíòîâ ïî äâóì òî÷êàì: ----------
void TScaler::Calibrate(uint16_t p1, uint16_t c1,
uint16_t p2, uint16_t c2)
{
uint16_t dp = p2 - p1;
uint16_t dc = c2 - c1;
Kx = (SCALE * dp + dc / 2) / dc;
Sx = Kx * c1 - SCALE * p1;
}
//------------------- Ïðåîáðàçîâàíèå êîäà â âåëè÷èíó: ------------------------
uint16_t TScaler::CodeToValue(uint16_t code)
{
int32_t v = (Kx * code - Sx + SCALE / 2) / SCALE;
if(v < 0) v = 0;
if(v > VMAX) v = VMAX;
return(v);
}
//------------------- Ïðåîáðàçîâàíèå âåëè÷èíû â êîä: -------------------------
uint16_t TScaler::ValueToCode(uint16_t value)
{
int32_t c = (SCALE * value + Sx + Kx / 2) / Kx;
if(c < 0) c = 0;
if(c > DAC_MAX_CODE) c = DAC_MAX_CODE;
return(c);
}
//----------------------------------------------------------------------------
//---------------------------- Êëàññ TAnalog: -------------------------------
//----------------------------------------------------------------------------
//----------------------------- Êîíñòðóêòîð: ---------------------------------
TAnalog::TAnalog(void)
{
Therm = new TTherm();
TempUpdate = 0;
Fan = new TFan();
Pin_CC.Init(IN_PULL, PULL_DN);
Pin_ON.Init(OUT_PP_2M, OUT_LO);
Pin_PVG.Init(IN_PULL, PULL_UP);
AdcV = new TAdc<ADC_CH_V, ADC_PIN_V>();
AdcI = new TAdc<ADC_CH_I, ADC_PIN_I>();
DacV = new TDac<DAC_CH_V>();
DacI = new TDac<DAC_CH_I>();
CCTimer = new TSoftTimer(CVCC_DEL);
CCTimer->Force();
CVTimer = new TSoftTimer(CVCC_DEL);
CVTimer->Force();
OvpTimer = new TSoftTimer();
OcpTimer = new TSoftTimer();
OppTimer = new TSoftTimer();
ProtSt = PR_OK;
CvCcSt = PS_UNREG;
CvCcPre = PS_UNREG;
Out = 0;
OutBlinkTimer = new TSoftTimer();
OutBlinkTimer->Oneshot = 1;
OffTime = 0;
//ïðîâåðêà ïèòàíèÿ:
while(PWR->CSR & PWR_CSR_PVDO || !Pin_PVG);
CalibData = new TParamList(CAL_CNT);
// Type Name Min Nom Max
CalibData->AddItem(new TParam(PT_V, " P1 ", VP1L, VPD1, VP1H)); //CAL_VP1
CalibData->AddItem(new TParam(PT_VC, " C1 ", 1, VCD1, DACM)); //CAL_VC1
CalibData->AddItem(new TParam(PT_V, " P2 ", VP2L, VPD2, VP2H)); //CAL_VP2
CalibData->AddItem(new TParam(PT_VC, " C2 ", 1, VCD2, DACM)); //CAL_VC2
CalibData->AddItem(new TParam(PT_I, " P1 ", IP1L, IPD1, IP1H)); //CAL_IP1
CalibData->AddItem(new TParam(PT_IC, " C1 ", 1, ICD1, DACM)); //CAL_IC1
CalibData->AddItem(new TParam(PT_I, " P2 ", IP2L, IPD2, IP2H)); //CAL_IP2
CalibData->AddItem(new TParam(PT_IC, " C2 ", 1, ICD2, DACM)); //CAL_IC2
CalibData->AddItem(new TParam(PT_NYDEF, "Stor", 0, 0, 2)); //CAL_STR
CalibData->AddItem(new TParam(PT_VC, "", 1, VMD1, ADCM)); //CAL_VM1
CalibData->AddItem(new TParam(PT_VC, "", 1, VMD2, ADCM)); //CAL_VM2
CalibData->AddItem(new TParam(PT_IC, "", 1, IMD1, ADCM)); //CAL_IM1
CalibData->AddItem(new TParam(PT_IC, "", 1, IMD2, ADCM)); //CAL_IM2
CalibData->EeSection = new TCrcSection(CalibData->ItemsCount);
CalibData->ReadFromEeprom();
CalibAll();
DacV->OnOff(0);
DacI->OnOff(0);
DacV->SetZero(ZV_VAL);
DacI->SetZero(ZI_VAL);
}
//---------- Êîððåêöèÿ ïðåäåëîâ ïàðàìåòðîâ ñîãëàñíî MAX_V è MAX_I: -----------
void TAnalog::TrimParamsLimits(void)
{
CalibData->Items[CAL_VP2]->Max = Data->TopData->Items[PAR_MAXV]->Value;
//êîððåêöèÿ êîäà, åñëè ïðèøëîñü ïîìåíÿòü òî÷êó:
if(CalibData->Items[CAL_VP2]->Validate())
CalibData->Items[CAL_VC2]->Value =
DacV->ValueToCode(CalibData->Items[CAL_VP2]->Value);
CalibData->Items[CAL_IP2]->Max = Data->TopData->Items[PAR_MAXI]->Value;
//êîððåêöèÿ êîäà, åñëè ïðèøëîñü ïîìåíÿòü òî÷êó:
if(CalibData->Items[CAL_IP2]->Validate())
CalibData->Items[CAL_IC2]->Value =
DacV->ValueToCode(CalibData->Items[CAL_IP2]->Value);
}
//-------------------------- Ïðîöåññ èçìåðåíèÿ: ------------------------------
void TAnalog::Execute(void)
{
Therm->Execute();
AdcV->Execute();
AdcI->Execute();
CvCcControl();
ThermalControl();
Protection();
Supervisor();
OffTimer();
}
//----------------- Çàãðóçêà êàëèáðîâêè äëÿ âñåãî ñðàçó: ---------------------
void TAnalog::CalibAll(void)
{
CalibDacV();
CalibDacI();
CalibAdcV();
CalibAdcI();
}
//-------------------- Çàãðóçêà êàëèáðîâêè äëÿ DAC_V: ------------------------
void TAnalog::CalibDacV(void)
{
DacV->Calibrate(CalibData->Items[CAL_VP1]->Value,
CalibData->Items[CAL_VC1]->Value,
CalibData->Items[CAL_VP2]->Value,
CalibData->Items[CAL_VC2]->Value);
}
//-------------------- Çàãðóçêà êàëèáðîâêè äëÿ DAC_I: ------------------------
void TAnalog::CalibDacI(void)
{
DacI->Calibrate(CalibData->Items[CAL_IP1]->Value,
CalibData->Items[CAL_IC1]->Value,
CalibData->Items[CAL_IP2]->Value,
CalibData->Items[CAL_IC2]->Value);
}
//-------------------- Çàãðóçêà êàëèáðîâêè äëÿ ADC_V: ------------------------
//Åñëè ïàðàìåòð ðàâåí CAL_VM1, ÷èòàåòñÿ ïåðâàÿ òî÷êà êîäà ADC_V.
//Åñëè ïàðàìåòð ðàâåí CAL_VM2, ÷èòàåòñÿ âòîðàÿ òî÷êà êîäà ADC_V.
//Èíà÷å èñïîëüçóþòñÿ ïðåæíèå çíà÷åíèÿ ïàðàìåòðîâ.
void TAnalog::CalibAdcV(char p)
{
if(p == CAL_VM1) CalibData->Items[CAL_VM1]->Value = AdcV->Code;
if(p == CAL_VM2) CalibData->Items[CAL_VM2]->Value = AdcV->Code;
AdcV->Calibrate(CalibData->Items[CAL_VP1]->Value,
CalibData->Items[CAL_VM1]->Value,
CalibData->Items[CAL_VP2]->Value,
CalibData->Items[CAL_VM2]->Value);
}
//-------------------- Çàãðóçêà êàëèáðîâêè äëÿ ADC_I: ------------------------
//Åñëè ïàðàìåòð ðàâåí CAL_IM1, ÷èòàåòñÿ ïåðâàÿ òî÷êà êîäà ADC_I.
//Åñëè ïàðàìåòð ðàâåí CAL_IM2, ÷èòàåòñÿ âòîðàÿ òî÷êà êîäà ADC_I.
//Èíà÷å èñïîëüçóþòñÿ ïðåæíèå çíà÷åíèÿ ïàðàìåòðîâ.
void TAnalog::CalibAdcI(char p)
{
if(p == CAL_IM1) CalibData->Items[CAL_IM1]->Value = AdcI->Code;
if(p == CAL_IM2) CalibData->Items[CAL_IM2]->Value = AdcI->Code;
AdcI->Calibrate(CalibData->Items[CAL_IP1]->Value,
CalibData->Items[CAL_IM1]->Value,
CalibData->Items[CAL_IP2]->Value,
CalibData->Items[CAL_IM2]->Value);
int16_t dp = 2 * AdcI->ValueToCode(0) - AdcI->ValueToCode(DP_VAL);
DP_Code = (dp < 0)? 0 : dp;
}
//------------------------ Îáñëóæèâàíèå çàùèòû: ------------------------------
inline void TAnalog::Protection(void)
{
//OVP:
if(AdcV->FastUpdate)
{
uint16_t vp = Data->SetupData->Items[PAR_OVP]->Value;
//åñëè OVP = MAX_V, çàùèòà âûêëþ÷åíà:
if((vp < Data->SetupData->Items[PAR_OVP]->Max) && Out)
{
if(Analog->AdcV->FastValue >= vp)
{
if(OvpTimer->Over())
{
OutControl(0);
Sound->ABell();
ProtSt |= PR_OVP;
}
}
else
{
OvpTimer->Start(Data->SetupData->Items[PAR_DEL]->Value);
}
}
}
//OCP:
if(AdcI->FastUpdate)
{
uint16_t ip = Data->SetupData->Items[PAR_OCP]->Value;
//åñëè OCP = MAX_I, çàùèòà âûêëþ÷åíà:
if((ip < Data->SetupData->Items[PAR_OCP]->Max) && Out)
{
if(Analog->AdcI->FastValue >= ip)
{
if(OcpTimer->Over())
{
OutControl(0);
Sound->ABell();
ProtSt |= PR_OCP;
}
}
else
{
OcpTimer->Start(Data->SetupData->Items[PAR_DEL]->Value);
}
}
//OPP:
uint16_t pp = Data->SetupData->Items[PAR_OPP]->Value;
//åñëè OPP = MAX_P, çàùèòà âûêëþ÷åíà:
if((pp < Data->SetupData->Items[PAR_OPP]->Max) && Out)
{
uint16_t pow = (uint32_t)Analog->AdcI->FastValue *
Analog->AdcV->FastValue / VI2P;
if(pow >= pp)
{
if(OppTimer->Over())
{
OutControl(0);
Sound->ABell();
ProtSt |= PR_OPP;
}
}
else
{
OppTimer->Start(Data->SetupData->Items[PAR_DEL]->Value);
}
}
}
}
//------------------------- Ñóïåðâèçîð ïèòàíèÿ: ------------------------------
inline void TAnalog::Supervisor(void)
{
static uint8_t PvgCnt = 0;
if(TSysTimer::Tick)
{
if(Pin_PVG) PvgCnt = 0;
else PvgCnt++;
}
if((PWR->CSR & PWR_CSR_PVDO) || (PvgCnt > PVG_PER))
{
Pin_ON = 0;
Sound->Off();
Display->Disable();
TSysTimer::Delay_ms(1000);
__disable_interrupt();
NVIC_SystemReset();
}
}
//------------------------- Ïðîâåðêà ïåðåãðåâà: ------------------------------
inline void TAnalog::ThermalControl(void)
{
if(Therm->Update)
{
Temp = Therm->Value;
int16_t Otp = Data->SetupData->Items[PAR_OTP]->Value;
int16_t TfanL = Data->SetupData->Items[PAR_FNL]->Value;
int16_t TfanH = Data->SetupData->Items[PAR_FNH]->Value;
//îøèáêà òåðìîìåòðà:
if(Temp == TEMP_FAIL)
{
ProtSt &= ~PR_OTP;
}
else
{
//òåìïåðàòóðà áîëüøå ïîðîãà OTP - DTAL:
if(Temp > Otp - DTAL)
{
TfanH = TEMP_FAIL; //ïîëíàÿ ñêîðîñòü âåíòèëÿòîðà
if(Out) Sound->ABell();
//òåìïåðàòóðà ïðåâûøàåò ïîðîã OTP:
if(Temp > Otp)
{
OutControl(0); //âûêëþ÷åíèå âûõîäà
ProtSt |= PR_OTP; //óñòàíîâêà ôëàãà çàùèòû
}
}
//òåìïåðàòóðà ìåíüøå ïîðîãà OTP - DTAL:
else
{
ProtSt &= ~PR_OTP; //ñáðîñ ôëàãà çàùèòû
}
}
Fan->Control(TfanL, TfanH, Temp); //óïðàâëåíèå âåíòèëÿòîðîì
TempUpdate = 1;
}
else
{
TempUpdate = 0;
}
}
//-------------------------- ×òåíèå òåìïåðàòóðû: -----------------------------
int16_t TAnalog::GetTemp(void)
{
return(Temp);
}
//---------------------- ×òåíèå ñêîðîñòè âåíòèëÿòîðà: ------------------------
char TAnalog::GetSpeed(void)
{
return(Fan->GetSpeed());
}
//----------------------- ×òåíèå ñîñòîÿíèÿ çàùèòû: ---------------------------
char TAnalog::GetProtSt(void)
{
return(ProtSt);
}
//------------------------- Ñáðîñ OVP/OCP/OPP: -------------------------------
void TAnalog::ClrProtSt(void)
{
ProtSt &= ~(PR_OVP | PR_OCP | PR_OPP);
}
//-------------------- Îáñëóæèâàíèå ðåæèìîâ CV/CC: ---------------------------
inline void TAnalog::CvCcControl(void)
{
if(TSysTimer::Tick)
{
char state = PS_UNREG;
if(Out)
{
char prestate = PS_UNREG;
//ïðîâåðêà ñèãíàëà CC:
if( Pin_CC) prestate |= PS_CC;
else prestate |= PS_CV;
//åñëè åñòü èçìåíåíèÿ, çàïóñê òàéìåðîâ:
if(prestate != CvCcPre)
{
if(prestate & PS_CV) CVTimer->Start();
if(prestate & PS_CC) CCTimer->Start();
CvCcPre = prestate;
}
//ôîðìèðîâàíèå òåêóùåãî ñîñòîÿíèÿ:
if((prestate & PS_CC) || !CCTimer->Over()) state |= PS_CC;
if((prestate & PS_CV) || !CVTimer->Over()) state |= PS_CV;
//çâóêîâàÿ èíäèêàöèÿ:
if(!(CvCcSt & PS_CC) && (state & PS_CC)) Sound->Alarm();
if(!(CvCcSt & PS_CV) && (state & PS_CV)) Sound->Alert();
}
CvCcSt = state;
//èíäèêàöèÿ ñâåòîäèîäàìè:
Display->LedCC = CvCcSt & PS_CC;
Display->LedCV = CvCcSt & PS_CV;
}
}
//------------------------ ×òåíèå ðåæèìîâ CV/CC: -----------------------------
char TAnalog::GetCvCcSt(void)
{
return(CvCcSt);
}
//------------------------ Ïðîâåðêà ñîñòîÿíèÿ CV: ----------------------------
bool TAnalog::IsCV(void)
{
return(CvCcSt & PS_CV);
}
//------------------------ Ïðîâåðêà ñîñòîÿíèÿ CC: ----------------------------
bool TAnalog::IsCC(void)
{
return(CvCcSt & PS_CC);
}
//-------------------- Âêëþ÷åíèå/âûêëþ÷åíèå âûõîäà: --------------------------
void TAnalog::OutControl(bool on)
{
//îáíóëåíèå ÖÀÏ:
DacV->OnOff(on);
DacI->OnOff(on);
//åñëè âêëþ÷åí Down Programmer, òî Pin_ON íå âûêëþ÷àåì:
if(Data->SetupData->Items[PAR_DNP]->Value)
Pin_ON = 1;
else Pin_ON = on;
Out = on;
Data->OutOn = on;
if(!Out)
{
CvCcSt = PS_UNREG;
Display->LedOut = 0;
Display->LedCC = 0;
Display->LedCV = 0;
}
else
{
CvCcSt = PS_CV;
OvpTimer->Start(Data->SetupData->Items[PAR_DEL]->Value);
OcpTimer->Start(Data->SetupData->Items[PAR_DEL]->Value);
Display->LedOut = 1;
TSysTimer::SecReset(); //ñáðîñ ñåêóíäíîãî òàéìåðà
}
}
//---------------------- ×òåíèå ñîñòîÿíèÿ âûõîäà: ----------------------------
bool TAnalog::OutState(void)
{
return(Out);
}
//-------------------- Òàéìåð àâòîîòêëþ÷åíèÿ âûõîäà: -------------------------
inline void TAnalog::OffTimer(void)
{
if(OutBlinkTimer->Over() && Out) Display->LedOut = 1;
if(TSysTimer::SecTick)
{
if(Out && OffTime)
{
OffTime--;
Display->LedOut = 0;
OutBlinkTimer->Start(OUT_BLINK_TIME);
if(!OffTime)
{
Sound->Beep();
OutControl(0);
}
}
}
}
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------
//----------------------------------------------------------------------------