3
\$\begingroup\$

I am using a MC9S08LH64 microcontroller's timer module to generate an internal timer for synchronization. bus clock is at 4.3 MHz, modulo is set at 4309 (TPM1MODH and TPM1MODL) and I am expecting pulse every 1.25 ms but the result is about every 3.75ms. Is there any setting I am missing here? Thank you very much

From the reference manual:

/*
 * TPM1SC: pg 358
   bit 
    7   TOF need to check for this flag
    6       not used since no interrupt being used
    5   1  not used
    4   0  selecting bus clock
    3   1
    2   0  not dividing clock down
    1   0
    0   0
  */ 

TPM1SC = 0x08;

*Update: I have just realized that changing the TPM1MOD has no effect on the result pulse width. TPM1SC is the only register I used to set up the module. Is there any other register I need to set up for this?

Here are the source code to set up the timer:

//to set up the modulo register:
void set_base_pulse(float time_ms)
{
  int modulo_value;
  modulo_value = (int) time_ms*1000/233;
  TPM1MODH = modulo_value >>8;
  TPM1MODL = modulo_value;
}

to generate the pulses, I checked the TOF flag, every 40 times the flag goes off, I toggle the output:

for (counter = 0; counter<40; counter++) {
  while (!TPM1SC_TOF) {}
  if (counter == 39) output ~= output;
}
\$\endgroup\$
  • \$\begingroup\$ I don't see how that last for() loop can work. "counter" never equals 40 inside the body of the loop; it only has that value after the loop exits. \$\endgroup\$ – Dave Tweed Sep 10 '12 at 21:05
  • \$\begingroup\$ sorry, it was 39, not 40 \$\endgroup\$ – user1604121 Sep 10 '12 at 21:21
1
\$\begingroup\$

I can't get the math to work out to either 1.25 ms or 3.75 ms.

If your TPM is using the bus clock and the bus clock is at 4.3 MHz then each tick is:

$$\frac{1}{4.3\times10^6} = 232.56\,\mathrm{ns}$$

If you have modulo_value set to 4309 (decimal), then a rollover occurs every:

$$232.56\,\mathrm{ns}\times4309 = 1\,\mathrm{ms}$$

So if you're checking for 40 occurrences of TPM1SC_TOF, then output should toggle every 40 ms.

If you have modulo_value set to 4309 (hexadecimal), then a rollover occurs every:

$$232.56\,\mathrm{ns}\times17,161 = 3.99\,\mathrm{ms}$$

In which case output should toggle every 159.64 ms.

Try using the debugger to see what TPM1MODH and TPM1MODL are actually being set to. Determine the proper radix (probably hexadecimal in the debugger) and use the calculations above to see if you can get the numbers to work out to what you're seeing.

Also of note from page 357 of the Reference Manual:

Clear TOF by reading the TPM status and control register when TOF is set and then writing a logic 0 to TOF. If another TPM overflow occurs before the clearing sequence is completed, the sequence is reset so TOF remains set after the clear sequence was completed for the earlier TOF.

Which you are not doing in your loop.

\$\endgroup\$
0
\$\begingroup\$

I don't use Freescale uCs, but if it's set up as a free running timer you need to set the modulo value on every interrupt, otherwise it will just roll over to 0 and count from there. So your first pulse will be correctly timed and all the rest will be the full count.

Try setting your TPM1MOD registers in the interrupt routine. Let us know how it goes.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.