📄 fc430_es417_iar.s43
字号:
mov.w &tachRPM, R12 ; Move current RPM value into temp
call #dispTach ; Call the func to disp RPM on LCD
cmp.w &tachRPM, &lastRPM ; Is (tachRPM > lastRPM) ?
jc dwnArrow ; No, RPM has decreased
upArrow: call #dispUpArrow ; Yes, RPM has increased
jmp saveRPM ; Save current RPM for next time
dwnArrow: call #dispDownArrow ; Enable down arrow - show decrease
saveRPM: mov.w &tachRPM, &lastRPM ; Save current RPM for next history
ret ; Return from subroutine
;*************************** LCD DISPLAY FUNCTIONS ****************************
clearLCD: mov.w #0x00, R15 ; Execute this loop 17 times
cLCD0: cmp.w #0x11, R15 ; Compare loop count to loop countr
jge cLCDdone ; Jump if greater than or equal to
mov.w &LCD, R14 ; LCD[i] = 0
add.w R15, R14 ; Add R15 to R14
mov.b #0x00, 0(R14) ; Set memory location to 0
add.w #0x01, R15 ; Increment loop counter
jmp cLCD0 ; Repeat this loop
cLCDdone: ret ; Return from subroutine
;------------------------------------------------------------------------------
toggleAnt: xor.b #0x10, &LCDM10 ; Physically toggle segment pin
ret ; Return from subroutine
;------------------------------------------------------------------------------
dispValue: mov.w R12, R10 ; Set up parameter #1
mov.w R14, R11 ; Set up parameter #2
mov.w #0x00, R9 ; Sign = 0
cmp.w #0x00, R10 ; Is (value < 0) ?
jge dV0 ; Jump if greater than or equal to
xor.w #0xFFFF, R10 ; Value = ~value + 1;
add.w #0x01, R10 ; Add 1 to parameter #1
mov.w #0x01, R9 ; Sign = 1
dV0: mov.w #0x06, R15 ; i = (6 - start)
sub.w R11, R15 ; Perform the subtraction
mov.w R15, R8 ; Move result to new temp register
dV1: cmp.w #0x0A, R10 ; While (value > 9)
jl dV2 ; Jump if less than
mov.w #0, IROP2H ; Divide by 10 to get the remainder
mov.w R10, IROP2L ; Load the quotient
mov.w #0x0A, IROP1 ; Load the Divisor
call #UDIV_32_16 ; LCD[i] = LCD_Table[value%10]
mov.w IROP2H, R14 ; Load the remainder from div oper
mov.w &LCD, R15 ; Set up the pointer to LCD table
add.w R8, R15 ; Add the offset into the LCD table
mov.b LCD_Table(R14), 0(R15) ; Update the actual LCD memory
mov.w #0, IROP2H ; Divide by 10 to get the dividend
mov.w R10, IROP2L ; Load the quotient
mov.w #0x0A, IROP1 ; Load the divisor
call #UDIV_32_16 ; Value = value / 10
mov.w IRACCL, R10 ; Load the dividend from the div op
add.w #0x01, R8 ; Increment loop counter
jmp dV1 ; Repeat the loop
dV2: mov.w &LCD, R15 ; LCD[i] = LCD_Table[value]
add.w R8, R15 ; Move the retrieved value to reg
mov.b LCD_Table(R10), 0(R15) ; Set the actual LCD memory byte
cmp.w #0x00, R9 ; Sign = 0 ?
jeq dV3 ; Yes, so do the jump
mov.w &LCD, R15 ; LCD[i-1] = LCD_Table[17];
add.w R8, R15 ; Move the retrieved value to reg
mov.b &LCD_Table+17,0xFFFF(R15); Update the actual LCD memory
dV3: ret ; Return from subroutine
;------------------------------------------------------------------------------
dispTemp: mov.w &tempDegF, R11 ; Fetch the current temp reading
mov.w #0x06, R10 ; Start position = 6
mov.b #0x00, &LCDM1 ; Clear the LCD memory
mov.b #0x00, &LCDM2 ; Clear the LCD memory
mov.b #0x00, &LCDM3 ; Clear the LCD memory
mov.w R10, R14 ; Set up parameter #1 for func call
mov.w R11, R12 ; Set up parameter #2 for func call
call #dispValue ; Call function to display on LCD
ret ; Return from subroutine
;------------------------------------------------------------------------------
dispTach: mov.w R12, R10 ; Display tachometer on LCD screen
mov.w #0x03, R11 ; Init temp register for param #1
mov.b #0x00, &LCDM4 ; Clear the LCD memory
mov.b #0x00, &LCDM5 ; Clear the LCD memory
mov.b #0x00, &LCDM6 ; Clear the LCD memory
mov.b #0x00, &LCDM7 ; Clear the LCD memory
mov.w R11, R14 ; Set up parameter #1 for func call
mov.w R10, R12 ; Set up parameter #2 for func call
call #dispValue ; Call function to display on LCD
ret ; Return from subroutine
;------------------------------------------------------------------------------
dispLevel: mov.b #0x00, &LCDM8 ; Display system level & bar on LCD
and.b #0xF0, &LCDM9 ; Clear lower byte of LCD memory
mov.b R12, R14 ; Init temp register with param #1
sub.b #0x00, R14 ; Check if level needs to be at 0
jeq dLevel0 ; Yes so jump to set the level to 0
sub.b #0x01, R14 ; Check if level needs to be at 1
jeq dLevel1 ; Yes so jump to set the level to 1
sub.b #0x01, R14 ; Check if level needs to be at 2
jeq dLevel2 ; Yes so jump to set the level to 2
sub.b #0x01, R14 ; Check if level needs to be at 3
jeq dLevel3 ; Yes so jump to set the level to 3
sub.b #0x01, R14 ; Check if level needs to be at 4
jeq dLevel4 ; Yes so jump to set the level to 4
sub.b #0x01, R14 ; Check if level needs to be at 5
jeq dLevel5 ; Yes so jump to set the level to 5
jmp dLevDone ; Go to done
dLevel0: mov.b &LCDM8, &LCDM8 ; Set LCD memory to display level 0
jmp dLevDone ; Go to done
dLevel1: bis.b #0x10, &LCDM8 ; Set LCD memory to display level 1
bis.b #0x03, &LCDM9 ; S17:S16
jmp dLevDone ; Go to done
dLevel2: bis.b #0x20, &LCDM8 ; Set LCD memory to display level 2
bis.b #0x07, &LCDM9 ; S17:S16
jmp dLevDone ; Go to done
dLevel3: bis.b #0x40, &LCDM8 ; Set LCD memory to display level 3
bis.b #0x0F, &LCDM9 ; S17:S16
jmp dLevDone ; Go to done
dLevel4: bis.b #0x88, &LCDM8 ; Set LCD memory to display level 4
bis.b #0x0F, &LCDM9 ; S17:S16
jmp dLevDone ; Go to done
dLevel5: bis.b #0x0F, &LCDM8 ; Set LCD memory to display level 5
bis.b #0x0F, &LCDM9 ; S17:S16
dLevDone: ret ; Return from subroutine
;------------------------------------------------------------------------------
; Display all icons on LCD screen
dispAcc: mov.b #0xFF, &LCDM8 ; Enable all LCD segments in byte
mov.b #0xFF, &LCDM9 ; Enable all LCD segments in byte
mov.b #0xFF, &LCDM10 ; Enable all LCD segments in byte
mov.b #0xF7, &LCDM11 ; Enable all LCD segments in byte
ret ; Return from subroutine
;------------------------------------------------------------------------------
dispUpArrow: ; Display the UP arrow on LCD
and.b #0x0F, &LCDM9 ; Clear all arrow segments first
bis.b #BIT4, &LCDM9 ; Enable the UP arrow segment
ret ; Return from subroutine
;------------------------------------------------------------------------------
dispDownArrow: ; Display the DOWN arrow on LCD
and.b #0x0F, &LCDM9 ; Clear all arrow segments first
bis.b #BIT6, &LCDM9 ; Enable the DOWN arrow segment
ret ; Return from subroutine
;------------------------------------------------------------------------------
rotateArrows:
mov.w &arrowState, R15 ; Rotate arrows once circular
sub.w #0x00, R15 ; Is current state at 0 ?
jeq rArrow0 ; Yes, jump to state 0
sub.w #0x01, R15 ; Is current state at 1 ?
jeq rArrow1 ; Yes, jump to state 1
sub.w #0x01, R15 ; Is current state at 2 ?
jeq rArrow2 ; Yes, jump to state 2
sub.w #0x01, R15 ; Is current state at 3 ?
jeq rArrow3 ; Yes, jump to state 3
jmp rArrow4 ; Current state is at 4 (end)
rArrow0: and.b #0x0F, &LCDM9 ; Clear all arrow segments
bis.b #BIT4, &LCDM9 ; Set the first arrow segment
jmp rArrow5 ; Jump to inc arrow state counter
rArrow1: and.b #0x0F, &LCDM9 ; Clear all arrow segments
bis.b #BIT5, &LCDM9 ; Set the second arrow segment
jmp rArrow5 ; Jump to inc arrow state counter
rArrow2: and.b #0x0F, &LCDM9 ; Clear all arrow segments
bis.b #BIT6, &LCDM9 ; Set the third arrow segment
jmp rArrow5 ; Jump to inc arrow state counter
rArrow3: and.b #0x0F, &LCDM9 ; Clear all arrow segments
bis.b #BIT7, &LCDM9 ; Set the fourth arrow segment
jmp rArrow5 ; Jump to inc arrowState counter
rArrow4: mov.w #0x00, &arrowState ; Reset arrowState counter
rArrow5: add.w #0x01, &arrowState ; Increment arrowState counter
cmp.w #0x04, &arrowState ; Is (arrowState >= 4) ?
jl rArrow6 ; Go to done if at end of state seq
mov.w #0x00, &arrowState ; Reset arrowState counter
rArrow6: ret ; Return from subroutine
;************************** GENERAL SYSTEM FUNCTIONS **************************
setStatLED: mov.b R12, R14 ; Set LED based on system status
sub.B #0x00, R14 ; Check if status is zero
jeq setLED0 ; Turn the LED ON
sub.B #0x01, R14 ; Decrement counter
jne setLED1 ; Goto done
mov.b #ACTIVITY, &status ; Blink (toggle) the LED
xor.b #ACTIVITY, &P1OUT ; Physically toggle the LED pin
ret ; Return from subroutine
setLED0: mov.b #0x00, &status ; Turn LED ON
bic.b #ACTIVITY, &P1OUT ; Physically clear the LED pin
setLED1: ret ; Return from subroutine
;------------------------------------------------------------------------------
; Translate pulse count totals into
; corresponding actual RPMs
updateTach: mov.w &tachCount, R12 ; Get the tachometer value
rra.w R12 ; Divide by 2
mov.w #60, &IROP1 ; Multiply by 60 to get RPM
mov.w R12, &IROP2L ; Load the main factor
call #UMPY_16x16 ; Call the 16-bit multiply function
mov.w &IROP2L, &tachRPM ; Store the result into RAM
mov.w #0x00, &tachCount ; Reset the pulse counter
ret ; Return from subroutine
;************************* INTERRUPT SERVICE ROUTINES *************************
ISR_PORT2: bit.b #TACH, &P2IFG ; Tachometer pulse detected ?
jnc ISR_P2D ; No, goto done
add.w #0x01, &tachCount ; Yes, increment pulse counter
bic.b #TACH, &P2IFG ; Clear PORT2 interrupt flag
ISR_P2D: reti ; Return from interupt
;------------------------------------------------------------------------------
ISR_TIMER0_A1:
bic.w #LPM0, 0x0(SP) ; Clear LPM0
bic.w #TAIFG, &TA0CCTL1 ; Clear TA0CCR1 interrupt flag
reti ; Return from interrupt
;------------------------------------------------------------------------------
ISR_BT: call #toggleAnt ; Blink the antenna icon on LCD
reti ; Return from interrupt
;------------------------------------------------------------------------------
ISR_WDT: bic.w #LPM0, 0x0(SP) ; Clear LPM0
reti ; Return from interrupt
;------------------------------------------------------------------------------
COMMON INTVEC ; Interrupt Vectors for MSP430F41x
;------------------------------------------------------------------------------
ORG BASICTIMER_VECTOR ; Basic Timer Interrupt Vector loc
DC16 ISR_BT ; Basic Timer Interrupt Vector val
ORG PORT2_VECTOR ; Port 2 Interrupt Vector location
DC16 ISR_PORT2 ; Port 2 Interrupt Vector value
ORG TIMER0_A1_VECTOR ; Timer_A3 CCR1-CCR2 Int Vector loc
DC16 ISR_TIMER0_A1 ; Timer_A3 CCR1-CCR2 Int Vector val
ORG WDT_VECTOR ; Watchdog Timer Int Vector loc
DC16 ISR_WDT ; Watchdog Timer Int Vector value
ORG RESET_VECTOR ; Main RESET Interrupt Vector loc
DC16 RESET ; Main RESET Interrupt Vector val
;------------------------------------------------------------------------------
END ; End of assembly source code
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -