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.

CCS/MSP430G2553: Trying to detect the half cycle of a sine wave

Part Number: MSP430G2553
Other Parts Discussed in Thread: MSP430WARE

Tool/software: Code Composer Studio

I am still fairly new to MSP430 and CCS and I'm currently working on trying to determine how long it takes a sine wave to hit 0 twice or the half cycle of the wave. The wave is generated by a function generator at 1KHz and is offset so there is no negative component.  The ADC works fine and I can detect when the sine wave hit 0. I also have a TimerA interrupt that gets activated every 0.0001 secs at which point interuCounter is incremented and is how I keep track of time between the two 0's of the wave. However when I try to count the time in between those two instances of voltage = 0 I keep getting "difference=1" no mater what I make the frequency. With 1KHz I should expect 10. Am I implementing the timer wrong? Or is something else missing that I'm overlooking? 

#include "msp430g2553.h"
#include "intrinsics.h"
int voltage=0;
int flag1=1;
int flag2=0;
int count=0;
int preCount=0;
int difference=0;
int flag3=0;
int interuCounter;
int sawZero;
void main(void)
{
   WDTCTL = WDTPW  + WDTHOLD;    // stop WDT
   DCOCTL = 0;
   BCSCTL1 = CALBC1_1MHZ;
   DCOCTL = CALDCO_1MHZ;


   ////////////////////////////////////////////////////////
      //TimerA setup
      TA0CCR0 |= 100; //count up to 100 (1/1MHz*100 = 0.0001 sec interrupt)
      TA0CCTL0 |= CCIE;
      TA0CTL |= TASSEL_2 + MC_1;//SMCLK clock, count up mode

     // _BIS_SR(LPM0_bits + GIE); // Sleep in LPM0 with interrupts enabled

   //////////////////////////////////////////////////////////////////////////////////////////


   // ADC configuration,V+ref=3V,V-ref=0V,Channel=A0

   ADC10CTL0  = ADC10ON + ADC10IE; // Vref Vr+=3v,Vr-=VSS,
                     // S&Htime = 4 X ADCCLK,ADC10 on,ADC interrupts enabled
   ADC10CTL1  = ADC10DIV_7; // INCH =0000->A0,ADCCLK src = ADC10CLK,
                            // ADCCLK/8,Single Channel Single Conversion
   ADC10AE0   = INCH_0;     // channel A0

   ADC10CTL0 |= ENC + ADC10SC; // Start Conversion

   _BIS_SR(LPM0_bits + GIE); // Sleep in LPM0 with interrupts enabled
}

/***************************************************************************/
/*                 interrupt vectors for MSP430                            */
/***************************************************************************/

#pragma vector = ADC10_VECTOR
__interrupt void adc10_interrupt(void)
{
  ADC10CTL0 |= ENC + ADC10SC;  // Start Conversion again
  voltage = ADC10MEM;//voltage will be whatever ADC reads
  P1DIR |= BIT6;
  P1OUT &= ~BIT6;


  }



#pragma vector=TIMER0_A0_VECTOR     // Timer0 A0 interrupt service routine
   __interrupt void Timer0_A0 (void) {

   interuCounter++;//increment every 0.0001 secs

   if(flag2==1)//Enter third if statment if I see  voltage=0 again
     {
        flag3=1;
    }
    if(voltage==0 && flag1==1)
     {
        preCount =interuCounter; //count when I first saw voltage=0
        flag1=0; //Don't enter this statement again unless I've already seen 0 twice
        flag2=1;//Enter third if statment if I see voltage=0 again
     }
    if(voltage==0 && flag3==1)
        {

           flag1=1;//RESET
           flag2=0;//RESET
           flag3=0;//RESET
           count=interuCounter;//count at second instance of voltage=0
           difference = count-preCount; //Difference between first instance an second instance of 0
           P1OUT |= BIT6;


        }


}

 

  • Hi,

    please let me verify one thing first:
    Do you need to detect the second 0 as early as possible to then initiate an action or could you first sample the whole sine wave and later on detect the time interval between two 0s?

    In case of the first scenario, I'd suggest to slightly adapt the usage of the Timer: Whenever ou detect the first 0 in your ADC sample you'll start the Timer counter and then stop it when detecting the second 0. You would check the ADC value in your ADC isr and start the timer in case you detect the 0. You'll then have the number of timer counts and can calculate the time interval as you'll know the timer clock frequency.

    In case of the second scenario, I'd suggest for you to trigger the ADC10 by using a Timer interrupt. That way you'd know the time interval between two samples and can calculate the time between the two 0s based on the number of samples in between and the Timer clock frequency.

    We provide a number of examples on the different peripherals, please go to CCS, open the TI Resource Explorer and then follow: MSP430Ware ->Devices->MSP430G2xx->MSP430G2553-> Peripheral Examples -> Register Level and take a look at the different ADC10 examples.
    Please let me know if this helps.

    Best regards,
    Britta
  • lots of ways of doing it:

    1) use a signal conditioner / comparator to generate a square wave out of it and to count the edges digitally;

    2) use adc to sample the input and perform fft/ieee1057;

    3) just count the input pulse train digitally and calculate the distance between two rising (or falling) edges;

    ...

    each with its own pros and cons.

  • Hello Britta,
    I have to use the first scenario and detect as early as possible. I was able to start the timer at the rising edge and end the timer at the falling edge and as I was able to get the half cycle so thank you for your help!

**Attention** This is a public forum