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.

MSP430G2553: Frequency meter code

Part Number: MSP430G2553
Other Parts Discussed in Thread: MSP430WARE

Hi

I'm looking at some code for a frequency counter. I'm still learning but I think the code should be fairly straightforward.

#include <msp430g2553.h>

/*** Global variables ***/
volatile unsigned int CounterValue = 0;
volatile unsigned int StoredCount = 0;
unsigned int Result = 0;

int main(void) {

	/*** Watchdog timer and clock Set-Up ***/
	WDTCTL = WDTPW + WDTHOLD;		// Stop watchdog timer
	BCSCTL1 = CALBC1_8MHZ;  		// Set range
	DCOCTL = CALDCO_8MHZ;   		// Set DCO step + modulation
	
	/*** GPIO Set-Up ***/
	P2DIR &= ~BIT0;				// P2.0 set as input
	P2SEL |= BIT0;				// P2.0 set to primary peripheral Timer1_A

	/*** Timer_A Set-Up ***/
	TA0CCR0 = 20000;			// 20000*400 = 8000000 or 8MHz
	TA0CCTL0 |= CCIE;			// Interrupt enable
	TA0CTL |= TASSEL_2;			// SMCLK

	TA1CCTL0 |= CCIE + CCIS_0 + CM_2 + CAP;	// Interrupt enable, capture select CCIxA, Positive edge, capture mode
	TA1CTL |= TASSEL_2;						// SMCLK

	_BIS_SR(GIE);				// Enter LPM0 with interrupts enabled

	while(1)
	{

	TA0CTL |= MC0;				// Start timer
	TA1CTL |= MC1;				// Start timer
	while(CounterValue != 400);	// Wait while CounterValue is not equal to 400
	TA0CTL &= ~MC0;				// Stop timer
	TA1CTL &= ~MC1;				// Stop timer
	Result = StoredCount;		// Store frequency in Result
	CounterValue = 0;			// Zero CounterValue
	StoredCount = 0;			// Zero StoredCount
	TA0R = 0;					// Zero Timer_A0 register
	TA1R = 0;					// Zero Timer_A1 register
	}
}

//Timer_A0 TACCR0 Interrupt Vector Handler Routine
#pragma vector=TIMER0_A0_VECTOR
__interrupt void Timer0_A0(void)
{
	CounterValue++;
}

//Timer_A1 TACCR0 Interrupt Vector Handler Routine
#pragma vector=TIMER1_A0_VECTOR
__interrupt void Timer1_A0(void)
{
	StoredCount++;
}

I have two questions:

1) How come TA0CCR0 is set to the decimal value of 20000? What's the significance of 20000?

2) How come the routine waits for CounterValue to reach 400? My understanding is that CounterValue is incremented for each positive edge. Why does it need to wait for 400 positive edges?

Any thought appreciated.

  • Hi Will,

    My answer to both your questions unfortunately is, I'm not sure.

    By loading 20000 into TA0CCR0 it is setting the value that TA0 counts up to. When TA0 counts to this value, the TA0CCR0 interrupt triggers incrementing CounterValue. Then once CounterValue > 400 the code in the while loop can execute again. This makes an ~8MHz frequency for the while loop. During the time that CounterValue is being incremented, TA1 is incrementing StroredCount every time a positive edge is seen.

    So the StoredCount would be the number of positive edges seen in an 8MHz time span.

    There is a TI provided example for how to measure the period and duty cycle of a signal in MSP430Ware that I recommend you check out. This would be the msp430g2xx3_ta_21.c example.

    Best regards,
    Caleb Overbay
  • Will Kleinberg said:
    What's the significance of 20000?

    If you multiply it by 400, result is 8000000 or 8MHz (hint: read the comment).

    Will Kleinberg said:
    Why does it need to wait for 400 positive edges?

    Who knows :) Perhaps only original author. Honestly this code is not the best way to implement frequency counter. You shall check this 43oh project and also search msp430 forum here for keywords.

  • But why is this 8mHz. How is it guaranteed that TA0 takes 1/400 second to count to 20000?
  • > If you multiply it by 400, result is 8000000 or 8MHz (hint: read the comment).

    For it to be 8MHz, each increment of CounterValue must take 1/20000th second. Does loading 5000 into TA0CCR0 make each interrupt trigger every 1/5000th second? If so, for the purpose of the original code, could TA0CCR0 have been loaded with 5000, or even 1000?
  • Will Kleinberg said:
    But why is this 8mHz

    Because DCO and timer is running at 8MHz!

        BCSCTL1 = CALBC1_8MHZ;          // Set range
        DCOCTL = CALDCO_8MHZ;           // Set DCO step + modulation

**Attention** This is a public forum