A small MSP430 board

I couple of months back I acquired a TI Launchpad, their loss-leader development board for their MSP430 family of microprocessors. I’ve had a long-term interest in the MSP430 as an alternative in the realm of 8-/16- bit micros.

Out of the box, I was able to the set up the mspgcc toolchain, and the other installation details were amalgamated from the interwebs. I believe the msp toolchain is now in the Ubuntu repositories, so all of the compilation la-di-da is a thing of the past.

Sadly, I was without an application.

The next week my coworker asked me where he could find a signal generator — I made the mistake of inquiring and it turned out he needed a 30Hz (later 25Hz) synchronization pulse for a cluster of computer vision cameras. Clearly a signal gen would be massive overkill (and would tie up the generator for months to come), so I offered to make a signal generator for him.

My first version was built on the Launchpad, and worked fine. Last week I finally got around to constructing a self-contained version.



Total time to first prototype was perhaps four hours, though I went through three iterations of the clocks — first using the internal very-low power oscillator (VLO), then the internal digitally-controlled oscillator (DCO), and finally using an external 32.768 kHz watch crystal. Each step was an attempt to find a little bit more timing accuracy.

For the curious, the schematics are here

It’s not the minimum number of components to run an MSP430, but close enough. Nor is it the smallest MSP that would do that job. But the G2211 came with the Launchpad.

The USB port only provides power (it’s convenient and there’s no chance of getting the voltage or polarity wrong). The C connecting reset to ground is recommended, but I’m not sure it’s mandatory. It should provide a little highpass filtering on the reset line. As built there’s no in-circuit programming, hence the socketed processor. It wouldn’t be too hard to add an ISP but I didn’t see the point.

The code is as follows (or here)

/******************************************************************************
 * 25Hz flasher.  Ripped unashamedly from the Launchpad demo app.
 * This version is targeted at the 430G2211 with a watch crystal
 ******************************************************************************/

//#include   <-taken care of by includeing io.h and setting -mmcu=msp430x2012 in cflags
#include 
#include 


#define     LED0                  BIT0
#define     LED1                  BIT6
#define     LED_DIR               P1DIR
#define     LED_OUT               P1OUT

// The Launchpad has two LEDs
// but the app board has just one
#undef      TWO_LEDS

#define     TA_OUT0               BIT2
#define     TA_DIR                P1DIR

void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT

  TA_DIR |= TA_OUT0;
  P1SEL  |= TA_OUT0;                        // Should set Pin 1.2 to TimerA out1

#ifdef TWO_LEDS
  LED_DIR |= LED0 + LED1;
  LED_OUT &= ~LED1;
#else
  LED_DIR |= LED0;
#endif
  LED_OUT |= LED0;                          // To enable the LED toggling effect
  // Use a 32.768 KHz watch crystal
  BCSCTL1 = XT2OFF;
  BCSCTL2 = SELM_3 | SELS;                   // MCLK = SMCLK = LFXT1CLK
  BCSCTL3 &= ~(LFXT1S_3);                    // Clear LFXT1Sx for 32678 crystal on LFXT1
  BCSCTL3 |= XCAP_3;                      // Set ~12 pF capacitance 

  // As set up, MC_1 means count to CCR0
  // OUTMOD_7 means reset at CCR1, set at CCR0
  // ISR make the LEDs behave similarly -- RED on at CCR1, GREEN on at CCR0
  //
  // Uses toggle mode, OUT1 toggles every time TimerA == TACCR1
  // And TimerA is in Up mode, so it counts 0->TACCR0, then resets
  // So the half-period of the output is set by TACCR0
  //
  // 32768 / 655 = 50.02
  // 
  // So ~655 for 25MHz
  TACCR0 = 655;                             // By calibration
  TACTL = TASSEL_1 |  MC_1;                  // TACLK = SMCLK, Up Mode
  TACCTL0 = CCIE;
  TACCTL1 = OUTMOD_4;                // Toggle mode
  TACCR1 = 0;

  WRITE_SR(GIE);                     // Enable interrupts

  /* Main Application Loop */
  while(1) {
    __bis_SR_register(LPM3_bits + GIE);          // LPM0 with interrupts enabled
    //nop();
  }

}

interrupt(TIMERA0_VECTOR) ta0_isr(void)
{
  static unsigned int count = 0;

  TACCTL0 &= ~CCIFG;

  if( ++count >= 25 ) {
#ifdef TWO_LEDS
    LED_OUT ^= (LED0 | LED1);
#else
    LED_OUT ^= LED0;
#endif
    count = 0;
  }

}

Not the tidiest code in the world. The 25Hz square wave is driven by the TimerA, while the flashing LEDs (the Launchpad board has two blinkenlights, while my board has just one) are driven my a more conventional counter-in-an-ISR. I’m quite sure I could fix it up so the LED is controlled by a timer as well, but I haven’t bothered.

Leave a Reply

Your email address will not be published. Required fields are marked *