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.
Hi all,
Have to admit it's been a awhile since I used the MSP430G series, but revisiting the controller for a basic project. The aim is to create a simple frequency counter and due to the lack of a function generator at home, I thought I would use the MSP430 to generate a PWM and then count the rising or falling edges of this generated pulse train.
I know a frequency counter can be made using both the Timer_A modules on the MSP430G2553, but guess my first question is this possible the way I am attempting to do it, by also generating the PWM from the MSP430?
TimerA_0 is used for the PWM generation on P1.2
TimerA_1 is used to generate an interrupt every ~500mS this is to allow some further code to be added for calculation and displaying later. GPIO P1.2 is looped to P2.1 and CCI1A is used to capture the incoming pulses.
The problem is I have the frequency of the PWM set quite low (250Hz) so it's possible to see the Count variable is approximately right, when pausing and running the code. However the captured value is way too high and not consistent with the PWM signal connected, if I ground P2.1 the Count variable stays at zero. I have checked the PWM with an oscilloscope and know that its fine, so pretty sure I have misunderstood the timer operation despite re-reading the family guide timer section a few times.
Now at the stage where 'I can't see the wood for the trees', so after someone to just say not possible and I can then pursue another route with a 555 timer as a make shift external square wave generator for testing.
#include <msp430g2553.h> volatile unsigned int Count = 0; volatile unsigned int Result = 0; int main(void) { /*** Watchdog timer and clock Set-Up ***/ WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer DCOCTL = 0; // Select lowest DCOx and MODx BCSCTL1 = CALBC1_1MHZ + DIVA_1; // Set range //BCSCTL3 |= LFXT1S_2; // VLO mode DCOCTL = CALDCO_1MHZ; // Set DCO step + modulation // Set-up GPIO P1DIR |= BIT2; // P1.2 set as output P1SEL |= BIT2; // P1.2 selected Timer0_A Out1 P2DIR &= ~BIT1; // P2.1 set as input P2SEL |= BIT1; // P2.1 selected Timer1_A CCI1A // PWM Output P1.2 TA0CCR0 |= 500 - 1; // PWM Period ~250Hz TA0CCTL1 |= OUTMOD_7; // TA0CCR1 output mode = reset/set TA0CCR1 |= 250; // TA0CCR1 PWM duty cycle 50% TA0CTL |= TASSEL_2 + MC_1 + ID_3; // SMCLK, Up Mode (Counts to TA0CCR0), /8 // PWM Capture P2.0 TA1CCR0 = 62500; // SMCLK 1MHz/8 = 125kHz therefore interrupt every ~500mS TA1CCTL0 |= CCIE; // Capture/compare interrupt enable TA1CCTL1 |= CM_1 + CCIS_0 + CAP + CCIE; // Falling Edge, CCI1A as input, Capture mode, Int enable TA1CTL |= TASSEL_2 + MC_1 + ID_3; // SMCLK, Continous. /8 _BIS_SR(GIE); // interrupts enabled } //Timer_A1 TACCR0 Interrupt Vector Handler Routine #pragma vector=TIMER1_A0_VECTOR __interrupt void Timer1_A0(void) { Result++; // Result = Count; // Count = 0; } //Timer_A1 TACCR1 Interrupt Vector Handler Routine #pragma vector=TIMER1_A1_VECTOR __interrupt void Timer1_A1 (void) { Count++; TA1CTL &= ~TAIFG; // Clear the interrupt flag }
Thanks,
Ant
Ant,
a few things I get from the first sight - this one:
TA0CCR0 |= 500 - 1;
only works when TA0CCR0 was zero before (which might be the case), but in general I would prefer the "=" for it. Furthermore there is missing "the main program", so you should set the controller into sleep mode or add
while( 1 ) {}
at the end of your main().
Dennis
**Attention** This is a public forum