⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 fc430_es417_iar.s43

📁 lcdcdode cor customized
💻 S43
📖 第 1 页 / 共 3 页
字号:


;************************ ZERO-INIT GLOBAL VARIABLES **************************

;------------------------------------------------------------------------------
            RSEG    DATA16_Z
            EVEN
;------------------------------------------------------------------------------
status      DS      1                       ; Alarm status of system
level       DS      1                       ; System cooling level setting
LCD         DS      2                       ; Temp storage for LCD memory map
tachCount   DS      2                       ; Frequency generator counter 4 fan
tachRPM     DS      2                       ; Current tachometer reading in RPM
tempDegF    DS      2                       ; Current temperature in degrees F
lastRPM     DS      2                       ; Last tachometer reading in RPM
arrowState  DS      2                       ; State machine for arrows on LCD		
TEMP        DS      2                       ; Temporary storage in temp routine
RESULT      DS      2                       ; Temporary storage in temp routine
IRBIT       DS      2                       ; Used for bit test
IROP1       DS      2                       ; First operand
IROP2L      DS      2                       ; Second operand low word
IROP2H      DS      2                       ; Second operand high word
IRACCL      DS      2                       ; Math result low word
IRACCH      DS      2                       ; Math result high word

;------------------------------------------------------------------------------
            RSEG    CODE
            EVEN
;------------------------------------------------------------------------------

;*************************** MAIN SYSTEM PROCESSING ***************************

RESET:      mov.w   #300h, SP               ; Initialize system stackpointer
            call    #initSystem             ; Initialize the system as a whole
main_loop:  bis.w   #LPM0, SR               ; Drop into Low Power Mode 0
            call    #checkTach              ; Update tachometer readings
            call    #sampleTemp             ; Take a temperature reading
            call    #dispTemp               ; Update temperature on LCD
            call    #checkTemp              ; Check temp & set cooling level
            call    #dispLevel              ; Display cooling level setting
            jmp     main_loop               ; Repeat main background loop

;------------------------------------------------------------------------------

initSystem: mov.w   #(WDTPW+WDTHOLD),&WDTCTL; Disable the Watchdog
            bis.b   #XCAP18PF, &FLL_CTL0    ; Set internal load caps for xtal
            mov.w   #0x00, R15              ; Reset counter
setupFLL:   cmp.w   #0x2710, R15            ; Delay for FLL to lock (@ power up)
            jc      setupP1                 ; FLL locked, exit calibration loop
            add.w   #0x01, R15              ; Increment our FLL delay counter
            jmp     setupFLL                ; Busy loop until FLL is locked
setupP1:    bic.b   #ACTIVITY, &P1SEL       ; Configure Port 1 Output Pin(s)
            bis.b   #ACTIVITY, &P1DIR       ; Physically set the Port 1 Pin(s)
setupP2:    mov.b   #0xFF, &P2SEL           ; Set segment outputs for LCD
            mov.b   #0xFF, &P2DIR           ; All outputs
            bic.b   #TACH, &P2SEL           ; Set up tachometer input
            bic.b   #TACH, &P2DIR           ; Set up tachometer direction
            bis.b   #TACH, &P2IE            ; Enable Port 2 interrupt
            bis.b   #TACH, &P2IES           ; Generate ints on falling edge
setupWDT:   mov.w   #WDT_ADLY_1000, &WDTCTL ; Set up Watchdog Interval
            bis.b   #WDTIE, &IE1            ; Enable WatchdogTimer Interval int
setupLCD:   mov.b   #0xFF, &P3SEL           ; Set segment outputs for LCD
            mov.b   #0xFF, &P3DIR           ; All outputs
            mov.b   #0xFF, &P4SEL           ; Set segment outputs for LCD
            mov.b   #0xFF, &P4DIR           ; All outputs
            mov.b   #0xFC, &P5SEL           ; Set Rxx and COM pins for LCD
            mov.b   #0xFF, &P5DIR           ; All outputs
                                            ; 4mux LCD, segs0-15 = outputs
            mov.b   #(LCDON+LCDSG0_3+LCD4MUX), &LCDCTL
                                            ; Set LCD frame freq = ACLK/128
                                            ; Set interrupt interval
setupBT:    mov.b   #(BT_fLCD_DIV128+BTDIV+BTIP2), &BTCTL
            bis.b   #BTIE, &IE2             ; Enable Basic Timer interrupt
            mov.b   #0xFF, &LCDM8           ; Set S15:S14 on LCD
            mov.b   #0xFF, &LCDM9           ; Set S17:S16 on LCD
            mov.b   #0xFF, &LCDM10          ; Set S19:S18 on LCD
            mov.b   #0xF7, &LCDM11          ; Set S21:S20 on LCD
setupPWM:   bis.b   #PWM, &P2DIR            ; Sonfigure for output direction
            bis.b   #PWM, &P2SEL            ; Select peripheral option
            mov.w   #PERIOD050USEC, &TA1CCR0; Set up the PWM Period
            mov.w   #(TASSEL_2+MC_1),&TA1CTL; Use SMCLK, count up mode
            mov.w   #OUTMOD_1, &TA1CCTL1    ; Output HI signal - keep fans off
setupCA0:   and.b   #~(REF+THERM), &P1SEL   ; Select GPIO function for R(ref)
            bis.b   #(REF+THERM), &P1DIR    ; Change R(ref) pin for output
                                            ; (vs. floating; saves power)
            and.b   #~(REF+THERM), &P1OUT   ; Clear resistor outputs
            mov.b   #(REF+THERM+CAIN), &CAPD; Disable input buffers for inputs
            mov.b   #P2CA0, &CACTL2         ; Set up comparator port
initData:   mov.b   #0x01, &level           ; Initialize to Level 1 (one-time)
            mov.w   #0x91, &LCD             ; Initialize LCD (one-time)
enableInts: eint                            ; Enable global interrupts
            ret                             ; Return from subroutine

;*************************** 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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -