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.

Create 2 second delay using ACLK (MSP430G2553)



I am trying to create a 2 second delay using ACLK. So far, I have used this formula: time (seconds) = (# of cycles)/ frequency (Hz). I am also using the VLO which has 12kHz frequency. Via calculations, I get the number of cycles should be 24,000. The ultimate reason for the delay is to sample the temperature (on board of the MSP430). Code worked fine as far as sampling the temperature before I added a timer vector to implement the delay. After that, the code reduilds and downloads and runs, although I keep getting an error within the watch function for my degreeF reading.

Could someone please look at my code and help me determine if I implemented the 2 second delay correctly and why is my degreeF is receiving an error?

Here is my code thus far:

#include "msp430.h"

long sample;

long DegreeF;

long old_DegreeF;

void main(void) {   

WDTCTL = WDTPW + WDTHOLD;                                // Stop WDT    ADC10CTL1 = INCH_10 + ADC10DIV_3;                        // Temp Sensor ADC10CLK/4   

ADC10CTL0 = SREF_1 + ADC10SHT_3 + REFON + ADC10ON;    //Set up the clock   

BCSCTL3 |= 0x20;                                        // Place 10 in bits 54 to select VLO clock (12kHz)   

BCSCTL3 &= 0x20;                                        // Make sure there is a 0 in bit 4   

BCSCTL1 &= 0x00;                                       // Place 00 in bits 54 to divide ACLK by 1.   

//Set the timer   

TA0CCR0 = 0x5DC0;                                     // Set up the initial count limit (24000) = 2 sec   

TA0CCTL0 = 0x10;                                   // Interrupt is enabled   

TA0CTL = TASSEL_1 + MC_1;                          // Timer A0 with ACLK and count up

   P1DIR |= 0x01;                                           // Set P1.0 to output direction (red led)   

P1DIR |= 0x40;                                           // Set P1.6 to putput direction (green led)

}   

// Timer A0 interrupt routine   

#pragma vector=TIMER0_A0_VECTOR   

__interrupt void Timer_A (void)    {              

ADC10CTL0 |= ENC + ADC10SC;                            // Sampling and conversion start     

while (ADC10CTL1 & ADC10BUSY);                         // Wait for ADC to complete     

sample = ADC10MEM;                                     // Read ADC sample     

DegreeF = ((sample - 630) * 761) / 1024;             

if(DegreeF<old_DegreeF)     

{P1OUT ^= 0x40;                      // Toggle P1.6 using exclusive-OR (green on)     

}     

else if(DegreeF>old_DegreeF)     

{P1OUT ^= 0x01;                      // Toggle P1.0 using exclusive-OR (red on)     

}      else     

{P1OUT ^= 0x40;                      // Toggle P1.6 using exclusive-OR (green on)     

P1OUT ^= 0x01;                      // Toggle P1.0 using exclusive-OR (red on)     

}  

old_DegreeF = DegreeF;   

}

 

  • First, the VLO has a typical frequency of 12kHz, but this varies from 4 to 20 kHz for individual devices. So don’t be surprised if you get a different timing than expected.

    Next, don’t fall out of main. You don’t have an OS to return to. Enter LPM0 or an endless while loop at the end of main.

    If you use global variables in an ISR, declare them volatile. ISRs are executed outside the expected program flow and their use of the variables in not expected by the compiler. Declaring them volatile tells the compile to not make optimizations on these variables, and use them exactly where and as often as the source code says.

     For the bits in control registers, the compiler provides proper defines. For the ADC10CTL0, you already use them. Please do so too for other control registers like BCSCTLx or ADC10CTLx. It makes typos more obvious (to you) and makes it easier to understand your intention and analyze your code (for us).

     

    Then, don’t do a busy-waiting inside an ISR. It completely perverts the purpose of ISRs. In your timer ISR, start the conversion, and read the result in the ADC10 ISR then.
    Or directly use the timer to trigger the conversion start (see the users guide) without need for a timer ISR.

     What kind of error is your DegreeF receiving?

     Note that the values in the uers guide for the degree calculation are (like the VLO speed) typical values. Actually, the offset and the gain (630 and 761) are subject to even wider variation than the VLO frequency And vary largely between individual MSPs.
    For this reason, many MSPs have calibration values - actual readings with a given reference, taken at a temperature of 30°C and 85°C. From there, you can easily calculate the offset and the gain (ADC10 readings per °C). Of course, for °F, an additional conversion is required then.

**Attention** This is a public forum