This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430FR2676: 10 ms timer interrupt using 32768 Hz Clock

Part Number: MSP430FR2676

Hello,

I am working on a project that is very low power, but needs a fairly accurate 10ms timer interrupt. Most of the micro controller's time will be spend in low power mode 3, but this system timer still fires each 10ms and increments a variable to track relative time.

I am using timer A with an external 32.768 KHz clock source divided by 1.

The compare value I am using is 328, which is actually generates a 10.009765625 ms interrupt instead of 10.0 ms. This slight difference in accuracy due to resolution of the timer is causing a stackup of "drift" from actual run time.

Is there a better way to achieve a 10.0 ms system interrupt  or system runtime tracker without sacrificing low current consumption that I am able to achieve with the 32.768kHz clock?

  • It doesn't sound like you really need a 10ms interrupt. If the ISR does more than increment a variable it could result in a lot of time in high power mode.

    I can think of a couple of ways to get higher accuracy.

    Run a slower interrupt and when you need a time value, read the current timer count and combine that with your counter. (Taking care so that interrupts don't cause trouble.)

    Or have the ISR add a fixed point value to a longer counter. The fractional bits let you adjust for clock errors.

  • In Up mode, you should set CCR0=(period-1), in this case 328-1, since it counts 0 as well. [Ref UG (SLAU445I) Fig 13-3]. As it is, you're actually counting (328+1)/32768=10.04ms.

    In addition to David's suggestions, you could

    3) Use a different time base, like 15.625ms. This would be easy for the code, but probably hard for the humans.

    4) Add (or subtract) a "leap-tick" every so many cycles. You'd have to do the arithmetic, but the code could be pretty simple. If you wanted to go off the deep-end, you could adjust the CCR0 value up/down on every cycle, creating a dither/jitter effect computed to average out over, say, 1 second. (This is how the USCI and the F2 BCS clock modulators work.)

  • "Is there a better way to achieve a 10.0 ms system interrupt  or system runtime tracker without sacrificing low current consumption that I am able to achieve with the 32.768kHz clock?"

    not if you sacrifice something.

    Here is one way to do it, using the compare module:

    1. set up the timer to run freely;

    2. set up a compare module that it triggers an isr 328 ticks from now.

    in the isr:

    1. advance the timer 328 ticks from now.

    2. accumulate a software counter by 32800;

    3. if that counter is more than 32768, subtrack 32768 from it and do something.

    in the long run, that "something" will be done at 10ms interval accurately; from cycle to cycle, however, you will experience jitter.

  • essentially, what happens here is that errors from individual cycles, 328 ticks vs. 327.68 ticks, is accumulated and once enough of such errors have occurred, you true up. As such, the timing is long-term accurate but short-term inaccurate.

  • Audrey:

    I want to elaborate on what James and David had said.

    Keep this in mind. 32,768 Hz is a very low frequency for carrying out a sequence of instructions within 10ms. If you need the accuracy, use the external oscillator for a timing trigger, but if needed, consider using an internal oscillator for driving the main clock at a higher frequency to carry out the instructions. And when I mean an instruction, I mean a single instruction which has been complied and loaded into memory. You must take into account the number of clock cycles needed to execute a single instruction within 10 ms.

    Also keep this in mind. Higher frequencies consume more energy.

    The section named "MSP430 Instruction Execution" of the user guide for this microcontroller tells us how many cycles is needed to execute a single instruction. It ranges from 3 to 6 cycles, depending on the type of instruction. And that does not include the 6 cycles needed by the CPU interruption system to load an interrupt service routine.

    To count the cycles, load (debug mode) your program into the microcontroller, then from the View menu, select Disassembly to view the code window, and from the Run menu, select Clock to view the clock (it'll appear at the lower right corner of the main window). When you step through your program, you can count the number of cycles needed to execute your instructions. Knowing the number of cycles needed then gives us the amount of time needed to execute the routine.

    For instructions which need 6 cycles to execute, and using a clock frequency of 32768 Hz, the processor will be able to execute 5.4 instructions in 10 milliseconds:

     (1 Instruction)/(6 cycles)*(32768 cycles)/(1 sec)*(.001 sec)/1 = 5.4 Instructions

    For instructions which need 3 cycles to execute, and using a clock frequency of 32768 Hz, the processor will be able to execute 10.9 instructions in 10 milliseconds:

    (1 Instruction)/(3 cycles)*(32768 cycles)/(1 sec)*(.001 sec)/1 = 10.9 Instructions

    When we reduce the clock frequency, we reduce the number of instructions executed per 10 ms.

    Good luck in your endeavor.

    -Thomas

  • Be aware that I had edited my last post to remove some errors.

**Attention** This is a public forum