// This routine measures the transducer damping at the specified frequency (PLLfreq).
// The system timer is used to measure when the LPF output (LPFD) has dropped to 1/2 the peak value.
// This is the settling time that will be used later when doing the frequency sweep.
unsigned damping_half_time (unsigned PLLfreq, unsigned pulse_width)
{
unsigned short i;
unsigned short peak = 0;
unsigned short half_peak = 0;
unsigned short temp = 0;
SCNT_bit.STIME = 0; // Make sure system timer is off.
STIM = 0; // Clear the system timer.
SCNT_bit.STDIV = 4; // Set system timer prescale divider to 16 (1µs per cycle).
PLLF_bit.PLLF = PLLfreq; // Set the PLL frequency.
BPH = pulse_width; // Pulse width = BPH/(receive frequency * 400) when BDIV = 0xC.
usWaitTimer2(10000); // Let the PLL settle for 10ms.
SCNT_bit.STIME = 1; // Start the system timer.
BPH_bit .BSTT = 1; // Send a burst.
usWaitTimer2(50); // Wait for LPF to partially settle.
RunTimer0_us(20); // Start timer # 1 with a reload time of every 20µs.
for (i = 0; i < 200; i++)
{
temp = LPFD; // Read the output of the lowpass filter.
if (temp > 0x2000 && temp > peak) {peak = temp;} // Save the peak value if it is greater than 2000.
if (temp < peak/2 && half_peak == 0) // If LPFD is less than half the peak value and the half peak time
{ // has not been set, then
half_peak = STIM; // save the time it took to reach half the peak value.
i = 101; // Half peak found so exit the loop.
}
while (T2CNB0_bit.TF2 == 0) {} // Wait for timer # 0.
T2CNB0_bit.TF2 = 0; // Clear flag.
}
T2CNA0_bit.TR2 = 0; // Stop timer # 0.
return half_peak;
}
void main()
{
unsigned short i = 0;
unsigned short peak = 0;
unsigned short first70 = 0;
unsigned short second70 = 0;
unsigned short center_pllf;
unsigned short wait2measure;
unsigned short halfpeak;
init();
// ***********************************************************************************************************
// ***********************************************************************************************************
// Configuration settings
echo_receive_gain(0); // Set receiver to minimum gain (allowed values 0-31)
Burst_Clock_Divider = 400; // for calculating the burst-frequency in PC-Application.
burst_setup(BURST_CLK_PLL, BURST_PULSE_1, BURST_DIV_400, 0, PLL_CLOCK_16MHZ, 0);
step_size=10; // Sets the step-size (steps go from 0 to 511).
// END configuration settings.
// ***********************************************************************************************************
// ***********************************************************************************************************
while(1)
{
// Use the "damping_half_time" routine to measure the time in µs that it takes for the
// ringing to drop to half of the peak value. Do this at more than one frequency so that
// one of the frequencies will be within range of the transducer.
wait2measure = damping_half_time(128, 88); //Measure damping time at 35kHz.
halfpeak = damping_half_time(256, 101); //Measure damping time at 40kHz.
if (wait2measure < halfpeak) {wait2measure = halfpeak;} // Save the longest time.
halfpeak = damping_half_time(384, 113); //Measure damping time at 45kHz.
if (wait2measure < halfpeak) {wait2measure = halfpeak;} // Save the longest time.
// Repeatedly pulse the transducer with a constant width pulse while sweeping the receiver
// frequency. Use the half-time value from the damping test (wait2measure) for the interval
// between pulse transmission and reading LPFD (lowpass filter data).
PLLF_bit.PLLF = 0; // Start the sweep at 30kHz.
BPH = 77; // Pulse ~6.3µs. This value is easy to maintain over frequency.
peak = 0;
number_of_steps = 0;
do // Sweep from 30kHz to 50kHz with step_size * 39.062500kHz.
{
usWaitTimer2(5000); // Wait 5ms for the frequency to settle.
STIM = 0; // Reset the system timer. It controls the Pulse to LPF read time.
BPH_bit .BSTT = 1; // Send burst.
while(STIM < wait2measure) {} // Wait the specified amount of time for the ringing to dampen.
lpfdata[number_of_steps]= LPFD; // Store the LPF reading.
if(lpfdata[number_of_steps]> peak) {peak = lpfdata[number_of_steps];} //Save the peak value.
number_of_steps++;
PLLF_bit.PLLF = number_of_steps * step_size; // Increase the frequency.
BPH = 77 + number_of_steps; // Increase the duty cycle to maintain pulse width.
} while (PLLF < 512-step_size);
// Find the center frequency based on the average of the two frequencies that have a
// LPFD reading that is 70% of the peak reading.
for (i = 0; i < number_of_steps; i++)
{
if (lpfdata[i] > peak*0.7)
{
first70 = i;
i = number_of_steps;
}
}
for (i = number_of_steps; i >0; i--)
{
if (lpfdata[i] > peak*0.7)
{
second70 = i;
i= 1;
}
}
i = (first70 + second70)/2; // i = the loop value at the center frequency.
center_pllf = i*step_size; // Set PLLF_bit.PLLF to this value for the resonant frequency.
//Remeasure damping using the center frequency.
damp_time = damping_half_time(center_pllf, 75);
// At this point there are three valuable pieces of information about the transducer.
// Peak = the peak value from the frequency sweep.
// center_pllf = the PLLF setting at the resonant frequency.
// damp_time = time for the resonance to decay to 1/2 the peak value.
center_burst_frequency = 16000000/Burst_Clock_Divider*(center_pllf+768)/1024;
SendData();
} // While(1)
} // End Main