我正在尝试让 MSP430 上的红灯在装配中每次按下按钮时逐渐闪烁
I am trying to make the red light on an MSP430 blink incrementally for each button press in Assembly
我试图让 MSP430 上的灯在每次按下按钮时闪烁,并跟踪按钮被按下的次数。例如,按下一个按钮将闪烁一次,然后按下一个按钮将闪烁两次等。我已经生成了使灯响应按钮按下的代码,以及使灯闪烁的代码,但是我无法将两者结合起来使灯仅闪烁一定次数。
; 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
//
使灯每隔一秒闪烁一次的代码
#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)
我试图将这两段代码结合起来,但它只会导致闪烁的灯光,我可以通过按下按钮在循环之间切换。我对 IAR 中的寄存器递增也有疑问。当我单步执行调试器时,它会在按下按钮时递增 R8,但是,当我简单地按下转到 运行 程序时,它不会在寄存器菜单中递增。任何正确方向的想法、评论或指示将不胜感激。
注意:虽然我知道这在 C 中可以更容易地实现,但我必须在 Assembly 中实现。
所以我终于想通了。事实证明,IAR 不会在 Go 命令上动态更新寄存器,而只会在单步执行时更新。我发现这一点是因为在我结束并重新启动程序后,寄存器会增加。这意味着代码工作正常,但没有实时显示。在我相信代码是正确的之后,我实施了其余的增量闪烁功能,并最终收到了一些按预期执行的工作代码。再次感谢那些花时间尝试帮助我的人。
#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
我试图让 MSP430 上的灯在每次按下按钮时闪烁,并跟踪按钮被按下的次数。例如,按下一个按钮将闪烁一次,然后按下一个按钮将闪烁两次等。我已经生成了使灯响应按钮按下的代码,以及使灯闪烁的代码,但是我无法将两者结合起来使灯仅闪烁一定次数。
; 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
// 使灯每隔一秒闪烁一次的代码
#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)
我试图将这两段代码结合起来,但它只会导致闪烁的灯光,我可以通过按下按钮在循环之间切换。我对 IAR 中的寄存器递增也有疑问。当我单步执行调试器时,它会在按下按钮时递增 R8,但是,当我简单地按下转到 运行 程序时,它不会在寄存器菜单中递增。任何正确方向的想法、评论或指示将不胜感激。
注意:虽然我知道这在 C 中可以更容易地实现,但我必须在 Assembly 中实现。
所以我终于想通了。事实证明,IAR 不会在 Go 命令上动态更新寄存器,而只会在单步执行时更新。我发现这一点是因为在我结束并重新启动程序后,寄存器会增加。这意味着代码工作正常,但没有实时显示。在我相信代码是正确的之后,我实施了其余的增量闪烁功能,并最终收到了一些按预期执行的工作代码。再次感谢那些花时间尝试帮助我的人。
#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