Jake 24 Posted April 23, 2016 Share Posted April 23, 2016 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(); } Quote Link to post Share on other sites
spirilis 1,265 Posted April 23, 2016 Share Posted April 23, 2016 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). Quote Link to post Share on other sites
Jake 24 Posted April 25, 2016 Author Share Posted April 25, 2016 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 ) Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.