Search code examples
assemblymsp430iar

I am trying to make the red light on an MSP430 blink incrementally for each button press in Assembly


I am attempting to make the light on an MSP430 blink with each button press and keep track of the number of times the button has been pressed. For example, one button press would blink once and the next button press would blink twice ect. I have produced the code that makes the light respond to a button press, and the code that makes the light blink, however I am having trouble integrating the two to make the light blink only a certain number of times.

 ; Code to make light to on with button press, also register increment hold
 #include "msp430.h"                     ; #define controlled include file

    NAME    main                    ; module name

    PUBLIC  main                    ; make the main label vissible
                                    ; outside this module
    ORG     0FFFEh
    DC16    init                    ; set reset vector to 'init' label

    RSEG    CSTACK                  ; pre-declaration of segment
    RSEG    CODE                    ; place program in 'CODE' segment

init:   MOV     #SFE(CSTACK), SP        ; set up stack

main:   NOP                             ; main program
    MOV.W   #WDTPW+WDTHOLD,&WDTCTL  ; Stop watchdog timer
    bis.b #001h, &P1DIR
    bic.b #008h, &P1DIR
    bis.b #008h, &P1REN
    bis.b #008h, &P1IE              ; Open Ports
    bis.b #008h, &P1IFG
    BIS.B #008h, &P1OUT
    mov.w #00000000h, R8            ; Register to hold incremental   value          

    BIS.W #CPUOFF+GIE, SR           ; Enter LPM
    nop                             ; Skip Cycle
P1_ISR
    Bis.b #1h, P1DIR                ; Change Light status
    xor.b #001, &P1OUT
    bic.b #008h, &P1IFG
    add.w #1h, R8                   ; Add one to R8
    mov.w R8, R9                    ; Copy R8 to R9
    reti                            ; Exit Interrupt

    COMMON INTVEC
    ORG RESET_VECTOR                ; Interrupt Vector
VECTOR:
    ORG PORT1_VECTOR
    DW P1_ISR
    JMP $
    END

// Code to make light flash every other second

 #include "msp430.h"                     ; #define controlled include file

    NAME    main                    ; module name

    PUBLIC  main                    ; make the main label vissible
                                    ; outside this module
    ORG     0FFFEh
    DC16    init                    ; set reset vector to 'init' label

    RSEG    CSTACK                  ; pre-declaration of segment
    RSEG    CODE                    ; place program in 'CODE' segment

init:   MOV     #SFE(CSTACK), SP        ; set up stack

main:   NOP                             ; main program
    MOV.W   #WDTPW+WDTHOLD,&WDTCTL  ; Stop watchdog timer
    BIS.B #LFXT1S_2, &BCSCTL3
    BIC.B #OFIFG, &IFG1 
    BIS.W #SCG0+SCG1, SR

    BIS.B #SELM_3, &BCSCTL2
    BIS.B   #DIVA_3, &BCSCTL1
    BIS.B   #DIVM_3+DIVS_3, &BCSCTL2


    mov.w #CCIE, &TACCTL0
    MOV.W #1000, &TACCR0
    MOV.W #TASSEL_1+MC_1, &TACTL
    BIS.W #CPUOFF+GIE, SR

TA0_ISR:
    Bis.b #1h, P1DIR 
    xor.b   #001h, &P1OUT           
    reti

    COMMON INTVEC
    ORG TIMER0_A0_VECTOR
    DW TA0_ISR


    JMP $                           ; jump to current location '$'
                                    ; (endless loop)

I have attempted to combine both these sections of code, however it just results in a blinking light that I can toggle between cycles with the button press. I also have an issue with the register incrementing in IAR. When I step through the debugger, it increments R8 on a button press, however, when I simply press go to run the program, it will not increment in the register menu. any thoughts, comments, or pointers in the correct direction would be greatly appreciated.

Note: While I understand that this can be implemented in C much easier, I must do this in Assembly.


Solution

  • So I finally figured it out. Turns out IAR will not dynamically update Registers on the Go command, but only on step throughs. I found this out because after I would end and restart programs, the register would be incremented. This means that the code was working correctly, but not showing in live time. After I trusted that the code was correct, I implemented the rest of the incremental blinking features and finally received some working code that performed as expected. Thanks again to those who took time to try and assist me.

    #include "msp430.h"                     ; #define controlled include file
        NAME    main                    ; module name
        PUBLIC  main                    ; make the main label vissible
                                        ; outside this module
        ORG     0FFFEh
        DC16    init                    ; set reset vector to 'init' label
        RSEG    CSTACK                  ; pre-declaration of segment
        RSEG    CODE                    ; place program in 'CODE' segment
    init:   MOV     #SFE(CSTACK), SP        ; set up stack
    main:   NOP                             ; main program
        MOV.W   #WDTPW+WDTHOLD,&WDTCTL  ; Stop watchdog timer
        bis.b #001h, &P1DIR
        bic.b #008h, &P1DIR
        bis.b #008h, &P1REN
        bis.b #008h, &P1IE              ; Open Ports
        bis.b #008h, &P1IFG
        BIS.B #008h, &P1OUT
        xor.b #001, &P1OUT
        mov.w #00000000h, R8            ; Register to hold incremental     value 
        mov.w #00000000h, R10
        BIS.W #CPUOFF+GIE, SR           ; Enter LPM
        nop                             ; Skip Cycle
    P1_ISR
        bic.b #008h, &P1IFG 
        CMP.W #0, R10
        jz Skip1
        add.w #1h, R8       
        mov.w R8, R9                    ; Copy R8 to R9
    CHANGEL:xor.b #001, &P1OUT              ; Add one to R8
        mov.w #050000,R15 ; Delay to R15
    Wait:   dec.w R15 ; Decrement R15
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        jnz Wait 
    CHANGEOFF:xor.b #001, &P1OUT                ; Add one to R8
        mov.w #050000,R15 ; Delay to R15
    Wait2:  dec.w R15 ; Decrement R15
        nop
        nop
        nop
        nop
        nop
        nop
        nop
        jnz Wait2
        dec.w R9
        jnz CHANGEL
     Skip1:     
        mov.w #1, R10
        reti                            ; Exit Interrupt
    
        COMMON INTVEC
        ORG RESET_VECTOR                ; Interrupt Vector
    VECTOR:
        ORG PORT1_VECTOR
        DW P1_ISR
        JMP $
        END