piglet 14 Posted July 28, 2013 Share Posted July 28, 2013 MSP430G2553 Sorry for what is probably a very basic question - but I've been trying over and over to get MCLK to 16MHz and the TIMERA using SMCLK on external clock crystal. Whatever I seem to do with the control registers I always seem to get the TIMERA on the higher frequency. I'm probably not understanding the user guide, and I can't find anything similar in code using google. Please could someone take pitty on me and paste me a C snippet to do this? Quote Link to post Share on other sites
oPossum 1,083 Posted July 28, 2013 Share Posted July 28, 2013 Select ACLK as the clock souce for the timer. ACLK defaults to the low frequency external xtal (typically 32.768 kHz). TA0CTL = TASSEL_1 | MC_1; Quote Link to post Share on other sites
roadrunner84 466 Posted July 29, 2013 Share Posted July 29, 2013 As oPossum says, if you want to use the low frequency crystal, you'd best use ACLK instead of SMCLK. I a typical situation, the MCLK and SMCLK run at the DCO frequency (1MHz or 16MHz in most cases) and ACLK runs at the LFXT1 frequency (32768Hz when a crystal is used). MCLK is used only fro the CPU and will be turned off in any low power mode. SMCLK will run in LPM0 and LPM1 as well, but will be turned off in LPM2 through LPM4. ACLK will remain active in all except LPM4. Quote Link to post Share on other sites
zinob 2 Posted July 29, 2013 Share Posted July 29, 2013 Assuming you use the crystal that came with the Launchpad you should start by setting the right capacitance on the port: BCSCTL3 |= XCAP_3; //Set to 12.5pf Then getting TimerA to use the crystal should, as oPossum says be as easy as TA0CTL = TASSEL_1 | MC_1; though remember that you should do this after setting up everything else like TA0CCR0 If it still doesn't work try to run it in debugger mode (that should run the LFXT1 of the debuggers clock IIRC). If that works you probably have made a bad solder or have a dead crystal. Also please note that the crystal is about three times faster (at 32kHz) than the VLO (12kHz) so this will speed up TA some. to set the MCLK to 16 MHz simply use: BCSCTL1 = CALBC1_16MHZ; // Set DCO DCOCTL = CALDCO_16MHZ; The example below will blink the led at about 2 Hz, if you change CALBC1_16MHZ and CALDCO_16MHZ to CALBC1_16HZ and CALDCO_1MHZ respectively you will notice that the LED stays on for a much longer time, mostly noticeable as an increase in brightness. This is due to the fact that the _delay_cycles part in the ISR now runs 16 times as long. #include <msp430g2553.h> void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT BCSCTL3 |= XCAP_3; //Set the LFXT cap to 12.5pf BCSCTL1 = CALBC1_16MHZ; // Set DCO DCOCTL = CALDCO_16MHZ; P1DIR |= BIT0+BIT6; // because we allways need to blink LED-s P1OUT &= ~(BIT0+BIT6); //Activate Timer A0 TA0CCTL0 = CCIE; // CCR0 interrupt enabled TA0CCR0 = 16383; TA0CTL = TASSEL_1 + MC_1; // ACLK, upmode _BIS_SR(LPM3_bits + GIE); // Enter LPM3 w/ interrupt } // Timer A0 interrupt service routine #pragma vector=TIMER0_A0_VECTOR __interrupt void Timer_0A (void) { P1OUT |=BIT0; _delay_cycles(40000); P1OUT &=~(BIT0); } Quote Link to post Share on other sites
roadrunner84 466 Posted July 29, 2013 Share Posted July 29, 2013 What kind of terrible example is that?!! You're using a timer to act upon an LED, but then you hardcode a delay inside your timer ISR! #include <msp430.h> void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT BCSCTL3 |= XCAP_3; //Set the LFXT cap to 12.5pf BCSCTL1 = CALBC1_16MHZ; // Set DCO to 16MHz DCOCTL = CALDCO_16MHZ; P1DIR |= BIT0+BIT6; // because we allways need to blink LED-s P1OUT &= ~(BIT0+BIT6); //Activate Timer A0 TA0CCTL0 = CCIE; // CCR0 interrupt enabled TA0CCR0 = 8191; // (32768 Hz divided by 4) - 1 ==> 4 "toggles" per second TA0CTL = TASSEL_1 + MC_1; // ACLK, upmode _BIS_SR(LPM3_bits + GIE); // Enter LPM3 w/ interrupt } // Timer A0 interrupt service routine #pragma vector=TIMER0_A0_VECTOR __interrupt void TIMER_A0_ISR(void) { P1OUT ^=BIT0; // toggle the value of P1.0 } Quote Link to post Share on other sites
zinob 2 Posted July 29, 2013 Share Posted July 29, 2013 (edited) @@roadrunner84 What kind horror is this you ask? Well exactly the kind of horror I was going for of course! The point was to give one way of seeing the ACLK (the frequency) and another way of seeing the MCLK (the duration). Allegedly a clearer way might have been to do something like this instead of letting it go in to LPM and just used a toggle in the ISR (like you did). _BIS_SR(GIE); for(;{ _delay_cycles(1000000); /* Yes _delay_cycles is ugly but the human * eye simply cannot cope with 16 MHz. And * setting up TA1 to the MCLK would make * the example more confusing. */ P1OUT ^=BIT6; } My code was just a quick 2 minute hack, didn't really spend any time trying to make it neat, just passable to illustrate something. While your code is both saner and better from a power perspective there is nothing to illustrate the MCLK speed. Edited July 29, 2013 by zinob Quote Link to post Share on other sites
piglet 14 Posted July 30, 2013 Author Share Posted July 30, 2013 Thank you all - much appreciated. I really don't know what I did wrong, but my code was very close to these examples and didn't work as I was expecting. With these pointers I got it working...if only for a few seconds... Using code composer I did a load of control-z to step back to see what I changed to try and let you know what I'd done that broke it, then stepped forward again by holding control-y to get the latest and it left the code completely muddled up and not working. *mutter*. Now I'm left with a corrupted project I didn't take a copy of when it was working! Oh the joys of software.... Quote Link to post Share on other sites
tripwire 139 Posted July 30, 2013 Share Posted July 30, 2013 Using code composer I did a load of control-z to step back to see what I changed to try and let you know what I'd done that broke it, then stepped forward again by holding control-y to get the latest and it left the code completely muddled up and not working. *mutter*. Now I'm left with a corrupted project I didn't take a copy of when it was working! It may be too late to try this, but CCS has a basic file history system which comes in handy when you fix/break something unexpectedly. If you right click on a file in Project Explorer you can select "Compare with->Local History..." That brings up the history tab which lists snapshots of the file by date and time. You can then compare the current file against old versions to see what's changed. If needed you can replace the current file contents with an older version too. Quote Link to post Share on other sites
piglet 14 Posted July 31, 2013 Author Share Posted July 31, 2013 Thank you. I went back through the project manually and corrected all the corruptions, finding a few lines I'd removed previously were now back in. Some lines changed and duplicated as I put the cursor on them which was rather worrying. I guess Code Composer had got into a real muddle. When I tried to compile it kept highlighting lines which weren't in error, with spurious error messages. project->clean, restart composer, move a few lines around and then back where they'd been in the first place and it compiled OK. Hurrah. Now to carry on with the real logic I wanted in the first place. I wish I had more than a few minutes a day to tinker. Work/wife/kids get first call on my time.... 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.