我正在尝试解释下面的 TI MSP 430 的汇编代码。当我在调试器中逐步执行这些行时,子程序“beep02”继续循环一段我不知道其起源的时间,然后它突然跳入“WDT_ISR”子程序。
我的假设是,当“狗吠”时,会以某种方式调用看门狗中断服务,并将程序从循环中的正常运行的代码中取出并推进到 WDT_ISR。这个对吗?
.title "morse.asm"
;*******************************************************************************
; Project: morse.asm
; Author: Spencer Gardner
;
; Description: Outputs a message in Morse Code using a LED and a transducer
; (speaker). The watchdog is configured as an interval timer.
; The watchdog interrupt service routine (ISR) toggles the green
; LED every second and pulse width modulates (PWM) the speaker
; such that a tone is produced.
;
; Revisions:
;
; RBX430-1 eZ430 Rev C
; OPTION A OPTION B
; .------------. .------------.
; SW1-->|P1.0^ P3.0|-->LCD_A0 (RED) LED<--|P1.0 P3.0|-->LCD_RST
; SW2-->|P1.1^ P3.1|<->SDA (GREEN) LED<--|P1.1 P3.1|<->SDA
; SW3-->|P1.2^ P3.2|-->SCL NC-->|P1.2 P3.2|-->SCL
; SW4-->|P1.3^ P3.3|-->LCD_RW NC-->|P1.3 P3.3|-->LED_3 (Y)
; INT1-->|P1.4 P3.4|-->LED_5 (GREEN) NC-->|P1.4 P3.4|<--NC
; INTA-->|P1.5 P3.5|<--RX NC-->|P1.5 P3.5|<--NC
; SVO1<--|P1.6 P3.6|<--RPOT NC-->|P1.6 P3.6|<--NC
; SVO2<--|P1.7 P3.7|<--LPOT NC-->|P1.7 P3.7|<--NC
; | | | |
; LCD_D0<->|P2.0 P4.0|-->LED_1 (G) SW_1-->|P2.0^ P4.0|<--NC
; LCD_D1<->|P2.1 P4.1|-->LED_2 (O) SW_2-->|P2.1^ P4.1|<--NC
; LCD_D2<->|P2.2 P4.2|-->LED_3 (Y) SW_3-->|P2.2^ P4.2|<--NC
; LCD_D3<->|P2.3 P4.3|-->LED_4 (R) SW_4-->|P2.3^ P4.3|<--RPOT
; LCD_D4<->|P2.4 P4.4|-->LCD_BL LCD_BL<--|P2.4 P4.4|<--LPOT
; LCD_D5<->|P2.5 P4.5|-->SPEAKER NC-->|P2.5 P4.5|-->SPEAKER
; LCD_D6<->|P2.6 P4.6|-->LED_6 (RED) (G) LED_1<--|P2.6 P4.6|-->LED_4 (R)
; LCD_D7<->|P2.7 P4.7|-->LCD_E (O) LED_2<--|P2.7 P4.7|<--NC
; .------------. .------------.
;
;*******************************************************************************
.cdecls C,LIST,"msp430.h" ; include c header
;------------------------------------------------------------------------------
; System equates
myCLOCK .equ 1200000 ; 1.2 Mhz clock
WDT_CTL .equ WDT_MDLY_0_5 ; WD configuration (Timer, SMCLK, 0.5 ms)
WDT_CPI .equ 500 ; WDT Clocks Per Interrupt (@1 Mhz)
WDT_IPS .equ myCLOCK/WDT_CPI ; WDT Interrupts Per Second
STACK .equ 0x0600 ; top of stack
;------------------------------------------------------------------------------
; External references
.ref numbers ; codes for 0-9
.ref letters ; codes for A-Z
; numbers--->N0$--->DASH,DASH,DASH,DASH,DASH,END ; 0
; N1$--->DOT,DASH,DASH,DASH,DASH,END ; 1
; ...
; N9$--->DASH,DASH,DASH,DASH,DOT,END ; 9
;
; letters--->A$---->DOT,DASH,END ; A
; B$---->DASH,DOT,DOT,DOT,END ; B
; ...
; Z$---->DASH,DASH,DOT,DOT,END ; Z
; Morse code is composed of dashes and dots, or phonetically, "dits" and "dahs".
; There is no symbol for a space in Morse, though there are rules when writing them.
; 1. One dash is equal to three dots
; 2. The space between parts of the letter is equal to one dot
; 3. The space between two letters is equal to three dots
; 4. The space between two words is equal to seven dots.
; 5 WPM = 60 sec / (5 * 50) elements = 240 milliseconds per element.
; element = (WDT_IPS * 6 / WPM) / 5
; Morse Code equates
ELEMENT .equ WDT_IPS*240/1000
;------------------------------------------------------------------------------
; Global variables ; RAM section
.bss beep_cnt,2 ; beeper flag
.bss delay_cnt,2 ; delay flag
;------------------------------------------------------------------------------
; Program section
.text ; program section
message: .string "HELLO CS 124 WORLD" ; PARIS message
.byte 0
.align 2 ; align on word boundary
RESET: mov.w #STACK,SP ; initialize stack pointer
mov.w #WDT_CTL,&WDTCTL ; set WD timer interval
mov.b #WDTIE,&IE1 ; enable WDT interrupt
bis.b #0x20,&P4DIR ; set P4.5 as output (speaker)
clr.w beep_cnt ; clear counters
clr.w delay_cnt
bis.w #GIE,SR ; enable interrupts
; output 'A' in morse code
loop: mov.w #ELEMENT,r15 ; output DOT
call #beep
mov.w #ELEMENT,r15 ; delay 1 element
call #delay
mov.w #ELEMENT*3,r15 ; output DASH
call #beep
mov.w #ELEMENT,r15 ; delay 1 element
call #delay
mov.w #ELEMENT*3,r15 ; output DASH
call #beep
mov.w #ELEMENT,r15 ; delay 1 element
call #delay
mov.w #ELEMENT*7,r15 ; output space
call #delay ; delay
jmp loop ; repeat
; beep r15 ticks of the watchdog timer
beep: mov.w r15,beep_cnt ; start beep
beep02: tst.w beep_cnt ; beep finished?
jne beep02 ; n
ret ; y
; delay r15 ticks of the watchdog timer
delay: mov.w r15,delay_cnt ; start delay
delay02: tst.w delay_cnt ; delay done?
jne delay02 ; n
ret ; y
;------------------------------------------------------------------------------
; Watchdog Timer interrupt service routine
;
WDT_ISR: tst.w beep_cnt ; beep on?
jeq WDT_02 ; n
dec.w beep_cnt ; y, decrement count
xor.b #0x20,&P4OUT ; beep using 50% PWM
WDT_02: tst.w delay_cnt ; delay?
jeq WDT_10 ; n
dec.w delay_cnt ; y, decrement count
WDT_10: reti ; return from interrupt
;------------------------------------------------------------------------------
; Interrupt Vectors
;------------------------------------------------------------------------------
.sect ".int10" ; Watchdog Vector
.word WDT_ISR ; Watchdog ISR
.sect ".reset" ; PUC Vector
.word RESET ; RESET ISR
.end