-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathanalog.h
493 lines (417 loc) · 13.2 KB
/
analog.h
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
//----------------------------------------------------------------------------
//Ìîäóëü óïðàâëåíèÿ îáîðóäîâàíèåì, çàãîëîâî÷íûé ôàéë
//----------------------------------------------------------------------------
#ifndef ANALOG_H
#define ANALOG_H
//----------------------------------------------------------------------------
#include "systimer.h"
#include "therm.h"
#include "fan.h"
#include "data.h"
#include "ditherdac.h"
#include "overadc.h"
//------------------------------- Êîíñòàíòû: ---------------------------------
//Ïðåäåëüíûå ïàðàìåòðû:
#define V_SCALE_MIN 10.00 //íàèìåíüøàÿ øêàëà íàïðÿæåíèÿ, Â
#define I_SCALE_MIN 1.000 //íàèìåíüøàÿ øêàëà òîêà, À
#define P_SCALE_MIN 1.0 //íàèìåíüøàÿ øêàëà ìîùíîñòè, Âò
#define V_SCALE_NOM 36.00 //íîìèíàëüíàÿ øêàëà íàïðÿæåíèÿ, Â
#define I_SCALE_NOM 4.000 //íîìèíàëüíàÿ øêàëà òîêà, À
#define P_SCALE_NOM 100.0 //íîìèíàëüíàÿ øêàëà ìîùíîñòè, Âò
#define V_SCALE_MAX 99.99 //íàèáîëüøàÿ øêàëà íàïðÿæåíèÿ, Â
#define I_SCALE_MAX 9.999 //íàèáîëüøàÿ øêàëà òîêà, À
#define P_SCALE_MAX 999.9 //íàèáîëüøàÿ øêàëà ìîùíîñòè, Âò
#define V_DEFAULT 5.00 //íàïðÿæåíèå ïî óìîë÷àíèþ, Â
#define I_DEFAULT 1.000 //òîê ïî óìîë÷àíèþ, À
//Ðàçðåøåíèå:
#define V_RES 0.01 //ðàçðåøåíèå ïî íàïðÿæåíèþ, Â
#define I_RES 0.001 //ðàçðåøåíèå ïî òîêó, À
#define P_RES 0.1 //ðàçðåøåíèå ïî ìîùíîñòè, Âò
//Ïåðåâîä åñòåñòâåííûõ âåëè÷èí (âîëüòû, àìïåðû, âàòòû)
//â èõ âíóòðåííå ïðåäñòàâëåíèå:
#define VOLTS2VAL(x) ((uint16_t)(x / V_RES + 0.5))
#define AMPS2VAL(x) ((uint16_t)(x / I_RES + 0.5))
#define WATTS2VAL(x) ((uint16_t)(x / P_RES + 0.5))
//Äåëèòåëü äëÿ ïåðåâîäà VI â P:
#define VI2P ((uint32_t)(P_RES / (V_RES * I_RES)))
//Õàðàêòåðèñòèêè àíàëîãîâîãî òðàêòà:
#define V_REF 3.30 //îïîðíîå íàïðÿæåíèå, Â
#define R28 1500 //âåðõíèé ðåçèñòîð äåëèòåëÿ COM, Îì
#define R29 49.9 //íèæíèé ðåçèñòîð äåëèòåëÿ COM, Îì
#define R70 20000 //ðåçèñòîðû R70 = R71 äèôôóñèëèòåëÿ íàïðÿæåíèÿ, Îì
#define R61 100000 //ðåçèñòîðû R61 = R62 äèôôóñèëèòåëÿ íàïðÿæåíèÿ, Îì
#define R57 10000 //ðåçèñòîðû R57 = R58 äèôôóñèëèòåëÿ íàïðÿæåíèÿ, Îì
#define R63 10000 //ðåçèñòîðû R63 = R64 äèôôóñèëèòåëÿ òîêà, Îì
#define R59 100000 //ðåçèñòîðû R59 = R60 äèôôóñèëèòåëÿ òîêà, Îì
#define R67R72 75 //äàò÷èê òîêà R67 || R72, ìÎì
#define V_COM (V_REF * R29 / (R28 + R29))
#define DP_I 0.005 //ïîðîã èíäèêàöèè DP, A
#define ZERO_V 0.00 //çàãðóæàåìîå íàïðÿæåíèå ïðè OUT OFF, Â
#define ZERO_I 0.001 //çàãðóæàåìûé òîê ïðè OUT OFF, À
#define DP_VAL AMPS2VAL(DP_I)
#define ZV_VAL VOLTS2VAL(ZERO_V)
#define ZI_VAL AMPS2VAL(ZERO_I)
//Äëÿ óñïåøíîé êàëèáðîâêè íóæíî:
//V_COM + V_DAC_FS < V_REF * 0.95
//V_COM + I_DAC_FS < V_REF * 0.95
//Äëÿ ïîëó÷åíèÿ ìàêñèìàëüíîé òî÷íîñòè æåëàòåëüíî:
//V_COM + V_DAC_FS > V_REF * 0.75
//V_COM + I_DAC_FS > V_REF * 0.75
//Äëÿ âûáðàííîãî âûõîäíîãî íàïðÿæåíèÿ è òîêà ýòî äîñòèãàåòñÿ ïðàâèëüíûì
//âûáîðîì ðåçèñòîðîâ äèôôóñèëèòåëåé íàïðÿæåíèÿ è òîêà, à òàêæå äàò÷èêà òîêà.
#define V_DAC_FS (V_SCALE_NOM / ((R70 + R61) / R57))
#define I_DAC_FS (I_SCALE_NOM * R67R72 / 1000 * R59 / R63)
//Êîäû çíà÷åíèé:
//Êîäû çíà÷åíèé:
#define VMIN VOLTS2VAL(V_SCALE_MIN)
#define IMIN AMPS2VAL(I_SCALE_MIN)
#define PMIN WATTS2VAL(P_SCALE_MIN)
#define VNOM VOLTS2VAL(V_SCALE_NOM)
#define INOM AMPS2VAL(I_SCALE_NOM)
#define PNOM WATTS2VAL(P_SCALE_NOM)
#define VMAX VOLTS2VAL(V_SCALE_MAX)
#define IMAX AMPS2VAL(I_SCALE_MAX)
#define PMAX WATTS2VAL(P_SCALE_MAX)
#define VDEF VOLTS2VAL(V_DEFAULT)
#define IDEF AMPS2VAL(I_DEFAULT)
//êðàòêèå ñèíîíèìû ïîëíîé øêàëû ÀÖÏ è ÖÀÏ:
#define ADCM ADC_MAX_CODE
#define DACM DAC_MAX_CODE
//Ïàðàìåòðû êàëèáðîâêè:
enum CalibData_t
{
CAL_VP1, //êàëèáðîâêà V, òî÷êà 1
CAL_VC1, //êàëèáðîâêà V, êîä 1
CAL_VP2, //êàëèáðîâêà V, òî÷êà 2
CAL_VC2, //êàëèáðîâêà V, êîä 2
CAL_IP1, //êàëèáðîâêà I, òî÷êà 1
CAL_IC1, //êàëèáðîâêà I, êîä 1
CAL_IP2, //êàëèáðîâêà I, òî÷êà 2
CAL_IC2, //êàëèáðîâêà I, êîä 2
CAL_STR, //ñîõðàíåíèå êàëèáðîâêè
CAL_VM1, //êàëèáðîâêà MeterV, êîä 1
CAL_VM2, //êàëèáðîâêà MeterV, êîä 2
CAL_IM1, //êàëèáðîâêà MeterI, êîä 1
CAL_IM2, //êàëèáðîâêà MeterI, êîä 2
CAL_CNT
};
//Ïðåäåëû äëÿ êàëèáðîâî÷íûõ òî÷åê:
#define VP1_MIN 0.01 //ìèíèìàëüíîå çíà÷åíèå òî÷êè 1 ïî íàïðÿæåíèþ, Â
#define VP1_MAX 8.99 //ìàêñèìàëüíîå çíà÷åíèå òî÷êè 1 ïî íàïðÿæåíèþ, Â
#define VP2_MIN 9.00 //ìèíèìàëüíîå çíà÷åíèå òî÷êè 2 ïî íàïðÿæåíèþ, Â
#define VP2_MAX V_SCALE_NOM //ìàêñèìàëüíîå çíà÷åíèå òî÷êè 2 ïî íàïðÿæåíèþ, Â
#define IP1_MIN 0.001 //ìèíèìàëüíîå çíà÷åíèå òî÷êè 1 ïî òîêó, À
#define IP1_MAX 0.899 //ìàêñèìàëüíîå çíà÷åíèå òî÷êè 1 ïî òîêó, À
#define IP2_MIN 0.900 //ìèíèìàëüíîå çíà÷åíèå òî÷êè 2 ïî òîêó, À
#define IP2_MAX I_SCALE_NOM //ìàêñèìàëüíîå çíà÷åíèå òî÷êè 2 ïî òîêó, À
//Êîäû ïðåäåëîâ äëÿ êàëèáðîâî÷íûõ òî÷åê:
#define VP1L VOLTS2VAL(VP1_MIN)
#define VP1H VOLTS2VAL(VP1_MAX)
#define VP2L VOLTS2VAL(VP2_MIN)
#define VP2H VOLTS2VAL(VP2_MAX)
#define IP1L AMPS2VAL(IP1_MIN)
#define IP1H AMPS2VAL(IP1_MAX)
#define IP2L AMPS2VAL(IP2_MIN)
#define IP2H AMPS2VAL(IP2_MAX)
//Ïðîìåæóòî÷íûå êîíñòàíòû äëÿ ðàñ÷åòà íîìèíàëüíûõ êàëèáðîâî÷íûõ êîýôôèöèåíòîâ:
#define V_DELTA 1.00 //íîì. ðàññòîÿíèå êàëèá. òî÷åê îò êðàåâ øêàëû, Â
#define I_DELTA 0.100 //íîì. ðàññòîÿíèå êàëèá. òî÷åê îò êðàåâ øêàëû, À
#define DAC_LSB (V_REF / DAC_MAX_CODE) //0.0000503663 (example)
#define COM_DAC (V_COM / DAC_LSB) //2109.457
#define V_OUT_RES (DAC_LSB * V_SCALE_NOM / V_DAC_FS) //0.0006043956
#define I_OUT_RES (DAC_LSB * I_SCALE_NOM / I_DAC_FS) //0.000067155
#define ADC_LSB (V_REF / ADC_MAX_CODE) //0.0000503663
#define COM_ADC (V_COM / ADC_LSB) //2109.457
#define V_IN_RES (ADC_LSB * V_SCALE_NOM / V_DAC_FS) //0.0006043956
#define I_IN_RES (ADC_LSB * I_SCALE_NOM / I_DAC_FS) //0.000067155
//Íîìèíàëüíûå êàëèáðîâî÷íûå êîýôôèöèåíòû:
#define VPD1 ((uint16_t)(V_DELTA / V_RES + 0.5))
#define VPD2 ((uint16_t)((V_SCALE_NOM - V_DELTA) / V_RES + 0.5))
#define IPD1 ((uint16_t)(I_DELTA / I_RES + 0.5))
//#define IPD2 ((uint16_t)((I_SCALE_NOM - I_DELTA) / I_RES + 0.5))
#define IPD2 ((uint16_t)(1.900 / I_RES + 0.5)) //äëÿ óìåíüøåíèÿ íàãðåâà øóíòà
#define VCD1 ((uint16_t)(VPD1 * V_RES / V_OUT_RES + COM_DAC + 0.5)) //3764
#define VCD2 ((uint16_t)(VPD2 * V_RES / V_OUT_RES + COM_DAC + 0.5)) //60019
#define ICD1 ((uint16_t)(IPD1 * I_RES / I_OUT_RES + COM_DAC + 0.5)) //3599
#define ICD2 ((uint16_t)(IPD2 * I_RES / I_OUT_RES + COM_DAC + 0.5)) //30402
#define VMD1 ((uint16_t)(VPD1 * V_RES / V_IN_RES + COM_ADC + 0.5)) //3764
#define VMD2 ((uint16_t)(VPD2 * V_RES / V_IN_RES + COM_ADC + 0.5)) //60019
#define IMD1 ((uint16_t)(IPD1 * I_RES / I_IN_RES + COM_ADC + 0.5)) //3599
#define IMD2 ((uint16_t)(IPD2 * I_RES / I_IN_RES + COM_ADC + 0.5)) //30402
//DAC_I ïðè êàëèáðîâêå V è DAC_V ïðè êàëèáðîâêå I çàãðóæàåòñÿ
//â êîäàõ (1/8 øêàëû), ÷òîáû èçáåæàòü âëèÿíèÿ òåêóùåé êàëèáðîâêè:
#define DAC_CAL_CODE (DAC_MAX_CODE / 8)
//ïàðàìåòðû èçìåðèòåëåé:
#define ADC_TUPD 320 //ïåðèîä îáíîâëåíèÿ èçìåðåííûõ çíà÷åíèé, ìñ
#define CVCC_DEL 120 //çàäåðæêà âûõîäà èç CV/CC, ìñ
#define FIR_POINTS (ADC_TUPD * ADC_FS / OVER_N / 1000)
#define ADC_PIN_V PIN7
#define ADC_PIN_I PIN6
#define ADC_CH_V 1
#define ADC_CH_I 0
#define DAC_CH_V 1
#define DAC_CH_I 0
//Ðåæèìû ðàáîòû èçìåðèòåëåé:
enum MeterMode_t { METER_AVG, METER_PKH, METER_PKL };
#define HOLD_TIME 1000 //âðåìÿ óäåðæàíèÿ ïèêîâûõ ïîêàçàíèé, ìñ
#define PVG_PER 50 //ìàêñèìàëüíûé ïåðèîä èìïóëüñîâ PVG, ìñ
#define OUT_BLINK_TIME 200 //âðåìÿ ãàøåíèÿ LED OUT ïðè ðàáîòå òàéìåðà, ìñ
//Ñîñòîÿíèå CV/CC:
enum CvCcState_t
{
PS_UNREG = 0,
PS_CV = 1,
PS_CC = 2,
PS_CVCC = 3
};
//Ñîñòîÿíèå çàùèòû:
enum PrState_t
{
PR_OK = 0,
PR_OVP = 1,
PR_OCP = 2,
PR_OPP = 4,
PR_OTP = 8
};
//----------------------------------------------------------------------------
//----------------------------- Êëàññ TScaler: -------------------------------
//----------------------------------------------------------------------------
class TScaler
{
private:
int64_t Kx;
int64_t Sx;
public:
TScaler(void) {};
void Calibrate(uint16_t p1, uint16_t c1,
uint16_t p2, uint16_t c2);
uint16_t CodeToValue(uint16_t code);
uint16_t ValueToCode(uint16_t value);
};
//----------------------------------------------------------------------------
//------------------------- Øàáëîííûé êëàññ TDac: ----------------------------
//----------------------------------------------------------------------------
template<uint8_t DacN>
class TDac : public TScaler
{
private:
TDitherDac<DacN> Dac;
uint16_t Code;
uint16_t ZeroCode;
bool On;
public:
TDac(void);
void SetCode(uint16_t c);
void SetZero(uint16_t z);
void SetValue(uint16_t v);
void OnOff(bool on);
};
//------------------------- Ðåàëèçàöèÿ ìåòîäîâ: ------------------------------
template<uint8_t DacN>
TDac<DacN>::TDac(void) : On(0), Code(0)
{
Dac.Init();
}
template<uint8_t DacN>
void TDac<DacN>::SetCode(uint16_t c)
{
Code = c;
if(On) Dac = Code;
}
template<uint8_t DacN>
void TDac<DacN>::SetZero(uint16_t z)
{
ZeroCode = ValueToCode(z);
if(!On) Dac = ZeroCode;
}
template<uint8_t DacN>
void TDac<DacN>::SetValue(uint16_t v)
{
Code = ValueToCode(v);
if(On) Dac = Code;
}
template<uint8_t DacN>
void TDac<DacN>::OnOff(bool on)
{
On = on;
Dac = On? Code : ZeroCode;
}
//----------------------------------------------------------------------------
//------------------------- Øàáëîííûé êëàññ TAdc: ----------------------------
//----------------------------------------------------------------------------
template<uint8_t AdcN, uint8_t AdcPin>
class TAdc : public TScaler
{
private:
TOverAdc<AdcN, AdcPin> Adc;
uint32_t FirCode;
uint16_t FirPointer;
bool ReadyFlag;
uint16_t HoldTime;
char Mode;
public:
TAdc(void);
void Execute(void);
void SetMode(char m);
bool FastUpdate;
uint16_t FastCode;
uint16_t FastValue;
bool Query(void);
bool Ready(void);
void Sync(void);
uint16_t Code;
uint16_t Value;
};
//------------------------- Ðåàëèçàöèÿ ìåòîäîâ: ------------------------------
template<uint8_t AdcN, uint8_t AdcPin>
TAdc<AdcN, AdcPin>::TAdc(void)
{
Adc.Init();
Mode = METER_AVG;
HoldTime = 0;
FastUpdate = 0;
FirCode = 0;
FirPointer = 0;
FastCode = 0;
FastValue = 0;
ReadyFlag = 0;
Code = 0;
Value = 0;
}
template<uint8_t AdcN, uint8_t AdcPin>
void TAdc<AdcN, AdcPin>::SetMode(char m)
{
Mode = m;
HoldTime = 0;
}
template<uint8_t AdcN, uint8_t AdcPin>
void TAdc<AdcN, AdcPin>::Execute(void)
{
if(Adc.Ready())
{
FastCode = Adc;
FastValue = CodeToValue(FastCode);
if(HoldTime) HoldTime--;
FirCode += FastCode;
if(++FirPointer == FIR_POINTS)
{
Code = (FirCode + FIR_POINTS / 2) / FIR_POINTS;
if(Mode == METER_AVG)
{
Value = CodeToValue(Code);
}
FirCode = FirPointer = 0;
ReadyFlag = 1;
}
if(Mode == METER_PKH)
{
if(FastValue >= Value)
{
Value = FastValue;
HoldTime = HOLD_TIME;
}
else
{
if(!HoldTime)
Value = FastValue;
}
}
if(Mode == METER_PKL)
{
if(FastValue <= Value)
{
Value = FastValue;
HoldTime = HOLD_TIME;
}
else
{
if(!HoldTime)
Value = FastValue;
}
}
FastUpdate = 1;
}
else
{
FastUpdate = 0;
}
}
template<uint8_t AdcN, uint8_t AdcPin>
inline bool TAdc<AdcN, AdcPin>::Query(void)
{
return(ReadyFlag);
}
template<uint8_t AdcN, uint8_t AdcPin>
inline bool TAdc<AdcN, AdcPin>::Ready(void)
{
if(ReadyFlag)
{
ReadyFlag = 0;
return(1);
}
return(0);
}
template<uint8_t AdcN, uint8_t AdcPin>
void TAdc<AdcN, AdcPin>::Sync(void)
{
FirCode = FirPointer = 0;
ReadyFlag = 0;
}
//----------------------------------------------------------------------------
//----------------------------- Êëàññ TAnalog: -------------------------------
//----------------------------------------------------------------------------
class TAnalog
{
private:
TGpio<PORTB, PIN0> Pin_CC;
TGpio<PORTB, PIN1> Pin_ON;
TGpio<PORTA, PIN12> Pin_PVG;
TFan *Fan;
TTherm *Therm;
int16_t Temp;
bool Out;
char ProtSt;
char CvCcSt;
char CvCcPre;
void Protection(void);
void Supervisor(void);
void CvCcControl(void);
void ThermalControl(void);
void OffTimer(void);
TSoftTimer *CCTimer;
TSoftTimer *CVTimer;
TSoftTimer *OvpTimer;
TSoftTimer *OcpTimer;
TSoftTimer *OppTimer;
TSoftTimer *OutBlinkTimer;
public:
TAnalog(void);
TParamList *CalibData;
TAdc<ADC_CH_V, ADC_PIN_V> *AdcV;
TAdc<ADC_CH_I, ADC_PIN_I> *AdcI;
TDac<DAC_CH_V> *DacV;
TDac<DAC_CH_I> *DacI;
void TrimParamsLimits(void);
void Execute(void);
void CalibAll(void);
void CalibDacV(void);
void CalibDacI(void);
void CalibAdcV(char p = CAL_STR);
void CalibAdcI(char p = CAL_STR);
uint16_t DP_Code;
uint16_t OffTime;
void OutControl(bool on);
bool OutState(void);
char GetProtSt(void);
void ClrProtSt(void);
char GetCvCcSt(void);
bool IsCV(void);
bool IsCC(void);
bool TempUpdate;
int16_t GetTemp(void);
char GetSpeed(void);
};
//----------------------------------------------------------------------------
extern TAnalog *Analog;
//----------------------------------------------------------------------------
#endif