0
\$\begingroup\$

Need help with this code, it is not creating any delay.
I tried simulating this code in Proteus.

#include <msp430.h> 
#include <stdio.h>
#include <stdlib.h>

void XTL_ini();
void TimerA_ini();
void delay();

int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer
    XTL_ini();
    TimerA_ini();
    P1DIR=0XFF;
    P2DIR=0XFF;
    while(1)
    {
        P1OUT=BIT0;
        delay();
    }
}

void XTL_ini()
{
    volatile int i=0;
    BCSCTL1|=XT2OFF;
    BCSCTL1&=~XTS;
    BCSCTL3|=LFXT1S_0;
    do{
        IFG1&=~OFIFG;
        for(i=5000;i;i--);
    }while(IFG1 & OFIFG);
    BCSCTL2|=SELM_3;
}

void TimerA_ini()
{
    TA0CTL|=TASSEL_1;          //32768
    TA0CTL|=(ID_3+TAIE);       //4096
}

void delay()
{
    TA0CTL|=MC_1;
    TA0CTL|=TACLR;
    TA0CTL&=~TAIFG;
    TA0CCR0=4.096;
    if(TA0CTL&TAIFG)
    {
       TA0CTL|=MC_0;
       TA0CTL|=TACLR;
       TA0CTL&=~TAIFG;       
    }
}
\$\endgroup\$
4
  • \$\begingroup\$ Not familiar with this MCU so I don't know its timer registers. But what in this code did you expect would cause a delay? For the delay() function to provide any sort of delay, It should at least contain a loop (while, for). \$\endgroup\$
    – Klas-Kenny
    Commented Sep 15, 2023 at 9:11
  • \$\begingroup\$ I want a delay using timer but with no interrupt i want to use a loop or in other words want to halt the msp430 till the TAR value matches the TACCRO value entered , because when i code in css it recommends to use timer delay instead of _delay_cycles function. \$\endgroup\$
    – SlickDaDDy
    Commented Sep 15, 2023 at 9:58
  • \$\begingroup\$ The compiler will warn you not to use the _delay_cycles function (which is actually a macro of fixed loops). But, if you don't care about saving power, and the processor has nothing else to do during the delay, just ignore the warning. \$\endgroup\$
    – Mattman944
    Commented Sep 16, 2023 at 10:18
  • \$\begingroup\$ @SlickDaDDy Are you still having troubles? The code I wrote is tested here on the indicated F2013 MCU and where P1.0 is hooked up to the LED. Just wondering. \$\endgroup\$ Commented Sep 22, 2023 at 18:21

3 Answers 3

2
\$\begingroup\$

Blink rate should be once per second with the following code. Easy to see. If you want to adjust it to run more often, change the "50" in the for-loop. This does NOT use interrupts, which I gather you do not want. No library code is called. Everything is below. (It's set for the MSP430F2013.)

/*
TIMER A2 DETAILS

It's probably best to include a diagram of how Timer A2 is being used.
The upper diagram helps show the timer counter's upward motion, over
time.  The line made with text, showing peaks and valleys, represents
the timer counter, itself, as it counts upwards.  The timer automatically
starts counting upwards when the counter reaches zero and automatically
resets back to zero when the counter reaches a value that is set into
TACCR0.  In this application, TACCR0 is set just once and isn't adjusted
afterwards.  It sets the basic cycle time for the LED pulsing.

        TACCR0 ----> ..^......^......^......^......^.....
                      /|     /|     /|     /|     /|     /   Upward
                     / |    / |    / |    / |    / |    /    Counter
                    /  |   /  |   /  |   /  |   /  |   /     Diagram
                |  /   |  /   |  /   |  /   |  /   |  / 
                | /    | /    | /    | /    | /    | /   
                |/     |/     |/     |/     |/     |/     
        ZERO ...v......v......v......v......v......v.....

            ----|------|------|------|------|------|---
                T      T      T      T      T      T   
                A      A      A      A      A      A      Event Names
                I      I      I      I      I      I      as Described
                F      F      F      F      F      F      in the User's
                G      G      G      G      G      G      Guide from TI

        time ----> ----> ----> ----> ----> ----> ----> ---->
*/
int main( void ) {
        WDTCTL= WDTPW | WDTHOLD;
        P1DIR |= 0x01;                              // P1.0 is LED
        BCSCTL1= CALBC1_16MHZ;
        DCOCTL= CALDCO_16MHZ;
        TACTL= MC_0 | TASSEL_2 | ID_3 | TACLR;      // reset it, first.
        TACCTL0= CM_0 | CCIS_2 | SCS | OUTMOD_1;    // set the mode.
        TACCR0= 19999;                              // 10ms intervals.
        TACTL= MC_1 | TASSEL_2 | ID_3;              // turn it on.
        for ( ; ; ) {
            P1OUT ^= 0x01;                          // using XOR toggles LED
            for ( int i= 0; i < 50; ++i ) {         // use (50)*10 ms per toggle
                while ( (TACTL & TAIFG) == 0 )      // wait for the flag to set
                    ;
                TACTL &= ~TAIFG;                    // clear the flag now
            }
        }
    return 0;                                       // never reaches this point
}

See if that gets you something useful. But note that the above code does not "halt the msp430". That can be done. But it requires interrupts. And since you also wrote, "I want a delay using timer but with no interrupt i want to use a loop", I decided this is as far as I go for now.

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

I don't fully understand what you mean with "timer with polling condition".

Example 1: macro using a blocking delay

#include <msp430.h>
#include <intrinsics.h>

// here you have to specify the MCLK frequency in MHz
#define HWM_MCLK_FREQ_MHZ_DEF  (16)

#if (HWM_MCLK_FREQ_MHZ_DEF == 1)
# define HWM_DELAY_US(x)            __delay_cycles((uint32_t)(x))
#elif (HWM_MCLK_FREQ_MHZ_DEF == 2)
# define HWM_DELAY_US(x)            __delay_cycles((uint32_t)(x) << 1)
#elif (HWM_MCLK_FREQ_MHZ_DEF == 4)
# define HWM_DELAY_US(x)            __delay_cycles((uint32_t)(x) << 2)
#elif (HWM_MCLK_FREQ_MHZ_DEF == 8)
# define HWM_DELAY_US(x)            __delay_cycles((uint32_t)(x) << 3)
#elif (HWM_MCLK_FREQ_MHZ_DEF == 16)
# define HWM_DELAY_US(x)            __delay_cycles((uint32_t)(x) << 4)
#endif
#define HWM_DELAY_MS(x)             HWM_DELAY_US((x) * 1000UL)

Example 2: using a timer interrupt

// here you have to specify the MCLK frequency in MHz
#define HWM_MCLK_FREQ_MHZ_DEF  (16)

#define TIMER_A_INTERVAL_US    (5000)

#if (HWM_MCLK_FREQ_MHZ_DEF == 1)
# define TIMER_A_CCR0  (TIMER_A_INTERVAL_US >> 3)
#elif (HWM_MCLK_FREQ_MHZ_DEF == 2)
# define TIMER_A_CCR0  (TIMER_A_INTERVAL_US >> 2)
#elif (HWM_MCLK_FREQ_MHZ_DEF == 4)
# define TIMER_A_CCR0  (TIMER_A_INTERVAL_US >> 1)
#elif (HWM_MCLK_FREQ_MHZ_DEF == 8)
# define TIMER_A_CCR0  (TIMER_A_INTERVAL_US)
#elif (HWM_MCLK_FREQ_MHZ_DEF == 16)
# define TIMER_A_CCR0  (TIMER_A_INTERVAL_US << 1)
#endif

void timer_a_init(void)
{
    TA0CCTL0 |= CCIE;
    TA0CTL = MC__STOP;
    TA0CCR0 = TIMER_A_CCR0;
    TA0CTL = TASSEL__SMCLK | MC__UP | ID__8 | TACLR; // clock source = SMCLK, counting mode = up, clock divider = 8
}

void timer_a_start(void)
{
    TA0CCR0 = TIMER_A_CCR0;
    TA0CTL = TASSEL__SMCLK | MC__UP | ID__8 | TACLR; // clock source = SMCLK, counting mode = up, clock divider = 8
}

/**
 * The TimerA0 interrupt fires once every TIMER_A_INTERVAL_US us.
 */
#pragma vector = TIMER0_A0_VECTOR
__interrupt void TIMER0_A0_ISR(void)
{
    // do stuff..
}
\$\endgroup\$
0
\$\begingroup\$
TA0CCR0=4.096;

This sets the register to the value 4. If you want the value 4096, write 4096.

if(TA0CTL&TAIFG)
{
   TA0CTL|=MC_0;
   TA0CTL|=TACLR;
   TA0CTL&=~TAIFG;       
}

This code checks the interrupt bit once, and then continues execution.

If you want to wait for the interrupt bit to be set, you have to implement a wait:

while (!(TA0CTL&TAIFG))
    ;
TA0CTL&=~TAIFG;
...
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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