?? fc430_es417_cce.asm
字號(hào):
;*************************** MATH UTILITY FUNCTIONS ***************************
;------------------------------------------------------------------------------
; Unsigned multiply routine IROP1 x IROP2L -> IRACH/IRACL
; variables used IROP1, IROP2L, IROP2H, IRACL, IRACH, IRBT
;------------------------------------------------------------------------------
UMPY_16x16: clr.w IRACCL ; 0 -> LSBs of result
clr.w IRACCH ; 0 -> MSBs of resut
clr.w IROP2H ; MSBs multiplier
mov.w #0x01,IRBIT ; Bit test register
MPY1: bit.w IRBIT,IROP1 ; Test actual bit
jz MPY2 ; If 0 do nothing
add.w IROP2L,IRACCL ; If 1 add multiplier to result
addc.w IROP2H,IRACCH ; Add carry to destination
MPY2: rla.w IROP2L ; Multiplier x 2
rlc.w IROP2H ; Rotate P2H left through carry bit
rla.w IRBIT ; Get the next bit to test
jnc MPY1 ; Finished if bit in carry
mov.w TEMP,IROP1 ; Move result into P1 variable
mov.w IRACCL,IROP2L ; Move low word into P2L var
mov.w IRACCH,IROP2H ; Move high word into P2H var
UMPY_DONE: ret ; Return from subroutine
;------------------------------------------------------------------------------
; Unsigned division subroutine 32-bit BY 16-bit
; IROP2M|IROP2L : IROP1 -> IRACL remainder in IROP2H
; return: carry = 0 = OK carry = 1 = quotient > 16 bits
; variables used IROP1, IROP2L, IRACL, IRBT, IROP2H
;------------------------------------------------------------------------------
UDIV_32_16: clr.w IRACCL ; Clear accumulator low
mov.w #17,IRBIT ; Initalize loop counter
DIV1: cmp.w IROP1,IROP2H ; Compare P1 to P2H
jlo DIV2 ; Jump if less than
sub.w IROP1,IROP2H ; Subtract P1 from P2H
DIV2: rlc.w IRACCL ; Rotate left through carry bit
jc UDIV_DONE ; Error: result > 16 bits
dec.w IRBIT ; Decrement loop counter
jz UDIV_DONE ; Is 0: terminate w/o error
rla.w IROP2L ; Rotate P2L left arithmetically
rlc.w IROP2H ; Rotate P2H left thru carry bit
jnc DIV1 ; Jump if carry bit not set
sub.w IROP1,IROP2H ; Subtract P1 from P2H
setc ; Set the carry bit
jmp DIV2 ; Repeat the current loop
UDIV_DONE: ret ; Return from subroutine
;*********************** SLOPE A/D CONVERSION FUNCTIONS ***********************
;--------Capacitor is charged up with reference resistor-----------------------
; SMCLK, clear, continuous
chargeCap: mov.w #(TASSEL1+TACLR+MC1), &TACTL
bic.b #REF, &CAPD ; Must be enabled for output func
bis.b #REF, &P1OUT ; Ref Set
mov.w #PERIOD5MSEC, &CCR1 ; CCR1 ~ TAR+5ms (5tu)
mov.w #CCIE, &CCTL1 ; Compare mode,interrupt
bis.w #LPM0, SR ; Wait for CCR1 interrupt
bis.b #REF, &CAPD ; Input buffer disabled 4 tri-state
bic.b #REF, &P1OUT ; Ref = reset
;--------Measure discharge time -----------------------------------------------
dischargeCap: ; -Comp = 0.25*Vcc, comp on
mov.b #(CARSEL+CAREF0+CAON), &CACTL1
; Neg, CCIB,cap,interrupt
mov.w #(CM1+CCIS0+CAP+CCIE), &CCTL1
push &TAR ; Save TAR at start of conversion
bic.b R14, &CAPD ; Must be enabled for output func
bis.w #LPM0, SR ; Wait for CCR1 interrupt
mov.w &CCR1, R14 ; R14 = TAR (CCR1) at EOC
sub.w @SP+, R14 ; R14 = discharge time
bis.b #(REF+THERM), &CAPD ; Input buffer disabled 4 tri-state
clr.b &CACTL1 ; Disable comparator
clr.w &CCTL1 ; Disable CCTL1
clr.w &TACTL ; Disable Timer_A
ret ; Return from subroutine
;--------Complete an entire sequence to sample temperature --------------------
sampleTemp: mov.w #REF, R14 ; R14 = Ref pin
call #chargeCap ; Charge cap. & measure reference
mov.w R14, TEMP ; Save Ref discharge time
mov.w #THERM, R14 ; R14 = Sensor pin
call #chargeCap ; Charge cap. and measure sensor
mov.w R14, RESULT ; Save Sensor discharge time
;------------------------------------------------------------------------------
; Calculate temperature based on the thermistor's variable resistance
;------------------------------------------------------------------------------
mov.w RESULT, IROP1 ; Get the result and load into RAM
mov.w #10000, IROP2L ; Initialize the multiplier factor
call #UMPY_16x16 ; Call the unsigned multiply func
call #UDIV_32_16 ; Call the unsigned divide function
;------------------------------------------------------------------------------
; Convert sensor resistance value to degrees F for display
; Table search is done directly with BCD subtraction
; Variable 'IRACCL' contains the sensor resistance value
;------------------------------------------------------------------------------
clr.w R13 ; Clear resistance table pointer
mov.w #99h, R14 ; R14 used as temperature counter
readTable: cmp.w RES_TAB(R13), IRACCL ; Compare table value to sensor
jl storeTemp ; Jump if sensor < table
incd.w R13 ; Double increment (word) pointer
dadd.b #99h, R14 ; Subtract 1 from counter
mov.w R14, R12 ; Save in dedicated register in
jmp readTable ; Mode is changed temp is not lost
storeTemp: sub.w #TEMP_CALFACTOR, R12 ; Adjust temp with cal. factor
mov.w R12, &tempDegF ; Store temperature into RAM
ret ; Return from subroutine
;------------------------------------------------------------------------------
checkTemp: cmp.w #PWM_L0, &tempDegF ; Check temp vs. first boundary
jl cTempDone ; Out of range; goto done
cmp.w #PWM_L1toL2, &tempDegF ; Check temp vs. second boundary
jge cTemp1 ; Go to next check
mov.b #0x1, R14 ; Set level = 1 in RAM
jmp cTemp2 ; Now go adjust PWM duty cycle
cTemp1: cmp.w #PWM_L2toL3, &tempDegF ; Check temp vs. third boundary
jge cTemp3 ; Go to next check
mov.b #0x2, R14 ; Set level = 2 in RAM
jmp cTemp2 ; Now go adjust PWM duty cycle
cTemp3: cmp.w #PWM_L3toL4, &tempDegF ; Check temp vs. fourth boundary
jge cTemp4 ; Go to next check
mov.b #0x3, R14 ; Set level = 3 in RAM
jmp cTemp2 ; Now go adjust PWM duty cycle
cTemp4: cmp.w #PWM_L4toL5, &tempDegF ; Check temp vs. fifth boundary
jl cTemp5 ; Now go adjust PWM duty cycle
mov.b #0x5, R15 ; Set level = 5 in RAM
jmp cTemp6 ; Now go adjust PWM duty cycle
cTemp5: mov.b #0x4, R15 ; Set level = 4 in RAM
cTemp6: mov.b R15, R14 ; Retrieve the level setting
cTemp2: mov.b R14, &level ; Store level into RAM
mov.w #OUTMOD_3, &TA1CCTL1 ; Generate PWM via output mode 3
mov.b R14, R15 ; Figure out current level
sub.b #0x1, R15 ; Level 1 ?
jeq cTemp7 ; We're currently in Level 1
sub.b #0x1, R15 ; Level 2 ?
jeq cTemp8 ; We're currently in Level 2
sub.b #0x1, R15 ; Level 3 ?
jeq cTemp9 ; We're currently in Level 3
sub.b #0x1, R15 ; Level 4 ?
jeq cTemp10 ; We're currently in Level 4
sub.b #0x1, R15 ; Level 5 ?
jeq cTemp11 ; We're currently in Level 5
jmp cTemp12 ; Invalid level setting
cTemp7: mov.w #DUTYCYCLE_030, &TA1CCR1; Set 30% fan duty cycle
jmp cTemp12 ; Go to done
cTemp8: mov.w #DUTYCYCLE_045, &TA1CCR1; Set 45% fan duty cycle
jmp cTemp12 ; Go to done
cTemp9: mov.w #DUTYCYCLE_060, &TA1CCR1; Set 60% fan duty cycle
jmp cTemp12 ; Go to done
cTemp10: mov.w #DUTYCYCLE_080, &TA1CCR1; Set 80% fan duty cycle
jmp cTemp12 ; Go to done
cTemp11: mov.w #DUTYCYCLE_100, &TA1CCR1; Set 100% fan duty cycle
cTemp12: mov.b &level, R12 ; Store the level in RAM
cTempDone: ret ; Return from subroutine
;------------------------------------------------------------------------------
checkTach: mov.w &tachRPM, R15 ; Retrieve tachometer reading
cmp.w #0x00, R15 ; Check fan RPM
jne setLED ; RPM not zero, no alarm condition
mov.b #0x00, R12 ; Reset temp register to 0
call #setStatLED ; Raise alarm condition
jmp refresh ; Update tach reading on display
setLED: mov.b #0x01, R12 ; Set temp register to 1
call #setStatLED ; Call func to set the STATUS LED
refresh: call #updateTach ; Refresh tachometer readings
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]
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -