Jump to content
43oh

Changing code from running on Crystal to running on DCO


Recommended Posts

Howdy Everybody,

 

I am trying to figure out how to change this code from running on the crystal to running on the DCO.  I already built the board this is going on and dumbed up and did not make any provisions for the crystal. 

 

I have not located the document that had the timer modes laid out to where I could understand the addressing of each of the timers. 

 

Thanks for the help!

#include <msp430.h>

#define LEDR BIT0
#define LEDG BIT6
#define BUTTON BIT3

const int TICKS_PER_SECOND = 32;
enum {state_waiting, state_hold_high};

unsigned int current_state = state_waiting;
unsigned int hold_timer = 0;

void init(void)
{

  // Stop watchdog timer to prevent time out reset
  WDTCTL = WDTPW + WDTHOLD;

  // Enable LED outputs and Button pullup
  P1OUT = BUTTON;
  P1DIR = LEDR + LEDG;
  P1REN = BUTTON;

   // Set up 32768Hz crystal
  BCSCTL3 |= XCAP_3;                              // select 12pF caps   SHOULD DEL THIS LINE

  // initialize Timer0_A
  TA0CCR0 = ( 32768 / TICKS_PER_SECOND ) - 1;     // set up timer for 32Hz
//DC0CCRO = ( 125000 / TICKS_PER_SECOND ) -1;   // REPLACE ABOVE LINE NEED TO ADU
  TA0CTL = TASSEL_1 + ID_0 + MC_1;                // configure and start timer
//BCSCTL2 |= SELM_0 + DIVM_8;     // SETUP FOR TIMER TO REPLACE ABOVE DCO TIMER DIVIDE BY 8


  // enable interrupts
  TA0CCTL0 = CCIE;                                // enable timer CCR0 interrupts CHANGE TO BCS?
  __enable_interrupt();                           // set GIE in SR
  LPM3;                                           // select low power mode 3
  while(1);
}


/**
* Timer interrupt called at 125Hz (TICKS_PER_SECOND)
*/
#pragma vector = TIMER0_A0_VECTOR
__interrupt void myTimerISR(void)
{

  switch( current_state )
  {
    /* state waiting */
    case state_waiting:
      if( ( P1IN & BUTTON ) == 0 )
      {
        if( hold_timer >= TICKS_PER_SECOND * 2 )
        {
          /* If button held for 2 seconds change state */
          current_state = state_hold_high;
          hold_timer = 0;
          break;
        }
        else
        {
          /* If button pressed, but not for 2 seconds yet inc timer */
          hold_timer++;
        }
      }
      else
      {
        /* Button not pressed, reset timer */
        hold_timer = 0;
      }
      break;

    /* state hold high */
    case state_hold_high:
      /* Set output high */
      P1OUT |= LEDR;

      if( hold_timer >= TICKS_PER_SECOND * 60 )
      {
        /* If timer has elapsed, set output LOW, switch state */
        P1OUT &= ~LEDR;
        hold_timer = 0;
        current_state = state_waiting;
        break;
      }
      else
      {
        hold_timer++;
      }
      break;

    /* return to a idle state */
    default:
      current_state = state_waiting;
      break;
  }
}

void main( void )
{
  init();
}

Link to post
Share on other sites

The ACLK will run off the VLO if the LFXTAL isn't present. So you'll configure timers to use SMCLK instead.

 

I wanna say it's TASSEL_2 for that (no datasheet in front of me atm as I'm on a phone), but you'll need to implement the clock divider (in TA0CTL) and maybe SMCLK itself should have a divider in place. See BCSCTL2 for that (IIRC).

Link to post
Share on other sites

Sprillis,

 

It is TASSEL_2   Do I need a line to setup and start the BCS?  Also on the DCOCTL I thought that was enough to tell it to go there, but I have not been able to get it to work, if you run it with the debugger, works perfectly.  As soon as you are completely off of it back to no function.  Desired pin goes high on start, but no response at all.  I dunno I am stumped. 



  // initialize Timer0_A
  TA0CCR0 = ( 10000 / TICKS_PER_SECOND ) - 1;     // set up timer for 12.5Hz
  TA0CTL = TASSEL_2 + ID_3 + MC_1;                // configure and start timer
  SFR_8BIT(BCSCTL2);
  SFR_8BIT(DCOCTL);
  // enable interrupts
  TA0CCTL0 = CCIE;                                // enable timer CCR0 interrupts
  __enable_interrupt();                           // set GIE in SR
  LPM3;                                           // select low power mode 3
  while(1);
}


/**
* Timer interrupt called at 32Hz (TICKS_PER_SECOND)
*/
#pragma vector = TIMER0_A0_VECTOR
__interrupt void myTimerISR(void)
{

  switch( current_state )
Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...