Jump to content
43oh

MSP430G Launchpad Frequency Counter


Recommended Posts

Hi all,

 

After bit of help.  I was inspired by this MSP430F550x frequency meter Jazz made and thought I would code one from scratch, different from the one I posted in the that original thread http://forum.43oh.com/topic/3317-msp430f550x-based-frequency-meter/

 

The one I made works fine but I am having an issue displaying above ~32kHz on the LCD, I know the variable Freq that holds the frequency is correct as viewed this in debug mode.  So it must be my implementation of the itoa function or possibly a casting issue?....this is where my C skills are a bit sketchy!

 

The video shows the frequency counter in operation and it uses an early iteration of RobG's EduKit BoosterPack.  It doesn't show what happens above 30kHz, however a negative value is displayed or one which is completely incorrect.

 

https://www.youtube.com/watch?v=Ene1dIvGBBo

 

The itoa function is attached as well but I doubt this is at fault, not one I have coded but I have used it before successfully.

#include "msp430.h"
#include "edukit.h"
#include "itoa.h"

/*** Constants ***/
const int NumberSamples = 4;

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

/*** Function prototype ***/
void calc_freq();

void main(void) {

	/*** System Set-Up ***/
	WDTCTL = WDTPW + WDTHOLD; // disable WDT
	initMSP430(); // init MSP430's clock
	BCSCTL3 |= LFXT1S_2;  // VLO mode
	_delay_cycles(16000000); // wait for LCD to reset
	setUpSPIforLCD(SPI2, CA, DA); // set up LCD's SPI
	initLCD(); // init LCD

	clearScreen(COLOR_BLACK);

	/*** GPIO Set-Up ***/
	P2DIR &= ~BIT0;			// P2.0 set as input
	P2SEL |= BIT0;			// P2.0 set to primary peripheral Timer1_A
	P1DIR |= BIT4;			// Set P1.4 as output
	P1SEL |= BIT4;			// Output SMCLK to P1.4

	/*** Timer Set-Up ***/
	TA0CCR0 = SampleTuneTime;				// 2MHz = 500nS therefore 60000 = 30mS sample time
	TA0CCTL0 |= CCIE;						// Interrupt enable
	TA0CTL |= TASSEL_2 + ID_3;				// SMCLK, /8
	TA1CCTL0 |= CCIE + CCIS_0 + CM_1 + CAP;	// Interrupt enable, capture select CCIxA, Positive edge, capture mode
	TA1CTL |= TASSEL_2;						// SMCLK

	/*** Set-up LCD text ***/
	setColor(COLOR_GREEN);
	drawString(10, 5, FONT_LG_BKG, "Frequency");
	drawString(25, 25, FONT_LG_BKG, "Counter");
	setColor(COLOR_BLUE);
	drawString(110, 85, FONT_MD, "Hz");

	_bis_SR_register(GIE);      // Enter LPM0 w/ interrupt

	while (1) {

		TA1CTL |= MC1;				// Start timer
		TA0CTL |= MC0;				// Start timer
		while (CounterValue != NumberSamples);	// Wait while CounterValue is not equal to 4
		TA0CTL &= ~MC0;				// Stop timer
		TA1CTL &= ~MC1;				// Stop timer

		Result >>= 2;				// Divide Result by 4
		calc_freq();

		unsigned char buffer[8];
		int toLCD = Freq;
		//int counter = 0;
		int Base = 10;
		itoa(toLCD, buffer, Base);

		char array[8] = { 0, };
		setColor(COLOR_BLACK);
		drawString(17, 80, FONT_LG_BKG, "888888");
		setColor(COLOR_ORANGE_RED);
		//int2ASCII(Result, array, 0);
		drawString(5, 80, FONT_LG_BKG, buffer);

		_delay_cycles(1600000);		// delay 100mS until next screen refresh

		Result = 0;					// Zero 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)
{
	TA0CTL &= ~MC0;				// Stop timer
	TA1CTL &= ~MC1;				// Stop timer
	CounterValue++;				// Increment CounterValue
		if (CounterValue >= (NumberSamples +1))	// Reset values if NumberSamples +1 is reached
			{
			CounterValue = 0;	// Zero CountValue
			StoredCount = 0;	// Zero StoredCount
			}
	Result += StoredCount;		// Store accumulated count in Result
	StoredCount = 0;			// Zero StoredCount
	TA1CTL |= MC1;				// Start timer
	TA0CTL |= MC0;				// Start timer
}

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

void calc_freq()
{
	float SampTime = 0.03;		// 30mS sample time
	Freq = Result / SampTime;	// Divide the averaged sampled result by the sample time to gain the frequency
}

Cheers,

Ant

 
Link to post
Share on other sites

I made some tweaks to the code as below but still have the issue as described

		char buffer[8];
		unsigned long toLCD = Freq;
		//int counter = 0;
		int Base = 10;
		itoa(toLCD, buffer, Base);

		//char array[6] = { 0, };
		setColor(COLOR_BLACK);
		drawString(17, 80, FONT_LG_BKG, "888888");
		setColor(COLOR_ORANGE_RED);
		//int2ASCII(Freq, array, 0);
		drawString(5, 80, FONT_LG_BKG, buffer);

Now the issue happens pretty much at 32760kHz (adjustment too course on the function generator to be accurate), which happens to be exactly half of what a 16bit integer can hold.

 

Back to more testing, but any idea's would be appreciated :-)

 

Cheers,

Ant

Link to post
Share on other sites

The itoa() function probably takes a signed integer. On the MSP430 that has a range of -32768 to +32767. You need something that takes an unsigned integer that has a range of 0 to 65535 to get beyond the 32767 limit. The next step would be using unsigned long to go all the way to 4,294,967,295.

 

A general purpose unsigned / unsigned long to ascii conversion can be found here:

http://forum.43oh.com/topic/1289-tiny-printf-c-version/

 

Here is a frequency counter that uses unsigned long to go up to 16 Mhz:

http://forum.43oh.com/topic/1913-frequency-counter-using-launchpad-nokia-5110-lcd/

Link to post
Share on other sites

oPossum,

 

Thanks for the information this seems to tally-up with the my observations, I will look into the itoa function and also see if I can find alternatives.

 

I was looking at your project, very nice and see you have solved the issue of measuring up to 16MHz despite using a 16Mhz clock is a simple but clever way.

Link to post
Share on other sites
  • 1 year later...

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...