Part Number: TDC1000-TDC7200EVM
Tool/software: Code Composer Studio
Hi!
I want to set the LPM3 of the MSP430 while not measuring anything. I was able to successfully use the ACLK with the internal REFO clock to replace the update trigger timer interrupt to be able to wake up. However I had to modify a part of your code in main.c, Init_Clock(). I can see that the ACLK source is set twice and I needed to change it again for the internal REFO.
Will this interfere with the rest of the flow-metering code? Is the clock used by some other process?
I have added two lines of code at the end:
//****************************************************************************** void Init_Clock(void) { // Enable XT2 XIN/XOUT Pins P5SEL |= 0x0C; // Select XIN, XOUT on P5.3 and P5.2 UCSCTL6 &= ~XT2OFF; // Enable XT2 UCSCTL6 |= XT2DRIVE_3; UCSCTL3 |= SELREF_2; // FLLref = REFO // Since LFXT1 is not used, // sourcing FLL with LFXT1 can cause // XT1OFFG flag to set // ACLK=REFO,SMCLK=DCO,MCLK=DCO UCSCTL4 = SELA__REFOCLK + SELS__DCOCLKDIV + SELM__DCOCLKDIV; UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx // Loop until XT1,XT2 & DCO stabilizes do { UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); // Clear XT2,DCO fault flags SFRIFG1 &= ~OFIFG; // Clear fault flags TI_TDC1000_LINK_LED_PxOUT ^= TI_TDC1000_LINK_LED_PIN; // Toggle LED }while (SFRIFG1&OFIFG); // Test oscillator fault flag __bis_SR_register(SCG0); // Disable the FLL control loop UCSCTL1 = DCORSEL_5; // Select DCO range 16MHz operation UCSCTL2 |= 124; // Set DCO Multiplier for 8MHz // (N + 1) * FLLRef = Fdco // (249 + 1) * 32768 = 8MHz // (124 + 1) * 32768 = 4MHz __bic_SR_register(SCG0); // Enable the FLL control loop // Worst-case settling time for the DCO when the DCO range bits have been // changed is n x 32 x 32 x f_MCLK / f_FLL_reference. See UCS chapter in 5xx // UG for optimization. // 32 x 32 x 8 MHz / 32,768 Hz = 250000 = MCLK cycles for DCO to settle __delay_cycles(250000); // vishy:continue to keep 8MHz delay // 11/4: Dont' divide SMCLK by 2 /*UCSCTL5 |= DIVS__2;*/ // 3/16: Select ACLK as XT2, divide ACLK by 2 UCSCTL5 |= DIVA__2; UCSCTL4 = SELA__XT2CLK + SELS__XT2CLK + SELM__XT2CLK; // SMCLK=XT2, MCLK=XT2=24MHz // After changing UCSCTL4, loop again until XT1,XT2 & DCO stabilizes (Errat workaround?) do { UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); // Clear XT2,DCO fault flags SFRIFG1 &= ~OFIFG; // Clear fault flags TI_TDC1000_LINK_LED_PxOUT ^= TI_TDC1000_LINK_LED_PIN; // Toggle LED }while (SFRIFG1&OFIFG); // Test oscillator fault flag TI_TDC1000_LINK_LED_PxOUT |= TI_TDC1000_LINK_LED_PIN; // Turn on LED // ######### LINES OF CODE ADDED ######### UCSCTL5 &= DIVA__1; // div by 1 UCSCTL4 = SELA__REFOCLK + SELS__XT2CLK + SELM__XT2CLK; // SMCLK=XT2, MCLK=XT2=24MHz }
And here is the timer set-up and interrupt code:
void timer1_A0_init(void) { TA1CCR0 = 0xFFFF; //max value of register TA1CCTL0 |= CCIE; // TA1CCR0 interrupt enabled // Note: TACLR clears both counter and clock divider: setup divider later TA1CTL |= TACLR; TA1CTL = TASSEL__ACLK + MC_3 + ID_0; // ACLK (32768 Hz), clear TAR, up/down, divide by 1, no overflow intrpt TAIE TA1EX0 = TAIDEX_0; // further divide by 1 to get 4 seconds }
//****************************************************************************** // Timer1 A0 interrupt service routine //------------------------------------------------------------------------------ #pragma vector=TIMER1_A0_VECTOR __interrupt void TIMER1_A0_ISR (void) { __bic_SR_register_on_exit(LPM3_bits); // Exit LPM3 __delay_cycles(24); // wake up time is 1us next_trigger_time = 1; TI_TDC1000_MEAS_LED_PxOUT ^= TI_TDC1000_MEAS_LED_PIN; // Blink red LED }
Thanks in advance!
Kind regards,
Thibault