Dear TI,
i was going through the firmware provided with slaa577,
and try to understand below lines of code,
In the function ISR(SD24B, adc_interrupt)
can you help understand below
if (abs(V_sample - phase->metrology.last_V_sample) <= phase->metrology.since_last*MAX_PER_SAMPLE_VOLTAGE_SLEW)
{
/* This doesn't look like a spike - do mains cycle detection, and
estimate the precise mains period */
if (V_sample < 0)
{
/* Log the sign of the signal */
phase->status &= ~V_POS;
}
else
{
if (!(phase->status & V_POS))
{
#if defined(MAINS_FREQUENCY_SUPPORT)
/* Apply limits to the sample count, to avoid spikes or dying power lines disturbing the
frequency reading too much */
/* The mains should be <40Hz or >70Hz to fail this test! */
if (256*SAMPLES_PER_10_SECONDS/700 <= phase->metrology.cycle_sample_count && phase->metrology.cycle_sample_count <= 256*SAMPLES_PER_10_SECONDS/400)
{
/* A mains frequency measurement procedure based on interpolating zero crossings,
to get a fast update rate for step changes in the mains frequency */
/* Interpolate the zero crossing by successive approx. */
z = V_sample - phase->metrology.last_V_sample;
x = 0;
y = 0;
for (k = 0; k < 8; k++)
{
y <<= 1;
z >>= 1;
x += z;
if (x > V_sample)
x -= z;
else
y |= 1;
}
/* Now we need to allow for skipped samples, due to spike detection */
z = y;
while (phase->metrology.since_last > 1)
{
z += y;
phase->metrology.since_last--;
}
/* z is now the fraction of a sample interval between the zero
crossing and the current sample, in units of 1/256 of a sample */
/* A lightly damped filter should now be enough to remove noise and get a
stable value for the frequency */
phase->metrology.mains_period += ((int32_t) (phase->metrology.cycle_sample_count - z) << 12) - (phase->metrology.mains_period >> 4);
/* Start the next cycle with the residual fraction of a sample */
phase->metrology.cycle_sample_count = z;
}
else
{
phase->metrology.cycle_sample_count = 0;
}
I need to know how the frequency is calculated in this routine, specifically what these below lines of code doing
z = V_sample - phase->metrology.last_V_sample;
x = 0;
y = 0;
for (k = 0; k < 8; k++)
{
y <<= 1;
z >>= 1;
x += z;
if (x > V_sample)
x -= z;
else
y |= 1;
}
can you pls, help to explain
regards