📄 meter.c
字号:
CE2 |= (EX_XFER | EX_RTC); // enable the interrupts
EX_XFER_RTC = TRUE; // Enable the shared external interrupt
EA = 1;
}
if (IE_XFER)
{
CLR_IE_XFER(); // Just clear the bit.
ce_xfer_busyz_isr ();
CE2 |= (EX_XFER | EX_RTC); // enable the interrupts
EX_XFER_RTC = TRUE; // Enable the shared external interrupt
CE_ENABLE();
EA = 1;
}
// This instantly reverses the command CE0
#if !CLI
if (0 == (CE0 & CE_EN))
{
ce_init ();
CE_ENABLE();
}
#endif
}
#endif
#if PULSE_CNT
pcnt_update (); // update the pulse counts
#endif
meter_lcd (); // output to the LCD
}
// Figure small values of Irms from va or wh
// the VA calculation from sqrt(wh^2 + var^2) uses narrowband
// data and current (Irms) calculated from it has a much lower noise
// floor than the basic irms
#if RMS_VALUES
#if M6520 || TRACE11
#define SMALL_IRMS_THRESHOLD 641776 // corresponds to 0.1A
#elif TRACE13
#define SMALL_IRMS_THRESHOLD 541499 // corresponds to 0.1A
#else
#error unknown device
#endif
#define compute_irms(_irms_, _isqsum_, _wh_, _vrms_) \
if (_isqsum_ < SMALL_IRMS_THRESHOLD) \
_irms_ = lroundf ((((float)(_wh_))*32768.0)/(((float)(_vrms_))/131072.0));
// _irms_ = ((_wh_ << 15)/((_vrms_ + 0x10000L)>>17));
#else // no rms values, so calculate them for creep!
#define compute_irms(_irms_, _isqsum_, _wh_, _vrms_) \
_irms_ = lroundf ((((float)(_wh_))*32768.0)/(((float)(_vrms_))/131072.0));
#endif
// This is essential when working with shunts
static void Compute_Small_Irms (void)
{
#if EQUATION == _1ELEMENT_2WIRE
// PhaseA VA hour computation for computing Irms = VAh / V
va0sum = VAh_WVAR ( &w0sum, &var0sum);
compute_irms(Irms_A, i0sqsum, va0sum, Vrms_A);
// PhaseB VA hour computation for computing Irms = VAh / V
va1sum = VAh_WVAR ( &w1sum, &var1sum);
compute_irms(Irms_B, i1sqsum, va1sum, Vrms_A);
#elif EQUATION == _1ELEMENT_3WIRE
// PhaseA VA hour computation for computing Irms = VAh / V
va0sum = VAh_WVAR ( &w0sum, &var0sum);
compute_irms(Irms_A, i0sqsum, va0sum, Vrms_A);
#elif EQUATION == _2ELEMENT_3WIRE_DELTA
// PhaseA VA hour computation for computing Irms = VAh / V
va0sum = VAh_WVAR ( &w0sum, &var0sum);
compute_irms(Irms_A, i0sqsum, va0sum, Vrms_A);
// PhaseB VA hour computation for computing Irms = VAh / V
va1sum = VAh_WVAR ( &w1sum, &var1sum);
compute_irms(Irms_B, i1sqsum, va1sum, Vrms_B);
#elif EQUATION == _2ELEMENT_4WIRE_DELTA
// PhaseA VA hour computation for computing Irms = VAh / V
va0sum = VAh_WVAR ( &w0sum, &var0sum);
compute_irms(Irms_A, i0sqsum, va0sum, Vrms_A);
// PhaseC VA hour computation for computing Irms = VAh / V
va2sum = VAh_WVAR ( &w2sum, &var2sum);
compute_irms(Irms_C, i2sqsum, va2sum, Vrms_C);
#elif EQUATION == _2ELEMENT_4WIRE_WYE
// PhaseA VA hour computation for computing Irms = VAh / V
va0sum = VAh_WVAR ( &w0sum, &var0sum);
compute_irms(Irms_A, i0sqsum, va0sum, Vrms_A);
// PhaseB VA hour computation for computing Irms = VAh / V
va1sum = VAh_WVAR ( &w1sum, &var1sum);
compute_irms(Irms_B, i1sqsum, va1sum, Vrms_B);
#elif EQUATION == _3ELEMENT_4WIRE_WYE
// PhaseA VA hour computation for computing Irms = VAh / V
va0sum = VAh_WVAR ( &w0sum, &var0sum);
compute_irms(Irms_A, i0sqsum, va0sum, Vrms_A);
// PhaseB VA hour computation for computing Irms = VAh / V
va1sum = VAh_WVAR ( &w1sum, &var1sum);
compute_irms(Irms_B, i1sqsum, va1sum, Vrms_B);
// PhaseC VA hour computation for computing Irms = VAh / V
va2sum = VAh_WVAR ( &w2sum, &var2sum);
compute_irms(Irms_C, i2sqsum, va2sum, Vrms_C);
#else
#error warning, unknown equation
#endif
}
// prevent creep
static void Apply_Creep_Threshold (void)
{
Status &= ~CREEP;
if (0 != IThrshld)
{
// The 6520 implements 1-element_2wire as two independent channels
// connected by a wire between Va and Vb, so, it needs different creep.
#if EQUATION == _1ELEMENT_2WIRE
bool creepA = FALSE, creepB = FALSE;
if (Vrms_A > VThrshld)
{
Status &= ~MINVA; // VA is ok status
if(Irms_A < IThrshld)
creepA = TRUE;
if(Irms_B < IThrshld)
creepB = TRUE;
}
else
{
Status |= MINVA; // VA is bad status
creepA = creepB = TRUE;
Vrms_A = v0sqsum = 0;
}
if (creepA)
{
Irms_A = w0sum = var0sum = i0sqsum = 0;
}
if (creepB)
{
Irms_B = w1sum = var1sum = i1sqsum = 0;
}
// In this equation, the element with the biggest current
// is selected, so both must be clear to get creep
if (creepA && creepB)
{
Status |= CREEP;
#if M6520
memset_ce (&wsum_accum, 0x40000000L);
memset_ce (&vsum_accum, 0x40000000L);
#elif TRACE11
memset_ce (&wsum_accum, 0xC0000000L);
memset_ce (&vsum_accum, 0xC0000000L);
#else
#error unknown device
#endif
}
else
Status &= ~CREEP;
#elif EQUATION == _1ELEMENT_3WIRE
bool creepA = FALSE, creepB = FALSE;
if (Vrms_A > VThrshld)
{
Status &= ~MINVA; // VA is ok status
// Both currents contribute to the calculation
#if M6520
// in the 6520, Irms_A -is- the difference
if( Irms_A < IThrshld )
creepA = TRUE;
#else
if ( (Irms_A - Irms_B) < IThrshld )
creepA = TRUE;
#endif
if(Irms_B < IThrshld)
creepB = TRUE;
}
else
{
Status |= MINVA; // VA is bad status
creepA = creepB = TRUE;
Vrms_A = v0sqsum = 0;
}
if (creepA)
{
Irms_A = w0sum = var0sum = i0sqsum = 0;
}
if (creepB)
{
Irms_B = w1sum = var1sum = i1sqsum = 0;
}
if (creepA)
{
Status |= CREEP;
#if M6520
memset_ce (&wsum_accum, 0x40000000L);
memset_ce (&vsum_accum, 0x40000000L);
#elif TRACE11
memset_ce (&wsum_accum, 0xC0000000L);
memset_ce (&vsum_accum, 0xC0000000L);
#else
#error unknown device
#endif
}
else
Status &= ~CREEP;
#elif EQUATION == _2ELEMENT_3WIRE_DELTA
bool creepA = FALSE, creepB = FALSE;
if (Vrms_A > VThrshld)
{
Status &= ~MINVA;
if(Irms_A < IThrshld)
creepA = TRUE;
}
else
{
Status |= MINVA;
creepA = TRUE;
Vrms_A = v0sqsum = 0;
}
if (Vrms_B > VThrshld)
{
Status &= ~MINVB;
if(Irms_B < IThrshld)
creepB = TRUE;
}
else
{
Status |= MINVB;
creepB = TRUE;
Vrms_B = v1sqsum = 0;
}
if (creepA)
{
Irms_A = w0sum = var0sum = i0sqsum = 0;
}
if (creepB)
{
Irms_B = w1sum = var1sum = i1sqsum = 0;
}
if (creepA && creepB)
{
Status |= CREEP;
#if M6520
memset_ce (&wsum_accum, 0x40000000L);
memset_ce (&vsum_accum, 0x40000000L);
#elif TRACE11
memset_ce (&wsum_accum, 0xC0000000L);
memset_ce (&vsum_accum, 0xC0000000L);
#else
#error unknown device
#endif
}
else
Status &= ~CREEP;
#elif EQUATION == _2ELEMENT_4WIRE_DELTA
bool creepA = FALSE, creepB = FALSE, creepC = FALSE;
if (Vrms_A > VThrshld)
{
Status &= ~MINVA;
if((Irms_A - Irms_B) < IThrshld)
creepA = TRUE;
}
else
{
Status |= MINVA;
creepA = TRUE;
creepB = TRUE;
Vrms_A = v0sqsum = 0;
}
if (Vrms_C > VThrshld)
{
Status &= ~MINVC;
if(Irms_C < IThrshld)
creepC = TRUE;
}
else
{
Status |= MINVC;
creepC = TRUE;
Vrms_C = v2sqsum = 0;
}
if (creepA)
{
Irms_A = w0sum = var0sum = i0sqsum = 0;
}
if (creepB)
{
Irms_B = w1sum = var1sum = i1sqsum = 0;
}
if (creepC)
{
Irms_C = w2sum = var2sum = i2sqsum = 0;
}
if (creepA && creepC)
{
Status |= CREEP;
#if TRACE13
memset_ce (&wsum_accum, 0xC0000000L);
memset_ce (&vsum_accum, 0xC0000000L);
#else
#error unknown device
#endif
}
else
Status &= ~CREEP;
#elif EQUATION == _2ELEMENT_4WIRE_WYE
bool creepA = FALSE, creepB = FALSE, creepC = FALSE;
if (Vrms_A > VThrshld)
{
Status &= ~MINVA;
if( (Irms_A - Irms_B) < IThrshld )
{
creepA = TRUE;
creepB = TRUE;
}
}
else
{
Status |= MINVA;
creepA = TRUE;
creepB = TRUE;
Vrms_A = v0sqsum = 0;
}
if (Vrms_B > VThrshld)
{
Status &= ~MINVB;
if((Irms_B - Irms_C) < IThrshld)
{
creepB = TRUE;
creepC = TRUE;
}
}
else
{
Status |= MINVB;
creepB = TRUE;
creepC = TRUE;
Vrms_B = v1sqsum = 0;
}
if (creepA && creepB)
{
w0sum = var0sum = 0;
}
if (creepB && creepC)
{
w1sum = var1sum = 0;
}
if (creepA)
{
Irms_A = i0sqsum = 0;
}
if (creepB)
{
Irms_B = i1sqsum = 0;
}
if (creepC)
{
Irms_C = i2sqsum = 0;
}
if (creepA && creepB && creepC)
{
Status |= CREEP;
#if TRACE13
memset_ce (&wsum_accum, 0xC0000000L);
memset_ce (&vsum_accum, 0xC0000000L);
#else
#error unknown device
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -