Rickta59 589 Posted May 4, 2011 Share Posted May 4, 2011 I've been looking for a way to run the msp430 with accurate MHZ speeds. In talking with NatureTM on IRC, he mentioned that he had used a crystal oscillator ( ECS-100A-160 ) successfully with his msp430g2231. He didn't have the exact code he used but he helped me recreate this snippet. I didn't have a crystal oscillator but I did have an ATTiny84 lying around that I put on a breadboard. I reprogrammed the ATTiny84 fuses so its CLKOUT fuse bit was enabled. The ATTiny is using an external 12MHZ crystal. This is fairly accurate, when you enable the CLKOUT fuse, avr outputs the CPU clock on that pin as a square wave. I connected that pin to the XIN on my msp430g2231 and left XOUT unconnected. I'm not sure if this is going to damage my g2231 as the specs say you should only feed it low frequency external square waves from 10k - 50k. So don't expect this to actually work. I'm just passing along what I've discovered. https://gist.github.com/954778 -rick //*********************************************************** // runfast.c - Using 12MHZ external square wave clock as LFXTCLK // source MCLK/SMCLK from 12MHZ wave and blink led // at 60Hz // // Use an external clock ( I'm using an attiny running at 12.00 MHZ // with the CLKOUT fuse enabled ) as the MCLK/SMCLK for the MSP430. // I've been told you could also use an external oscillator like an // ECS-100A-160. I ordered some of these to verify. // // LFXT1 oscillator logic level square wave input frequency, LF mode // // XIN - external clock in from attiny CLKOUT pin ( set avr fuse to get clock ) // XOUT - NC // P1.0 - led on until OSCFault cleared // P1.4 - SMCLK frequency, measuer with multimeter/oscope // P1.6 - 60Hz led flash, measure with multimeter/oscope // //*********************************************************** #include void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer P1DIR = BIT0 | BIT6 | BIT4; // P1.0 and P1.6 output, P1.4 SMCLK frequency P1SEL = BIT4; // P1.4 output SMCLK on P1.4, measure with multi meter P1OUT = BIT0; // red LED on until OSCFault is cleared DCOCTL = 0x00; BCSCTL2 = SELM_3 + DIVM_0 + SELS + DIVS_0; // MCLK Source Select 3: LFXTCLK // MCLK/1 SMCLK/1 SMCLK LFXTCLK BCSCTL1 |= XTS; // XTS BCSCTL3 = LFXT1S_3 | XCAP_0; // LFXT1 = 12MHZ crystal, No Capacitor // not sure if this is needed while(IFG1 & OFIFG) { IFG1 &= ~OFIFG; // Clear OSCFault flag _delay_cycles(10000); // delay for flag and visibility } P1OUT = 0; // red LED off __bis_SR_register(SCG0); // Stop DCO, we just use the LFXT1 which is // actually running at 12MHZ while(1) { P1OUT ^= BIT6; // green LED on, measure this, it should be 60Hz _delay_cycles((12000000/60/2)-35); // 12MHZ, 60/2, 35 overhead clocks } } touch, timsoer, jmparatte and 1 other 4 Quote Link to post Share on other sites
touch 34 Posted May 4, 2011 Share Posted May 4, 2011 I seem to remember people running it with 16MHZ external crystals, I cant find the post at the moment though. I'm tempted to throw a 12mhz crystal in instead of a 37khz watch crystal and see what happens now. Quote Link to post Share on other sites
jsolarski 94 Posted May 4, 2011 Share Posted May 4, 2011 Looks like it should work compiles with minor changes on mspgcc, but no way to test with 12MHz. Maybe if i get a chance i will set another DCO calibrated MSP to be used as a digital clock to test. I know the VLO works with out an issue. Quote Link to post Share on other sites
jmparatte 0 Posted April 30, 2012 Share Posted April 30, 2012 I've made also some experimentations about clocking the G2231 with an external clock 16MHz. Before reading your code, I experimented a solution near yours, but with a little change: the ACLK is driven with an external clock and the MCLK is driven with the internal DCO. I will explain it far. First I tried your code. It works. See below my code test: void main (void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer BCSCTL3 = LFXT1S_3 | XCAP_0; // Digital external 0.4- to 16-MHz clock source // Drive ACLK, MCLK & SMCLK with digital external clock source on XIN pin... // LFXT1CLK = Digital external clock = Quartz Pierce Oscillator = 16MHz // ACLK = LFXT1CLK/8 = 2MHz // MCLK = SMCLK = 16MHz DCOCTL = 0x00; // Select lowest DCO and RMOD settings BCSCTL1 |= DIVA_3; // ACLK/8 BCSCTL2 = SELM_3 | DIVM_0 | SELS*1 | DIVS_0; // LFXT1CLK or VLOCLK BCSCTL3 = LFXT1S_3 | XCAP_0; // Digital external 0.4- to 16-MHz clock source // // (Not sure if this is needed?) Yes, it's needed! while(IFG1 & OFIFG) { IFG1 &= ~OFIFG; // Clear OSCFault flag // _delay_cycles(10000); // Delay for flag and visibility (perhaps it's needed) } // __bis_SR_register(SCG0); // Stop DCO. We just use LFXT1CLK which is actually // running with digital external clock source Comments: 1/ The code while(IFG1 & OFIFG) {...} before __bis_SR_register(SCG0) seams to be necessary else it's like if an internal PLL takes a lot of time to synchronize with the external clock. I've observed that because the 1rst task (not described here) of my main(){...} procedure is to send a signature on the TXD pin, and some characters was wrong. 2/ The code _delay_cycles(10000) doesn't seam to be necessary running with a 16MHz extrernal clock. Not sure if it's same running at other frequencies. 3/ In my example, ACLK runs at 2MHz (LFXT1CLK/8). 4/ I haven't found a TI documentation about __bis_SR_register(SCG0) to stop the internal VLO and take the external clock instead. 5/ It seams that set XTS to "1" in the BCSCTL1 is not necessary. It's "0" in my example. So OK, it works like that. But here is another idea: Is it necessary to run MCLK with a precise frequency ? I answer NO and I can simplify the code with the 2 ideas: 1/ Drive ACLK with a precise quartz external clock to clock the timer. 2/ Drive MCLK with DCOCLK running at high frequency to clock the processor. My proposed code: void main (void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer // Clock after Reset, SMCLK = MCLK = ACLK = DCOCLK = ~1.1MHz: // DCOCTL: 0x60 (DCO_3, RMOD_0) // BCSCTL1: 0x87 (XT2OFF*1, XTS*0, DIVA_0, RSEL_7) // BCSCTL2: 0x00 (SELM_0, DIVM_0, SELS*0, DIVS_0) // BCSCTL3: 0x05 (XT2S_0, LFXT1S_0, XT2OF*0, LFXT1OF*1) // SR: 0x0003 (V*0, SCG1*0, SCG0*0, OSCOFF*0, CPUOFF*0, GIE*0, N*0, Z*1, C*1) // My MSP430G2331 has calibrated values: // CALDCO_1MHZ: 0xA8 (DCO_5, RMOD_8) // CALBC1_1MHZ: 0x86 (XT2OFF*1, XTS*0, DIVA_0, RSEL_6) // Set DCOCLK to calibrated 1MHz... // DCOCTL = 0x00; // Select lowest DCO and RMOD settings // BCSCTL1 = CALBC1_1MHZ; // Set range // DCOCTL = CALDCO_1MHZ; // Set DCO step + modulation // Set DCOCLK ~16MHz... DCOCTL = 0x00; // Select lowest DCO and RMOD settings BCSCTL1 = XT2OFF*1 | XTS*0 | DIVA_0 | 14; //RSEL_0; // Set range DCOCTL = DCO0*3 | 0; //DCO_3 | RMOD_0; // Set DCO step + modulation // Drive ACLK with digital external clock source on XIN pin... // LFXT1CLK = Digital external clock = Quartz Pierce Oscillator = 16MHz // ACLK = LFXT1CLK/8 = 2MHz // MCLK = SMCLK = DCOCLK = ~16MHz BCSCTL1 |= DIVA_3; // ACLK/8 BCSCTL2 = SELM_0 | DIVM_0 | SELS*0 | DIVS_0; // DCOCLK 2x BCSCTL3 = LFXT1S_3 | XCAP_0; // Digital external 0.4- to 16-MHz clock source Benefits are: 1/ Smaller code. 2/ Processor clocked immediately at high frequency and ready to use. jmP Quote Link to post Share on other sites
Rickta59 589 Posted April 30, 2012 Author Share Posted April 30, 2012 But here is another idea: Is it necessary to run MCLK with a precise frequency ? I answer NO and I can simplify the code with the 2 ideas: 1/ Drive ACLK with a precise quartz external clock to clock the timer. 2/ Drive MCLK with DCOCLK running at high frequency to clock the processor. jmP Interesting... I guess last year when I posted this I had about 2 weeks playing with the msp430 G series. Since that time I've learned a lot about the right way to do this. I agree that it is probably better to use the DCO clock for the SMCLK. However, I'd suggest for getting a more accurate Timer clock it makes sense to drive the Timer with an external clock instead of the driving the LFXT1 oscillator logic level. The data sheet say the external clock for the LFXT should be 10-50kHz. It also says that it is perfectly within spec to run the TimerA using an external clock up to 16MHz. It might be better to source the TimerA clock with an external signal and then retain the ACLK for use with the VLO for power savings. Driving the ACLK at 16MHz isn't really legal. Driving the TimerA clock is. Check out this page http://www.ti.com/lit/ds/symlink/msp430 ... df#page=25 and look at TimerA and TACLK. -rick 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.