Thursday, March 15, 2012

Using ACLK and the 32kHz Crystal

The other day I decided to build a timer to control some lights in my apartment. As I hope to expand this mini project into a full-fledged home automation system built around the CC430, a simple light timer from Walmart would not do! Obviously, the LaunchPad is the perfect tool for the job.

For example, let's say that I wanted to keep my lights on for 5 hours at night while I am on vacation. The first thing you will need is a way to tell time; this requires some sort of real-time clock. Since the high frequency clock sources on the MSP430 are not accurate enough to keep reliable time over a large period of time (anything greater than 1 minute in my opinion), a lower frequency clock will be needed. Though many of the newer MSP430s have built in 32kHz clocks, such as the the MSP430F5510, the value line series does not!

The 32.768kHz Crystal

The first step for building this project is to install the 32.768kHz crystal onto the LaunchPad. From this point onward I will just be calling this 32kHz for simplicity. You might be wondering why a real time clock is based on 32.768kHz; 32768 is exactly 2^15. This number can be divided down using binary values to give you a frequency of 1Hz, or a period of 1 second. This is why 32kHz is the standard frequency used in real-time clocks.


The above image shows the crystal soldered onto my LaunchPad. There are many methods you can use to solder this on, one of which is nicely documented on Justin's Tech blog. I ended up soldering the base of the crystal first, ensuring that the clock was positioned correctly before I soldered the small leads. Use any method that works for you.

The LED Hello World

The first thing you should do once you have this soldered onto your board, is test it. Making sure that everything works before you start a complicated project is very important. Let's make an LED turn on every two seconds, for one second. Instead of changing the timer output pins directly as we did in an earlier post, lets blink the LED manually so that we can easily expand the functionality of this program in a future post. There are a few things you should notice in the code below.


In this code we divide the clock by 64 (lines 26 and 37) which causes the timer to increment 512 times a second (512Hz). Once the clock counts up to 512, one second has gone by, and an interrupt is thrown. Now that we are entering an interrupt routine instead of automatically toggling the output, we can use this interrupt routine in the future to expand the functionality of this code.

The last important line of code is line 27, where a capacitance value is set. This value matches the capacitors that come installed on your LaunchPad. In the next section, I will elaborate slightly on what this capacitance is.


Edit: This statement is actually incorrect. A big thank you goes out to Jens-Michael Gross for pointing it out to me.
"The capacitance setting is an internal switch that enables some silicon capacitors on the MSP die. The selection has to match the required load capacitance of the used watch crystal. You can set it to minimum (plain parasitic pin capacitance) and apply external capacitors of the proper value, if you want. However, the available options are sufficient for the most watch crystals, so external capacitors are unnecessary, even counterproductive. And external capacitors have a large tolerance that affects the crystal frequency. The LaunchPad I just got has no capacitors installed (the C21 and C22 pads are empty, as it should be if the XCAP options are used."
Custom Design

One thing I wanted to mention before this post comes to a close, is how you can take this design off the LaunchPad and make it your own. Many projects work out so well that you just want to create a PCB or make it permanent in some other way.

Working with crystals can be tricky for beginners, as there is one thing you must look out for. All crystals require a load capacitance to remain stable, Wikipedia (Pierce Oscillator) and Texas Instruments both have some quality information on the topic. The value of these two capacitors depend on which crystal you use. Even two crystals with the same frequency which are made by the same manufacture might require different load capacitor values. Please check the crystal's datasheet for this information. For example, the LaunchPad uses 12pF capacitors to load the crystal we just installed, yet many crystals require 22pF.


Edit: This statement is actually incorrect. Another big thank you goes out to Jens-Michael for pointing it out to me. Thanks for reading!
"12pF is the typical load for most crystals I've ever seen. But due to the electric connection, a 12pF load means [there will be 2] 24pF capacitance on each of the crystals sides. Reason is that (seen from the crystal), the two capacitors are in series to each other and parallel to the crystal. […] Subtract the ~2pF pin capacitance of the MSPs pins and you get [two separate] 22pF [for] external capacitors, resulting in 12pF load. The XCAP settings already include pin capacitance and the /2 factor."
A bit more information and great advice from Jens-Michael!
"Experiments have shown that the G devices (in opposition to the AFE2x and some other x2 family devices without HFXT1 input) will accept a high-frequency TTL clock signal (e.g. from a self-oscillating quartz oscillator) on the XTIN pin, when in bypass mode. The Datasheet limits external clock to 50kHz, but there were no problems with 16MHz."
Conclusion

As you can see by the following screenshot from my oscilloscope, this timer is pretty darn accurate.


Hopefully you enjoyed this post and found it informative. I am going to try to keep things a bit more bite-sized from now on. Let me know what you think.

Post links to your projects which use the ACLK or the 32kHz crystal in the comment section below!

24 comments:

  1. "When using a timer on the MSP430, it is important to divide the source clock down to a reasonable frequency", why? is it more engery efficient or is there some other reason

    ReplyDelete
    Replies
    1. Nice catch! I should have been a bit more clear with that statement.

      Edit: "When using a timer on the MSP430 to keep track of long periods of time, it is important to divide the source clock down to a reasonable frequency."

      Why? Let me give you an example: if you are using a 16MHz clock to measure out 1 second, you need 16 million timer cycles to get this value. Since the timer is a 16-bit timer, you can only count up to 2^16. By diving the 16MHz clock by 512 (8*8*8), you get a base frequency of 31.25kHz. Now you can use your 16-bit timer to count up to a second by setting the compare register to 31250.

      Delete
    2. hm ok but for 32768 Hz you wouldnt have to divide the clock since that is (as you stated) 2^15 and therefore within the range of the timer register

      Delete
    3. Correct. Originally I was going to have the timer keep track of every minute, not every second. If this were the case, the clock would have to be divided down. I will remove that statement from the post, hopefully it will alleviate some confusion.

      Thanks!

      Delete
  2. Thanks for nice project. question: Can I use MSP430G2231, if so should "TIMER0_A0_VECTOR" be changed to "TIMERA0_VECTOR"
    Are there other changed I must do?

    ReplyDelete
    Replies
    1. I believe that is the only thing that needs to be changed. If you create a project in CCS and attempt to run the code, it will tell you if you have any errors. You can check in the devices header file if you cannot determine what the correct definition is.

      Delete
  3. Are you going to transfer this code over to a CC430 in the future? Or are you planning on sticking to a Launchpad and using and external radio (i.e. a CC2000 series device)?

    ReplyDelete
    Replies
    1. Good question. The current plan is to transfer the code to a CC430. I am in the process of building a small CC430 module, hopefully the first prototype will work well enough to continue forward. Once I have more free time, I will be able to finish the layout.

      Delete
    2. Nice! I would love to see how you go through all the board design and changing of code to make it work on a CC430. I am in the planning stages of either using a CC430 or a MSP430 + C2000 radio to a low-power application as well... I would like to see how your project develops over time!

      Keep up the good work

      Delete
  4. Hi,
    I have a 32K crystal, and I want timer to trigger after 1 minute. Is it possible to do so ?
    At this point my timer setting is:
    TACTL = TASSEL_1 | MC_2 | ID_3 | TAIE; //gives me 32k/ (8*64 K) = trigger after 16 second.
    Then I used a global variable , volatile minute_counter.
    #pragma vector=TIMERA1_VECTOR
    __interrupt void Timer_A (void)
    {
    switch (TAIV)
    {
    case 2: //CCR1
    break;
    case 4: //CCR2
    break;

    case 10: //once every 1 minute
    minute_one++;
    if (minute_one ==4)
    {
    my_code_to_do_stuff_after_this_trigger;
    }
    break;
    }
    _BIC_SR_IRQ(LPM3_bits); // Exit LPM3 after reti
    }

    Will this work?
    At this moment it is stuck in some UART code, and I cant debug it.
    Thanks

    ReplyDelete
  5. Do you know what Makey Makey is? If not google for it. It is based on Arduino, it would be great to make it on a MSP430 Launchpad base!
    bye

    ReplyDelete
  6. Hi,
    I am really confused about the accuracy of clock in MSP430 lauhchpad devices. I am using msp430g2231 and 2553. In your example, it is working in Lowpower mode 3. I tried the above code without usign the LPM3, and instead I am doing some other operations in a while loop. Then it is not triggring the interrupt. So the timer will use the ACLK only when it is in LPM3?

    I used PIC,AVR etc and there I can use the external Hf crystal and I can achieve a great accuracy but here in MSP430 launchpad, still I don't know how to do things with such accuracy.

    ReplyDelete
  7. Okay am sorry, I forgot to activate the GIE. Now its working not only in lpm, but the other mode also..

    ReplyDelete
  8. hey GREAT WORK..........explains everything in a well defined manner
    but can u pls group all the tuts on msp430 in an ascending order as it is very difficult to find the tuts
    thx reply soon.............

    ReplyDelete
  9. can we use a crystal of higher frequency than the normal 32KHz available with the launchpad?

    ReplyDelete
    Replies
    1. According to the datasheet on the MSP430G2553, the crystals which you can use on XT1 must be between 10kHz and 50kHz. I'm there these numbers can be stretched a bit (although it is not recommended). You should ask on the e2e.ti.com forums fora more detailed explanation.

      Delete
  10. My clock is acting strangely because it seems that my XIN has no pull-up or pull-down. The interrupts are delayed and erratic.

    However, when I pull XIN up or down manually using an external resistor, the timer works perfectly.

    I'm using your code exactly as posted here.

    Any idea how I can enable the internal pullup or pulldown resistors for XIN? Is there something similar to writing 1 or 0 (for pullup/pulldown) to the respective bit in PxOUT and then writing 1 to the respective bit PxREN?

    ReplyDelete
    Replies
    1. As long as you are using the crystal provided in the LaunchPad kit and follow the directions exactly (and keep the code the same), everything should work fine. There is no reason to hook up a pull-up or pull-down resistor to a crystal, it is just not how they work. It might be possible that you have a solder bridge somewhere as well. Sorry I can't be of more help.

      Delete
  11. I am completely new to msp430. I want to use this board for controlling some LEDs accurately in the order of milliseconds. By the explanation that has been given it seems that the minimum is 1 second. Is that so?

    ReplyDelete
    Replies
    1. Actually, by changing a few parameters you can change the interrupt time to anything you want (as long as it is less than your clock rate). Check out one of my earlier posts for more information on MSP430 timers.

      http://www.msp430launchpad.com/2010/07/timers-and-clocks-and-pwm-oh-my.html

      Delete
  12. Hello there, You have done an excellent job.
    job online

    ReplyDelete
  13. Hi Nicholas, has the "printf()" been revised to be used in a MSP430G2553.
    I am unable to use it in the form as available on your blog
    of 08 June 2012.

    ReplyDelete
  14. I tested your code but led was turn on cca 2,5s. When I changed CCR0 on 30720 led turn on cca 2:30 (2.5m). Can you help my?

    ReplyDelete