EmbeddedRelated.com
Forums

Timer code help

Started by Hithesh March 20, 2011
Hi group,

I am trying to write my first timer code on the ez430F2013 USB board using
IAR kickstart.

The timer is Timer_A
Clock input is VLO
No division.
Timer is configured to count UP, upto 32768-1
When I load the code, LED lights up, but doesn't toggle.
Any help?
#include "msp430.h"

int main(void)
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
BCSCTL3 |= LFXT1S_2; // ACLK routed from VLO
TACTL = TASSEL_1 + MC_1 + TACLR ; // ACLCK, upmode to TCCR0
value, Timer_A Clear
TACCTL0 = CCIE; // TACCR0 interrupt enabled
TACCR0 = 32768-1;
P1DIR |= 0x01; // Set P1.0 to output direction
P1OUT ^= 0x01; // Toggle P1.0
}

// Timer A0 interrupt service routine
#pragma vector=TIMERA0_VECTOR
__interrupt void Timer_A (void)

{
P1OUT ^= 0x01; // Toggle P1.0
TACCR0 = 32768-1; // reset TACCR0 register

}


Beginning Microcontrollers with the MSP430

On Sun, 20 Mar 2011 22:33:49 +0530, you wrote:

>Hi group,
>
>I am trying to write my first timer code on the ez430F2013 USB board using
>IAR kickstart.
>
>The timer is Timer_A
>Clock input is VLO
>No division.
>Timer is configured to count UP, upto 32768-1
>When I load the code, LED lights up, but doesn't toggle.
>Any help?
>#include "msp430.h"
>
>int main(void)
>{
> WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
> BCSCTL3 |= LFXT1S_2; // ACLK routed from VLO
> TACTL = TASSEL_1 + MC_1 + TACLR ; // ACLCK, upmode to TCCR0
>value, Timer_A Clear
> TACCTL0 = CCIE; // TACCR0 interrupt enabled
> TACCR0 = 32768-1;
> P1DIR |= 0x01; // Set P1.0 to output direction
> P1OUT ^= 0x01; // Toggle P1.0
>}
> // Timer A0 interrupt service routine
> #pragma vector=TIMERA0_VECTOR
> __interrupt void Timer_A (void)
> {
> P1OUT ^= 0x01; // Toggle P1.0
> TACCR0 = 32768-1; // reset TACCR0 register
> }

You may wish to consider the idea of enabling interrupt
events by using this function call:

__enable_interrupt( );

Also, you probably do NOT want your main() function to exit.
So either the use of a for(;;); type statement at the end or
else entering low power mode, this way:

__low_power_mode_0( );

Finally, and I admit it has been long enough for me to
forget, but I don't recall that you need to reload TACCR0 in
the interrupt function in up-mode.

Jon
Jon,

Enabling the interrupt worked.

Yes, you are right. I don't have to reload the TACCR0.

Thanks
-Hithesh

On Sun, Mar 20, 2011 at 11:16 PM, Jon Kirwan wrote:

> On Sun, 20 Mar 2011 22:33:49 +0530, you wrote:
>
> >Hi group,
> >
> >I am trying to write my first timer code on the ez430F2013 USB board using
> >IAR kickstart.
> >
> >The timer is Timer_A
> >Clock input is VLO
> >No division.
> >Timer is configured to count UP, upto 32768-1
> >When I load the code, LED lights up, but doesn't toggle.
> >Any help?
> >
> >
> >#include "msp430.h"
> >
> >int main(void)
> >{
> > WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
> > BCSCTL3 |= LFXT1S_2; // ACLK routed from VLO
> > TACTL = TASSEL_1 + MC_1 + TACLR ; // ACLCK, upmode to TCCR0
> >value, Timer_A Clear
> > TACCTL0 = CCIE; // TACCR0 interrupt enabled
> > TACCR0 = 32768-1;
> > P1DIR |= 0x01; // Set P1.0 to output direction
> > P1OUT ^= 0x01; // Toggle P1.0
> >}
> > // Timer A0 interrupt service routine
> > #pragma vector=TIMERA0_VECTOR
> > __interrupt void Timer_A (void)
> > {
> > P1OUT ^= 0x01; // Toggle P1.0
> > TACCR0 = 32768-1; // reset TACCR0 register
> > }
>
> You may wish to consider the idea of enabling interrupt
> events by using this function call:
>
> __enable_interrupt( );
>
> Also, you probably do NOT want your main() function to exit.
> So either the use of a for(;;); type statement at the end or
> else entering low power mode, this way:
>
> __low_power_mode_0( );
>
> Finally, and I admit it has been long enough for me to
> forget, but I don't recall that you need to reload TACCR0 in
> the interrupt function in up-mode.
>
> Jon
>
>


Jon,

One more question - How do I use the IDx timer divier bits.

I tried ID_4. But didn't work.

-Hithesh

On Sun, Mar 20, 2011 at 11:16 PM, Jon Kirwan wrote:

> On Sun, 20 Mar 2011 22:33:49 +0530, you wrote:
>
> >Hi group,
> >
> >I am trying to write my first timer code on the ez430F2013 USB board using
> >IAR kickstart.
> >
> >The timer is Timer_A
> >Clock input is VLO
> >No division.
> >Timer is configured to count UP, upto 32768-1
> >When I load the code, LED lights up, but doesn't toggle.
> >Any help?
> >
> >
> >#include "msp430.h"
> >
> >int main(void)
> >{
> > WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
> > BCSCTL3 |= LFXT1S_2; // ACLK routed from VLO
> > TACTL = TASSEL_1 + MC_1 + TACLR ; // ACLCK, upmode to TCCR0
> >value, Timer_A Clear
> > TACCTL0 = CCIE; // TACCR0 interrupt enabled
> > TACCR0 = 32768-1;
> > P1DIR |= 0x01; // Set P1.0 to output direction
> > P1OUT ^= 0x01; // Toggle P1.0
> >}
> > // Timer A0 interrupt service routine
> > #pragma vector=TIMERA0_VECTOR
> > __interrupt void Timer_A (void)
> > {
> > P1OUT ^= 0x01; // Toggle P1.0
> > TACCR0 = 32768-1; // reset TACCR0 register
> > }
>
> You may wish to consider the idea of enabling interrupt
> events by using this function call:
>
> __enable_interrupt( );
>
> Also, you probably do NOT want your main() function to exit.
> So either the use of a for(;;); type statement at the end or
> else entering low power mode, this way:
>
> __low_power_mode_0( );
>
> Finally, and I admit it has been long enough for me to
> forget, but I don't recall that you need to reload TACCR0 in
> the interrupt function in up-mode.
>
> Jon
>
>


On Mon, 21 Mar 2011 00:15:00 +0530, you wrote:

>One more question - How do I use the IDx timer divier bits.
>
>I tried ID_4. But didn't work.

You don't really describe what "didn't work" means. What did
you do, what did you observe? Also, I didn't know there was
an ID_4. The usual ones are:

#define ID_0 (0*0x40u) /* /1 */
#define ID_1 (1*0x40u) /* /2 */
#define ID_2 (2*0x40u) /* /4 */
#define ID_3 (3*0x40u) /* /8 */

Which spells them all out, so far as I'm aware. You've only
got two bits in the IDx field, so four symbols total. Maybe
you are thinking of the /1, /2, /4, and /8 in the docs. But
the above shows you which is which. You just need to realize
that the ID_x #define uses 0, 1, 2, and 3, for /1, /2, /4,
and /8 shown in the doc. It's not hard to understand, once
your mind is wrapped around the fact that this is a 2-bit
field that can only take on the values of 00, 01, 10, and 11,
which are the binary equivalent of 0, 1, 2, and 3.

Also, I usually set up the IDx field at the same time I also
use MC_0 to stop the clock and use TACLR. These two are the
first thing I do before setting anything else, usually.
Something like this:

TACTL= MC_0 | TASSEL_2 | ID_3 | TACLR;

Then I do things like set TACCTL0 and the TACCR0 values.

Then after that I go back and modify TACTL (or just set it)
with MC_1 (or whatever) and the rest. So the last thing I
do, assuming the above setting, might look like:

TACTL= MC_1 | TASSEL_2 | ID_3;

Then it is running. Might be a good time, either right
before or right afterwards, to use:

__enable_interrupt( );

Jon