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/MSP430F2132: Timer not behaving as expected.

Part Number: MSP430F2132

Tool/software: Code Composer Studio

Hello,

First thanks for viewing this and helping me. I will try and keep this quick and concise. I am using timerA0_A3 and setting up with the following code. I have confirmed that these settings took in the register tab provided in CCS.  Basically my problem is that when I set a TA0CCR0 value I am not viewing that this interrupt is being timed properly when I set a pin high and then low. on an O-scope. 

TA0CTL = (TASSEL_1 | ID_3 | MC_1 | TACLR ); // ACLK, DIV BY 8 , Up mode: Timer counts up to TACCR0., clear at start

TA0CCTL0 = CCIE; // capture/compare interrupt enabled TimerA0

I have a case statement for setting the TA0CCR0. the time in seconds can be calculated by ..... time_in_seconds = (8 * TA0CCR0) / 32KHz due to the fact that I set TASSEL_1 | ID_3 

case 12: // 32KHz clk
{
switch(letter)
{
case '1':
{
TA0CCR0 = 2; // 488us
time_in_seconds = 0.00048828125; // time in ms = (8 * TA0CCR0) / 32KHz
G_cmdfsm =1;
break;
}
case '2':
{
TA0CCR0 = 4; //1ms
time_in_seconds = 0.009765625;                                      OBSERVED A PERIOD OF 9.76MS
G_cmdfsm = 1;
break;
}
case '3':
{

TA0CCR0 = 41; //10 ms
time_in_seconds = 0.010009765625;
G_cmdfsm = 1;
break;
}
case '4':
{

TA0CCR0 = 410; //100 ms                                               OBSERVED A PERIOD OF 802.5MS                            
time_in_seconds = 0.10009765625;
G_cmdfsm = 1;
break;
}
case '5':
{

TA0CCR0 = 2048; //500ms                                             OBSERVED A PERIOD OF 4 SECONDS 
time_in_seconds = 0.5;
G_cmdfsm = 1;
break;
}
case '6':
{
TA0CCR0 = 4096; //1 seccond
time_in_seconds = 1; // 1 second = 1000 ms :)
G_cmdfsm = 1;
break;
}
case '7':
{
TA0CCR0 = 8192; //2 seccond
time_in_seconds = 2; // 1 second = 1000 ms :)
G_cmdfsm = 1;
break;
}

}
break;

}

Finally the interrupt is doing the following.....

#pragma vector = TIMER0_A0_VECTOR //600 us
__interrupt void Timer_A_CCR0_ISR(void)
{
P2OUT |= BIT4; //pin 5 high
/*
//CPR=1250;

cntr_register(IR_LOAD, IR_OTR, 0, NULL);

initial_counter_value = cntr_register(IR_RD, IR_OTR, COUNTER_REG_SIZE, NULL); // read the counter to get a baseline

calculated_rpm = (number_of_counts_per_sample_peiod*(60/time_in_seconds/(5000)));

//calculated_rpm = (number_of_counts_per_sample_peiod*(60/(time_in_ms)/(1000)))/(4*CPR);

trunc (calculated_rpm);

number_of_counts_per_sample_peiod = initial_counter_value - end_of_timer_counter_value;

//printf(" %d",number_of_counts_per_sample_peiod);

printf("%d ", calculated_rpm);

cntr_register(IR_LOAD, IR_OTR, 0, NULL);

end_of_timer_counter_value = cntr_register(IR_RD, IR_OTR, COUNTER_REG_SIZE, NULL);
*/
P2OUT &= ~BIT4; // pin 5 low

}// end timer

However I am not getting the proper period when i set the pins  high then low (even when I comment out all the code . The timers I observed can be found in the case statement. As can be seen he values are very far off from what i would expect. I have looked at how long that code is taking to calculate and it takes 600us to execute the calculations and the print statement in the timer. I hope that made sense.... Thanks for any help you can give me. 

  • Hi Tyler, Thanks for your detailed post. from your description, I think you want to use the configurable capture compare function in timer A. There are some basic timer A 3CC code example on MSP430F21x2 Code Examples (Rev. J) . Could you please try run these code and test the 3CC feature of timer A. Thanks!

  • 1) What platform are you using? Does it have a 32kHz crystal? If not, I expect you're using VLOCLK, which is quite a bit slower than 32kHz, not to mention somewhat less predictable [Ref data sheet (SLAS578J) Table p.33]. 

    2) Set CCR0=period-1, since it counts through 0 as well. This will be most noticeable with small values, though the effect will still be fractional.

    3) I suggest you use TACLR after setting a new CCR0. Depending on what order you're testing in, residual counts in TA0R will throw your numbers off. [Ref User Guide (SLAU144J) Sec 12.2.3.2]

    Items (1)-(3) only seem to explain part of your discrepancy, but until they're straightened out it's hard to guess well.

  • Hi Bruce,

    Thanks for the response.

    1)I am using a custom board and it does use the 32kHz crystal.  But that is interesting that you say I might be using that as the period can be seen to be inconstant. Is there anyway to verify what clock Im using (besides looking at the register and seeing that the bits were set in accordance with the Aclk, TASSEL_1) 

    2)  Okay I made that change but didn't effect the period in much except for the lower values,  But it still doesn't explain the large discrepancy with the period.  

    3) Strangely, no matter where i put the clear command it breaks the code and it doesn't  go into the interrupt. 

    case '2':
    {
    //TA0CTL = TACLR;
    TA0CCR0 = 4; //1ms
    //TA0CTL = TACLR;
    time_in_seconds = 0.009765625;
    G_cmdfsm = 1;
    break;
    }
    case '3':
    {
    //TA0CTL = TACLR;
    TA0CCR0 = 41; //10 ms
    //TA0CTL = TACLR;
    time_in_seconds = 0.010009765625;
    G_cmdfsm = 1;
    break;
    }

  • 1) The surest-no-guessing way is to put ACLK out on P2.0 -- set P2DIR.0=1, P2SEL.0=1 and measure it on a scope [Ref data sheet (SLAS578J) Table 22]. This Example does this:

    https://dev.ti.com/tirex/explore/node?node=ABuD0ngn6pQTdcIWv-WPEw__IOGqZri__LATEST

    If you don't have a scope, use the debugger to check BCSCTL3:LFXT1OF and IFG1:OFIFG [Ref User Guide (SLAU144J) Secs 5.3.4 and 5.3.6]

    2) I was only expecting a fractional difference from this in particular. The oscillator is the prime suspect at the moment.

    3) Try:

    > TA0CTL |= TACLR;

    The TACLR bit clears itself when it's finished.

  • So there it is, period is 244us (as observed on my o scope) .... 1/244*10^-6=4098hz 

    8/4098.36*411=802.27ms  and can be seen in my original post the observed period of  802.5MS matches. So the set up is incorrect. Im not sure what i did wrong though.    

    Here is my code for setting up the 32Khz 

    // Set CPU clock and start the LFXT1 32KHz crystal oscillator
    static void SetupClock(void)
    {
    uint i;

    for (i=0; i<0xfffe; i++); // Delay for XTAL stabilization

    // Reset the 16MHz oscillator flash values if they were accidently erased
    if ( (CALBC1_16MHZ == 0xFF) && (CALDCO_16MHZ == 0xFF) )
    Reset_DCO();

    BCSCTL1 = CALBC1_16MHZ; // Set DCO to 16MHz
    BCSCTL1 &= ~(DIVA_3 | XTS); // Reset XTS bit (if set) for XT1 low freq mode
    DCOCTL = CALDCO_16MHZ;

    // select 12.5pF of load capacitance for the LFXT1 32KHz oscillator
    BCSCTL3 = XCAP_3;

    // clear the oscillator fault flag and wait for the oscillator
    // fault flag to stay cleared
    do
    {
    IFG1 &= ~OFIFG; // clear OFIFG bit in IFG1
    for (i=0; i<0xff; i++); // delay

    } while (IFG1 & OFIFG);

    } // end SetupClock(void)

  • I agree that it sure looks like a /8 on the crystal. I can see that you're clearing the DIVA field. That said: I suggest you check the DIVA field anyway. While you're in there, check to make sure the 0xC0 bits in P2SEL are 1 and in P2DIR are 0. This isn't the symptom I would expect if they weren't, but why wonder?

    The code here looks fine. Is this function always called? Does the clock signal look steady (no "stuttering")? Would you know if ResetDCO was called?

    4kHz is (just barely) in the spec-ed range for the VLO, but that 4096 can't be a coincidence (seems like, anyway). Also detecting whether it's really the VLO in disguise is fairly difficult, and checking registers is easy.