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.

frequency measurement on MSP430G2112 Please help

Other Parts Discussed in Thread: MSP430G2112

I want to measure an input signal on P1.1 using MSP430G2112 and to display it on a LCD conected on P2. I use Timer0_ A and interrupt routine.

If routine is activated LED P1.6 flashes. The problem is that I can't read the value of time that pass between 2 interrupts.

I put the TACCR0 value in "nr" variable and display it on LCD but the value is 0.

I post the code and please tell me where I am wrong and how is correct.

Many thanks!

#include "msp430.h"

//LCD initiation

unsigned int nr, dif, Compare, Oldcapture;

void main(void)
{
      WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
      InitializeLcm() ;             // defined in LCD initiation
    ClearLcmScreen();        // defined in LCD initiation
          __delay_cycles(65000);
      
      BCSCTL3 |= XCAP_3;         
      BCSCTL1 = CALBC1_1MHZ;
      DCOCTL = CALDCO_1MHZ;

             P1DIR = ~BIT1; //imput signal P1.1
             P1SEL |= BIT1;
             P1OUT |= BIT6;  // P1.6 initial state ON
             P1OUT &= ~BIT0; // P1.0 initial state OFF
           
             TACTL |= TASSEL_1 + TACLR + MC_2;      // I use an 32768 Hz watch crystal         
              TACCTL0 |= CM_1+ CCIS_0 + CAP;
           
         
            CCTL0 |= CCIE;
            TACCR0=65000;
              _BIS_SR(GIE);

     while(1)
       {        
            display (nr);  // defined in LCD initiation

            display(dif);
            __delay_cycles(10000);
         }
}


#pragma vector=TIMER0_A0_VECTOR  
__interrupt void Timer_A0 (void)
{
  
    TA0CCTL0 &= ~CCIFG;        // Capture occured, clear flag
    P1OUT ^= BIT6;
        
     if (w<100)
     {
         Compare = TACCR0;             
         dif = Compare - Oldcapture;     

         Oldcapture = Compare;              
          w++;
    }
    else
    {
        w=0;
        P1OUT ^= BIT0;
        nr = TACCR0;
    }
}

  • From the main code flow, nr and dif are 'magically' changing. The compiler does not know about interrupts and how/when they are triggered. It just sees the code as you program it. And in teh code flow of main, nr and dif are never written to. So the compiler assumes that they are constant and does not read them in from memory each time you access them. It makes the code shorter and faster.
    In this specific case, however, the variables suddenly change their value in memory, and this is not related to code operation.
    To tell the compiler that this can happen, so it won't make assumptions baout their state and perform optimizations on them, you need to declare them 'volatile'. All hardware registers are declared this way.

    Besides this:In TIMERxx_A0_VECTOR (but not A1 vector!), you don't need to manually clear the IFG bit. This is automatically done the very moment the ISR is started. There is only one source for this interrupt, so if the ISR is entered, you know that it was the CCR0 interrupt and nothign else. So the hardware was optimized to save you some CPU cycles.

    Also, your ACLK is 32768Hz, so the timer is clocked by 32768Hz. Keep in mind that this is also the maximum frequency you can detect.
    On an input signal, any frequency above 32768Hz will give you alternating 0 and 1 differences. Between 16384 and 32768Hz you'll get 1 or 2, 10922 to 16348 will give you 2 or 3 and so on. So your reading is only precise on lower input frequencies. On 1kHz, you'll get either 32 or 33 as difference, which is 1024 or 993Hz. The minimum frequency is 0.5Hz. you'll get an overrun (and therefor an aliased result) for lower frequencies.
    To get higher precision, you'll need a higher clock for the timer. But then the minimum frequency will be also higher. With 1MHz SMCLK/TACLK, you'll be able to detect from 16Hz on. And on 1kHz, you'll have a resolution of 1 Hz

  • Thank you for explainings.

**Attention** This is a public forum