This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

CCS/MSP430F5529: MSP430 operating LEDs with interrupts and switches in assembly

Part Number: MSP430F5529


Tool/software: Code Composer Studio

I am trying to make a basic program that will toggle LED2 when SW2 is pressed.  I believe I have the setup done correctly, but I think my interrupt function is the problem.  Can you guys spot my error here?  Thank you in advance.

;-------------------------------------------------------------------------------
; MSP430 Assembler Code Template for use with TI Code Composer Studio
;
;
;-------------------------------------------------------------------------------
            .cdecls C,LIST,"msp430.h"       ; Include device header file

;-------------------------------------------------------------------------------
            .def    RESET                   ; Export program entry-point to
                                            ; make it known to linker.
            .def	SW2_ISR
;-------------------------------------------------------------------------------
            .text                           ; Assemble into program memory.
            .retain                         ; Override ELF conditional linking
                                            ; and retain current section.
            .retainrefs                     ; And retain any sections that have
                                            ; references to current section.

;-------------------------------------------------------------------------------
RESET:       mov.w   #__STACK_END,SP         ; Initialize stackpointer
StopWDT:     mov.w   #WDTPW|WDTHOLD,&WDTCTL  ; Stop watchdog timer

Setup:
			bis.b	#00000001b, &P1DIR		; set P1.0 as output (LED1)
            bis.b   #10000000b, &P4DIR      ; Set P4.7 as output (LED2)
            bic.b   #00000001b, &P1OUT		; Turn LED1 off
            bic.b	#10000000b, &P4OUT		; Turn LED2 off
            bic.b	#00000010b, &P2DIR		; Set P2.1 as input for SW1
            bis.b	#00000010b, &P2REN		; Enable pull-up resistor at P2.1
            bis.b	#00000010b, &P2OUT		; Required for proper IO
			bic.b	#00000010b, &P1DIR		; Set P1.1 as input for SW2
			bis.b	#00000010b, &P1REN		; Enable pull-up resistor at P1.1
			bis.b	#00000010b, &P1OUT		; Required for proper IO
            bis.w   #GIE, SR                ; Enable Global Interrupts
            bis.b	#00000010b, &P2IE		; Enable Port 2 interrupt from bit 1
            bis.b	#00000010b, &P2IES		; Set interrupt to call from hi to low
            bic.b	#00000010b, &P2IFG		; Clear interrupt flag
            bis.b	#00000010b, &P1IE		; Enable Port 1 interrupt from bit 1
            bis.b	#00000010b, &P1IES		; Set interrupt to call from hi to low
            bic.b	#00000010b, &P1IFG		; Clear interrupt flag
;-------------------------------------------------------------------------------
; Main loop here
;-------------------------------------------------------------------------------

InfLoop:
            jmp		$						; Loop here until interrupt

SW2_ISR:
            bic.b   #00000010b, &P1IFG      ; Clear interrupt flag

ChkSw:      bit.b   #02h, &P1IN             ; Check if SW2 is pressed
											; (0000_0010 on P1IN)
            jnz		LExit					; If not zero, SW2 not pressed
											; Loop and check again
Debounce:   mov.w   #2000, R15              ; Set to (2000 * 10 cc )

SWD20ms:    dec.w   R15                     ; Decrement R15
            nop
            nop
            nop
            nop
            nop
            nop
            nop
            jnz     SWD20ms                 ; Delay over?
            bit.b   #00000010b, &P1IN       ; Verify SW2 is still pressed
           	jnz		LExit					; If not, wait for SW2 press

LEDon:      bis.b   #008h, &P4OUT           ; Turn on LED1

SW2wait:    bit.b   #002h, &P1IN            ; Test SW2
            jz      SW2wait                 ; Wait until SW2 is released
            bic.b   #008h, &P4OUT           ; Turn off LED1

LExit:      reti
;-------------------------------------------------------------------------------
; Stack Pointer definition
;-------------------------------------------------------------------------------
            .global __STACK_END
            .sect   .stack

;-------------------------------------------------------------------------------
; Interrupt Vectors
;-------------------------------------------------------------------------------
            .sect   ".reset"                ; MSP430 RESET Vector
            .short  RESET
            .sect   ".int20"                ;P1.x Vector
            .short  SW2_ISR
            .end

  • Lines 69 and 73 should say "LED2" in the comment instead of "LED1"

  • You enable global interrupts first then fiddle with the port interrupts. Enabling port interrupts, setting the edge, and then clearing the flag. Which is messed up.

    Clearing the flag in particular is a wasted effort since it would already have resulted in an interrupt. Really a problem since I see only one ISR and two enabled interrupts.

    For switch debouncing there are better methods:

    Oh, if don't set a low power mode in your main loop you are really missing out on one of the best features of the MSP430.

**Attention** This is a public forum