I am currently migrating my code from MSP430F47176 to MSP430F67691. I have one timer (TIMER A0) that counts up to one configurable value (TACCR) using ACLK (32 kHz) as source. I use interrupt routine every time the timer reach this value, enabling interrupts and initiating timer again. My source clock configuration is:
- ACLK: 32 kHZ
- MCLK, SMCLK: 16 MHz
void xtal_init(void) { //UCSCTL3 |= SELREF__XT1CLK; // FLL Ref = REFO UCSCTL4 = SELA_0 + SELS_4 + SELM_4; // Select ACLK = LFXT1 // SMCLK = DCO // MCLK = DCO // Initialize LFXT1 //P7SEL |= 0x03; // Select XT1 UCSCTL6 &= ~(XT1OFF); // XT1 On UCSCTL6 |= XCAP_3; // Internal load cap // Loop until XT1 fault flag is cleared do { UCSCTL7 &= ~XT1LFOFFG; // Clear XT1 fault flags }while (UCSCTL7&XT1LFOFFG); // Test XT1 fault flag // Initialize DCO to 16,777216MHz __bis_SR_register(SCG0); // Disable the FLL control loop UCSCTL0 = 0x0000; // Set lowest possible DCOx, MODx UCSCTL1 = DCORSEL_5; // Select DCO range 24MHz operation UCSCTL2 = FLLD_1 + FLLD_16MHz;// Set DCO Multiplier for 16,777216MHz // (N + 1) * FLLRef = Fdco // (511 + 1) * 32768 = 16,777216MHz // Set FLL Div = fDCOCLK/2 __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 16,777216 MHz / 32,768 Hz = 524288 = MCLK cycles for DCO to settle __delay_cycles(524288);// // Loop until XT1,XT2 & DCO stabilizes do { UCSCTL7 &= ~(XT2OFFG + XT1LFOFFG + DCOFFG); // Clear XT2,XT1,DCO fault flags SFRIFG1 &= ~OFIFG; // Clear fault flags }while (SFRIFG1&OFIFG); // Test oscillator fault flag }
Problem I have found is that, while I debug, timer seems to count much faster than expected. I know it because I have checked that TIMER REGISTER counts about 5000 every I debug only ONE instruction. The same code in my old MSP430F47176 works perfectly I have to execute several instructions just to count 1.
This is timer initialization and interrupt service routine:
void TimerA0_init(void) { TA0CTL = TACLR; TA0CCR0 = (Uint16) 32*50*CHECK_RX_RATE-1; TA0CCTL0 = 0x00; TA0CCTL1 = 0x00; TA0CTL = TASSEL_1 + MC_1 + TAIE; //source: ACLK - 32 kHz; Count UP to TACCR0 } // Timer A0 interrupt service routine #pragma vector=TIMER0_A1_VECTOR __interrupt void Timer_A (void) { __bis_SR_register(GIE); //Interrupts enabled //stop timer TA0CTL = TACLR; //Reset & Switch Off TA TA0CTL = 0; TA0CCR0 = (Uint16) 32*50*CHECK_RX_RATE-1; TA0CCTL0 = 0x00; TA0CCTL1 = 0x00; TA0CTL = TASSEL_1 + MC_1 + TAIE; //source: ACLK - 32 kHz; Count UP to TACCR0 }
I execute it in loop while (1);
First thing I thought was that perhaps source ACLK was not correxctly configured, but I have checked ACLK PIN of microcontroller and is 32 kHz, as expected.
Thank you.