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.

Having trouble slowing things down enough.

Other Parts Discussed in Thread: MSP430G2231

Let me start by saying that I am very new to the MSP430, and microcontrollers in general. I just decided to jump in and try to swim.  I'm still in the stage of trying assemble a large number of chunks of information into something coherent in my mind.  Anyway, I'm trying to set up a MSP430G2231 to read a moisture sensor every 15 minutes or so, well actually any amount of time around 5 minutes or longer would be fine, and I can't seem to get everything slowed so the timer takes that long to count.

My thought process is such...

VLO =12,000Hz (Give or take, I read about how its not very accurate)

Use VLO to source ACLK.

Then divide ACLK by 8 = 1500Hz

Use ACLK to clock Timer A.

Divide source clock on Timer A by 8 = 187.5Hz

 

Seeing as how Timer A is 16 bits it can count to 65536, and if you take 65536/187.5 you get about 350 seconds or about 5.8 minutes for the timer to count all the way up.  The problem I am having is that currently I have my code set up to blink LED's and I'm only getting about a minute of delay between LED changes.  I really don't know what else to try.

 

My code is as follows.  I haven't done anything with the moisture sensor yet.  My first step is just trying to get everything slowed down.

 

 

#include <intrinsics.h>

//#include <msp430g2231.h>

#include <io430g2231.h>

#define red_LED   BIT0

#define grn_LED   BIT6

 

 

void main(void)

{

 

  //configure clocks

BCSCTL3 |= LFXT1S_2;                      // LFXT1 = VLO

BCSCTL2 |= SELM_3 + SELS;                 // SMCLK  = MCLK = VLO = 12Khz

IFG1 &= ~OFIFG;                           // Clear OSCFault flag

__bis_SR_register(SCG1 + SCG0);           // Stop DCO

BCSCTL1 |= DIVA_3 + LFXT1S0;                   //Divide ACLK by 8

 

  WDTCTL = WDTPW | WDTHOLD;

  P1OUT = ~red_LED;

  P1DIR = red_LED | grn_LED;

  TACTL = MC_2 | ID_3 | TASSEL_1 | TACLR;  //Configure Timer A

 

 for (;;) {

    while (TACTL_bit.TAIFG == 0) {

    }

    TACTL_bit.TAIFG = 0;

    P1OUT ^= red_LED | grn_LED;

  }

}

 

  • For this kind of job, one would usually use an interrupt function. The same, however, can be achieved with polling.

    Just do not toggle teh LED on each occurence of a timer overflow. Count up a variable and just toggle the pin if the variable reaches a certain value (and reset it to 0 again then).

  • Looks like the bug is here:

    skysurf76 said:

    BCSCTL1 |= DIVA_3 + LFXT1S0;                   //Divide ACLK by 8

    Field LFXT1S is not in BCSCTL1, and as luck would have it, adding LFXT1S0 changes the DIVA field, messing up your intended divider.

    Jeff

  • Jeff, thank you very much.  I'm getting about a 7 minute cycle time now which is perfect.  Its a bit longer than I expected but the longer the better.

     

    Jens, I know I should be using interrupts for this and that is my ultimate goal, but getting the timer setup in a satisfactory way was my first goal.  Next I'll move on to interrupts.  What I'm trying to do is use a MSP430G2231 to hook up to a basic moisture sensor, take a reading every so often using the timer, interrupts, and an adc, and if the moisture is low enough turn a servo to open a valve to water some plants.  I plan on using a battery pack to power it so I want to keep power consumption to a minimum which is why I started with using the timer only and as slow and as low of power of clocks as possible.  Next I'll learn interrupts, and how to put the cpu to sleep and wake it up with the interrupts.

  • skysurf76 said:
    I'm getting about a 7 minute cycle time now which is perfect.  Its a bit longer than I expected but the longer the better

    The VLO is surely not the right clock source for a definitive delay. It has  awide variation range and drifts largely with temperature.
    So I didn't pay much attention to the timing values you cited. 7 minutes is as well in the exepcted range as 4.
    I'm not in the office, so I didn't even try to check the correct register settings (good catch, Jeff).

    skysurf76 said:
    I want to keep power consumption to a minimum which is why I started with using the timer only and as slow and as low of power of clocks as possible.

    Well, using the VLO here surely is the lowest possible power consumption. Combine this with low power mode for the main loop and a timer-controlled ADC (does the 2231 have an ADC10? I really miss the docs in my office!), it will give you almost no power consumption at all. (self-discharge of the batteries will be much higher I guess).

    If you control the ADC with the timer, you won't neven need a timer ISR, only an ISR that is triggered when the ADC has finished the conversion.
    Main problem will be to not flood the plants then, as it takes another 7 minutes until you get the 'wet' reading and close the valve again (unless you make the code a bit more complicated)

  • You can double the interval (~14 minutes) by running the timer in up-down mode.  Set CCR0 to 65535, and your timer period will be 65535 * 2 cycles.  And you can still use CCR0 CCIFG to trigger the ADC if you like.

    Jeff

**Attention** This is a public forum