Sam Mullinix
Sam Mullinix

Reputation: 306

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.

Upvotes: 0

Views: 562

Answers (1)

Sam Mullinix
Sam Mullinix

Reputation: 306

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

Upvotes: 0

Related Questions