Other Parts Discussed in Thread: MSP430F67691, MSP430F47176
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.