MSP430 Timer A interrupt flags are wacko

microcontrollermsp430

Trying to setup a timer on my MSP430F5529 that should interrupt after approx. 2 seconds.

My initial setup looks like this:

TA1CTL      = (TASSEL_SMCLK | ID_DIV8 | MC_UP |TACLR | TAIE | TAIFG);
TA1EX0      = (TAIDEX_DIV4);
TA1CCR0     = 0xFFFF;
TA1CCTL1    = (CM_NONE | CCIS_A | CAP_0 | CCIE_1 | OUT_1 | COV_0 | CCIFG_0);

As far as I know, this should setup Timer A to interrupt approx. every 2 seconds.

SMCLK frequency = 1 MHz

TA1CTL is divided by 8 with ID_DIV8, and again by 4 with TAIDEX_DIV4 so in total is divided by 32. This means TA1R gets a tick every 32us. It counts until it reaches TA1CCR0, which is at 65,536. 65,536 * 32us = 2.09715 seconds.

The interrupt is successful, however it incorrectly sets several flags.

It sets CCIFG in TA1CCTL0, TA1CCTL1, and TA1CCTL2. Not just TA1CCTL1, as I expected.

Another question I have is this: Why am I forced to use TA1CCR0 to specify what value gets counted to, when I am using TA1CCTL1? I tried specifying a value in TA1CCR1 initially, but the counter never incremented. This makes no sense at all to me.

So if anyone out there is pretty familiar with the MSP430 and could help, it'd be greatly appreciated.

Best Answer

CCR0 holds the maximum value that the timer counts up to. When the timer reaches this value it resets to zero. Only CCR0 does this. CCR1 and CCR2 can trigger an interrupt when they match the current count, but the timer will keep on going past them. Since CCR0 sets the timer period, it is the obvious choice for generating the periodic interrupt (you could use CCR1 or CCR2, but then you would just have more registers to set up, and they might have other uses).

If CCR1 and CCR2 are set to less than CCR0 then the timer will match them before reaching its maximum count, so when the CCR0 interrupt occurs you will see that the CCR1 and CCR2 interrupt flags have already been set. You can enable just the CCR0 interrupt and ignore the other flags - they won't cause any harm.

TA1CCTL1 contains various bits that are used to configure CCR1. This has no relation to TA1CCR0 - you must still set it to the maximum count you require. If TA1CCR0 is left at zero then the timer won't count!