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; 
 }
}
Velvet
4,9085 gold badges18 silver badges32 bronze badges
asked Sep 15, 2023 at 8:44
\$\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\$ 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\$ 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\$ 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.

answered Sep 16, 2023 at 5:07
\$\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..
}
answered Sep 15, 2023 at 9:34
\$\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;
...
answered Sep 17, 2023 at 11:25
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.