AW32: Period Measurement with Timer Capture Mode

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

AW32: Period Measurement with Timer Capture Mode

3,665 Views
BasePointer
Contributor II
Hi,
 
I have a TXCO 36.864Mhz and my MCU uses it as external xtal. The bus frequency is 18.432Mhz.
I also have a high resolution frequency counter, and it says 0.5ppm error for the TXCO.
I want to measure another signal has frequency 0.5Hz with this time base.
I also measured this low frequency signal with my high resolution counter, and it says 1.5ppm error for it.
 
MCU Xtal error: 0.5ppm (I measured this from MCLK pin of MCU, this is nice feature)
Low frequency signal error: 1.5ppm (I measured this directly from MCU pin that is TPM1CH0, the signal on there is clean, has fast rise time and no jitter, so I eliminated hardware errors)
I expect to measure about 1ppm error with my capture routine below.
 
 
Code:
// fBus = 18.432MhzTPM1CNT = 0; // reset timer1TPM1MOD = 0; // no modulo// Input capture, rise-edge, ch0 interrupt enable: PULSE1TPM1C0SC = 0b11000100;// Interrupt enable// Bus frequency// Divider: 1/16TPM1SC = 0b01001100;interrupt VectorNumber_Vtpm1ovf void intTPM1OVF(void){  // tpm1 frequency 1.152Mhz  // overflow occurs at 1.152Mhz / 65536  ++main_timer_overflow_counter;    TPM1SC;    TPM1SC_TOF = 0;}interrupt VectorNumber_Vtpm1ch0 void intTPM1CH0(void){  // PULSE1  previous_capture[0] = last_capture[0]; // save previous pulse    last_capture[0].OverFlowValue = main_timer_overflow_counter;  last_capture[0].CaptureValue = TPM1C0V;  last_capture[0].Initialized = 1;  last_capture[0].Counter++;    TPM1C1SC;  TPM1C0SC_CH0F = 0;}

 
My routine simply works by taking time-stamps of incoming two rise edges and calculate the difference for the period. I'm calculating time-stamp for rise-edges with (main_timer_overflow_counter*65536) + CaptureValue;
 
As the result, I'm measuring 2,304,218 or 2,304,219 for the period. The measured value is stable, this is good for me, but I expect it as 2,304,000. This means I measured 94ppm error instead of 1ppm. and I don't have any idea why it is so. Do you have?
 
Thanks.
Labels (1)
0 Kudos
Reply
7 Replies

790 Views
Ake
Contributor II
Hi,
I looked at your code, but as I  have got no frequency counter, it is a bit difficult to measure.
One thing that I don't understand, why are you using the channel interrupt AND the overflow interrupt?
Another thing is that as the TPMxCnV register was not initallized, it will have 0x0000 as the interrupt value. The same value is for the overflow interrupt. So those two interrupts must be coming very close to each other.
I would only use the overflow interrupt.
 
But as I have no frequency counter, I can't measure the output frequency.
 
Regards,
Ake
0 Kudos
Reply

790 Views
BasePointer
Contributor II
Hi Ake,
 
I'm using TPMxCnV to capture the time of the coming rise edge of an external signal. With this way, I can measure the period of the signal.
 
From AW32 Datasheet / Chapter 10 Timer/PWM (S08TPMV2):
----------------------------------------------------------------------------------------------
10.5.2.1 Input Capture Mode
With the input capture function, the TPM can capture the time at which an external event occurs.
----------------------------------------------------------------------------------------------
 
I need the channel interrupt to know capture value, and using timer interrupt to control overflows. I don't know about initializing TPMxCnV.
 
Thanks.
0 Kudos
Reply

790 Views
bigmac
Specialist III
Hello BP,
 
I cannot explain why you are getting an error of about 200 TPM cycles.  I can see one potentially intermittent problem with your code, but this would produce an error of 66636 TPM cycles, should it occur.
 
The problem would occur only if the capture value should ever be zero (this assumes that  the overflow interrupt occurs when the counter is zero).  When both interrupts are simultaneously generated, the capture interrupt will take precedence.  Therefore, the overflow counter may not have been updated when the capture value is read.
 
The simplest way to compensate for this possibility - if the capture value is zero, increment the stored overflow counter value (but do not increment the actual overflow counter since this would be updated immediately the channel ISR completes).
 
Alternatively, if it happens that the overflow interrupt occurs when the counter value is 65535 (I don't know), this problem might not occur.
 
I seem to recall an application note that covered input capture issues for HC908 TIM module.  I suspect it is quite probable that the TPM module will behave slightly differently in the timer overflow department.
 
I'm not sure if it will achieve anything for your error problem, but you might try reducing the TPM modulo value somewhat, perhaps a decimal value of 57599, and see whether the measurement discrepancy alters.  With this value, you should get exactly 40 overflows for your 0.5 Hz signal.
 
Regards,
Mac
 
0 Kudos
Reply

790 Views
BasePointer
Contributor II
Hi Mac,
 
I see your point, channel interrupts has higher priority than the overflow. I modified ISR like below:
 
Code:
interrupt VectorNumber_Vtpm1ch0 void intTPM1CH0(void){  // PULSE1  ...    last_capture[0].OverFlowValue = main_timer_overflow_counter;  if(TPM1SC_TOF) last_capture[0].OverFlowValue++; // <------- added    last_capture[0].CaptureValue = TPM1C0V;  ...}

 
I have two devices currently working on. One of them is a metering application and uses LC60. This application needs accurate RTC (0.5sec/day). So I need to calibrate its low power crystal. To able to do this, I designed a calibrator with AW32. The scenario is simple, I will generate a signal that has period 2.000000sec at LC60 side(output-compare) and measure it at AW32 side(input-capture). I found my problem(94ppm) at LC60 side, the measurement unit (AW32) works well.
 
I have 16,384 Hz bus frequency at LC60 side and need to generate two rise-edges have time 2sec between them. If I set "TPM1MOD = TPM1C0V = 16384", this gives 94 ppm error. If I set 16383, it gives about 30ppm error. I don't know why.
 
I re-wrote my pulse generation routine at LC60 side by changing only TPM1C0V, this generated acurate 2 sec pulses and AW32 measured them perfectly.
 
 
Code:
    /* Take the bus frequency directly from the external */    ICGC2 = 8; // Generate a reset request on loss of clock.    ICGC1 = 0b00110100;   // FBE mode, fbus=16,384 Hz, clock monitor enabled    TPM1SC = 0; // disable timer    TPM1MOD = 0;    TPM1CNT = 0;    TPM1C0V = 512; // tpm1 counter, first toogle time         TPM1C0SC = 0b00010100; // toggle at compare mode    TPM1SC = 0b00001000; // fbus, 1/1    while(!TPM1C0SC_CH0F) __RESET_WATCHDOG(); // first toogle time - 1        TPM1C0V += 1536;    tmp = TPM1C0SC; TPM1C0SC_CH0F = 0;        while(!TPM1C0SC_CH0F) __RESET_WATCHDOG(); // second toogle time - 0        TPM1C0V += (32768-1536);    tmp = TPM1C0SC; TPM1C0SC_CH0F = 0;        while(!TPM1C0SC_CH0F) __RESET_WATCHDOG(); // third toogle time - 1        TPM1C0V += 1536;    tmp = TPM1C0SC; TPM1C0SC_CH0F = 0;        while(!TPM1C0SC_CH0F) __RESET_WATCHDOG(); // fourth toogle time - 0        TPM1SC = 0; // disable timer            asm("dcb 0x8D"); // reset the mcu

 
 
Thanks for your helps.
 
 
 
 
0 Kudos
Reply

790 Views
bigmac
Specialist III
Hello BP,
 

BasePointer wrote:

I have 16,384 Hz bus frequency at LC60 side and need to generate two rise-edges have time 2sec between them. If I set "TPM1MOD = TPM1C0V = 16384", this gives 94 ppm error. If I set 16383, it gives about 30ppm error. I don't know why.

For an overflow period of 16384 TPM cycles, the correct setting for TPM1MOD should be 16383 (one less than the overflow period required, since an additional cycle period will elapse before the counter is zeroed).  The TPM1C0V register may contain any value, 16383 or less.  A difference of one cycle period does amount to about 61 ppm, as you have measured.
 
Will you be able to maintain the required accuracy (5 ppm per day) over temperature, and allowing for aging of the crystal?  My understanding is that low frequency crystals have a degraded temperature specification, compared with high frequency AT-cut crystals.  When used within a watch, the human body tends to regulate the temperature of the crystal.
 

BasePointer wrote:
interrupt VectorNumber_Vtpm1ch0 void intTPM1CH0(void){  // PULSE1  ...    last_capture[0].OverFlowValue = main_timer_overflow_counter;  if(TPM1SC_TOF) last_capture[0].OverFlowValue++; // <------- added    last_capture[0].CaptureValue = TPM1C0V;  ...}
I have a problem with simply testing the overflow flag.  Since quite a few bus cycles will elapse between the occurrence of the input capture event, and the eventual testing of the flag, if the flag should become set sometime after the input capture event, an erroneous correction would be applied.  I think you will need to test the input capture value, as previously described.
 
Regards,
Mac
 
0 Kudos
Reply

790 Views
BasePointer
Contributor II


bigmac wrote:
 
Will you be able to maintain the required accuracy (5 ppm per day) over temperature, and allowing for aging of the crystal?  My understanding is that low frequency crystals have a degraded temperature specification, compared with high frequency AT-cut crystals.  When used within a watch, the human body tends to regulate the temperature of the crystal.
Hi Mac,
 
I make temperature  compensation for RTC like mentioned TI's application note: http://focus.ti.com/lit/ml/slap107/slap107.pdf
 
It is easy for also LC60.
 
Thanks,
BP.
0 Kudos
Reply

790 Views
ballen
Contributor I
BP,
If you can find a copy, the old 68HC11 Users Manual has a good example of using the overflow for measuring long time intervals. Granted, it's in assembly, but it explains the timing issues pretty well. I've used the method it outlines on more than one occassion in both C and assembly. Just a thought...
BA
0 Kudos
Reply