MSP430
Getting Started

Modified
© Ray Wisman

Resources

YouTube of LaunchPad - http://www.youtube.com/watch?v=GIUcMvukRXs

Wiki description - http://en.wikipedia.org/wiki/TI_MSP430

Texas Instruments MSP430x2xx Family User Guide - http://focus.ti.com/lit/ug/slau144e/slau144e.pdf

Texas Instruments IAR Embedded Workbench Kickstart - http://focus.ti.com/docs/toolsw/folders/print/iar-kickstart.html

Texas Instruments Code Composer Studio - http://focus.ti.com/docs/toolsw/folders/print/ccstudio.html

MSP430 Assembly Language Tools v 3.3 User's Guide  MSP430 - http://focus.ti.com/lit/ug/slau131e/slau131e.pdf

MSP430 C/C++ Programming - http://focus.ti.com/lit/ug/slau132e/slau132e.pdf

MSP430F20xx, G2x01, G2x11, G2x21, G2x31 Code Examples - http://www.ti.com/lit/zip/slac080

MSP430 IAR Assembly Language Getting Started - http://www.ece.uah.edu/~milenka/cpe323-09S/labs/lab2.s09.pdf

Getting Started

The following steps through creating and simulating execution of a basic assembler program.

  1. Download, unzip and install IAR Embedded Workbench to a Windows machine. IAR is the IDE.
  2. Start IAR.

    File | New | Workspace

    Project | Create New Project | asm

    Select as in the image at right
     

  3. Create a folder named First. Open the folder and name the file First also.
  4. A basic assembler program should be created, the IDE should appear as at right.
  5. Project | Rebuild All
  6. Save workspace as First also.
  7. Project | Options

    Select

    Debugger | Simulator

  8. Project | Download and Debug
  9. View | Registers

    Should now appear as below and be ready to simulate execution.

  10. Note the SP register value, probably 0x0000.

    Execute one instruction by:

    Debug | Step Into

    SP register should change, probably to 0x0A00.

 

Simulation

IAR can simulate hardware, CPU and peripherals such as push button and LED I/O.

The following flashes an LED on the Launchpad or a simulated LED in IAR.

  1. Open IAR and follow the instructions above on creating a project.
  2. Copy and paste the following into code window.
    #include "msp430.h"
    ;-------------------------------------------------------------------------------
                ORG     0FC00h                  ; Progam Start (1K Flash device)
    ;-------------------------------------------------------------------------------
    RESET       mov.w   #0280h,SP               ; Set stackpointer (128B RAM device)
    StopWDT     mov.w   #WDTPW+WDTHOLD,&WDTCTL  ; Stop watchdog timer
    SetupP1     bis.b   #001h,&P1DIR            ; Set P1.0 to output direction
                                                ;
    Mainloop    xor.b   #001h,&P1OUT            ; Toggle P1.0
    Wait        mov.w   #02,R15             	   ; Delay to R15
    L1          dec.w   R15                     ; Decrement R15
                jnz     L1                      ; Delay over?
                jmp     Mainloop                ; Again
                                                ;
    ;-------------------------------------------------------------------------------
    ;           Interrupt Vectors
    ;-------------------------------------------------------------------------------
                ORG     0FFFEh                  ; MSP430 RESET Vector
                DW      RESET                   ;
                END
    


     

  3. In Project | Options set the Simulator options as below:
  4. In Project select Download and Debug.
  5. In Peripherals select LED.
  6. In Debug select Autostep.
  7. The simulated LED should turn ON/OFF as the program executes.

Emulation

CCS (Code Composer Studio) can download to the Launchpad hardware and debug.

View the YouTube video and follow the instructions on downloading CCS, creating a project, and emulating.

In creating a new CCS project, enter the Device Variant, MSP430G2231, as below:

When starting a debugging session, you may need to View | Debugger to see the debug panels as below.


 

Polling - LED controlled by Push button

Polling refers to querying a device on its state. The upside of polling is its relative ease of implementation, the downside that it requires the CPU to check the device

Here, the push button input is used to turn LED output on when the button is pressed. The state of the push button is polled to determine whether up or down.

The push button and LED are connected to the CPU via a port (i.e. interface). Ports are bidirectional, providing external input and output.

First a discussion of the relevant ports:

WDTCTL

Controls the watchdog timer, used to execute a system reset when time expires. WDTPW + WDTHOLD turns it off.

P1SEL

Controls which of 8 data bits are selected, 0 selects. Normally all are 0 so not necessary to initialize.

P1DIR

Controls the direction of each of the 8 data bits of port P1. Must be initialized before input or output on data port.

Bit 3 (0x08) is the push button, 0 sets the direction as input.
Bit 6 (0x40) is the green LED (1), 1 sets the direction as output.

P1OUT

Outputs 8 bits of data to port P1.

Bit 6 (0x40) is the green LED, 0 set the LED off.

P1IN

Inputs 8 bits of data from port P1.

Bit 3 (0x08) is the push button, 0 when down

#include <msp430g2231.h>

#define LED_1 0x40						// BIT6

void main(void) {
	WDTCTL = WDTPW + WDTHOLD; 			// Stop watchdog timer
	P1DIR &= ~0x08;					// Push Port 1 P1.3 (push button) as input
	P1DIR |= LED_1; 					// Set P1.6 (LED) to output direction
	P1SEL &= ~0x08;					// Select Port 1 P1.3 (push button)
	P1OUT &= ~LED_1; 					// Set the LED off

	while( 1 ) {
		if( (P1IN & 0x08) == 0) 			// Push button down when bit 3 == 0
			P1OUT |= LED_1;			// Set LED on when button down
		else 
			P1OUT &= ~LED_1;			// Set LED off when button off
	}	
} 					
            .cdecls C,LIST,  "msp430G2231.h"
            .text                           
main        mov.w   #0280h,SP               ; Set stackpointer (128B RAM device)
            mov.w   #WDTPW+WDTHOLD,&WDTCTL  ; Stop watchdog timer
            bis.b   #01000000b,&P1DIR       ; Set P1DIR.6 = 1, output direction
            bic.b   #00001000b,&P1DIR       ; Set P1DIR.3 = 0, input direction
            bic.b   #00001000b,&P1SEL       ; Select Port 1 P1.3 (push button)
            bic.b   #01000000b,&P1OUT       ; Set P1OUT.6 = 0, LED off               

_while                                      ; while(1) {
_if         mov.b   &P1IN, R15              ;    if( P1IN.3 == 0)
            and.b   #00001000b, R15         ;       P1OUT.6 = 1
            jz      _then                   ;    else
            jmp     _else                   ;       P1OUT.6 = 0
_then       bis.b   #01000000b, &P1OUT      ; }
            jmp     _endif
_else       bic.b   #01000000b, &P1OUT
_endif
            jmp     _while
_endwhile
;           Interrupt Vectors
            .sect   ".reset"                ; MSP430 RESET Vector
            .short  main                  
            .end

Interrupts - LED controlled by Push button

Interrupts signal some event has occurred, such as a push button has been pressed.

For this example, the push button input is used to toggle LED output on when the button is pressed. The interrupt only occurs when the button is pressed, not released, causing some complication in turning the LED on when button pressed and off when not pressed; we don't know when the button is released. To avoid the added complication, the interrupt simply toggles the LED.

A discussion of the relevant ports for interrupts:

P1IE

Interrupt mask, bit 3 (0x08) of P1 is the push button; 1 enables/0 disables. Must be 1 for the device to trigger an interrupt.

P1IFG

Clears the interrupt flag, bit 3 (0x08) for push button. When interrupt occurs, the corresponding flag (bit) is set to 1.

An interrupt handler should normally disable the interrupt by setting flag to 0, allowing another interrupt to occur.

#include <msp430g2231.h>

#define LED_1 0x40						// BIT6

void main(void) {
	WDTCTL = WDTPW + WDTHOLD; 			// Stop watchdog timer
	P1DIR |= LED_1; 					// Set P1.6 to output direction
	P1OUT &= ~LED_1; 					// Set the LED off
	P1SEL &= ~0x08;					// Select Port 1 P1.3 (push button)
	P1IE |= 0x08;					// Port 1 Interrupt Enable P1.3 (push button)

	__enable_interrupt();				// Enable interrupts

	while(1);
} 

								// Port 1 interrupt service routine
#pragma vector=PORT1_VECTOR
__interrupt void Port_1(void) {
	P1IFG &= ~0x08; 					// P1.3 Interrupt Flag cleared
	P1OUT ^= LED_1; 					// Toggle LED state
}
            .cdecls C,LIST, "msp430G2231.h"
            .text                           ; Assemble to Flash memory

main        mov.w   #0280h,SP               ; Set stackpointer (128B RAM device)
            mov.w   #WDTPW+WDTHOLD,&WDTCTL  ; Stop watchdog timer
            bis.b   #01000000b,&P1DIR       ; P1DIR.6 = 1, output direction
            bic.b   #00001000b,&P1DIR       ; P1DIR.3 = 0, input direction
            bic.b   #00001000b,&P1SEL       ; Select Port 1 (push button)
            bic.b   #01000000b,&P1OUT       ; P1OUT.6 = 0, LED off               
            bis.b   #00001000b,&P1IE	   ; P1IE.3 = 1, enable interrupt on Port 1, push button
            eint					   ; Enable processor interrupts
	    	
_while      jmp     _while                  ; while(1);
_endwhile

PORT1	      bic.b   #00001000b, &P1IFG	   ; P1IFG.3 = 0, clear push button interrupt
	    	xor.b   #01000000b, &P1OUT	   ; P1OUT.6 toggle LED
	    	reti

;           Interrupt Vectors
            .sect   ".reset"                ; MSP430 RESET Vector
            .short  main                    ;
            .sect   ".int02"                ; Port 1 vector
            .short  PORT1                   ;        
            .end