kod programu


;*******************************************************************
;
; Inductance & Capacitance Meter with Software calibration
;
;*******************************************************************
;
; First, let us choose our weapon - a 16F628
;
;*******************************************************************
;
; LC002 - THIS ONE WORKS FINE WITH A WELL BEHAVED DISPLAY
;
; Deleted CpyBin subroutine and one call to it
;
; Modified B2_BCD to take its input directly from
;
; Modified "oscillator test" so it copies F3 to
;
; Fixed Get_Lcal so it gets the correct number
;
; Minor adjustment to MS100 timing to correct frequency display
;
; Check for oscillator too slow when measuring L or C.
;
;
;*******************************************************************
;
; LC003 - Optimised / Modified to handle "bad" displays
;
; Removed duplicated code in DATS subroutine
;
; Added code to fix crook display (select by jumper on B4 - 10)
;
; Optimised L & C formatting code
;
; Optimised "Display" subroutine
;
; Cleaned up LCDINIT
;
;
;*******************************************************************
;
; LC004 - Deleted timer Interrupt Service Routine
;
; Modified way oscillator "out of range" condition is detected
;
;
;*******************************************************************
;
; LC628 - LC004 code ported to 16F628 by Egbert Jarings PA0EJH.
; Mem starts now at 0x20
; InitIO modified , 628 PortA start's up in Analog Mode
; So changed to Digital Mode (CMCON)
;
; Display's "Calibrating" to fill up dead Display time
; when first Powerd Up.
;
; Changed pmsg Routine, EEADR trick wont work with 628,
; PCL was always 0x00 so restart occurs. EEADR is now Etemp.
;
; Also changed EEADR in FP routine to Etemp
;
; Bad Display isn't bad at all, its a Hitachi HD44780, as
; 80% of all Display's are. Adress as 2 Lines x 8 Char.
; So LCDINIT modified for 2 x 8 Display's. (0x28 added)
;
;*******************************************************************
;
; LC005 - Cosmetic rewrite of RAM allocation from LC004
;
; No change to address of anything - I hope
; Identified unused RAM & marked for later removal.
;
;
;*******************************************************************
;
; LC006 - Merge LC005 and LC628
;
; All "#ifdef" F628 parts by Egbert Jarings PA0EJH.
; (or derived from his good work)
;
; Cleaned up RAM allocation.
;
; Added message re: processor type, just to verify selection
;
; Included extra initialisation (2 line) command by PA0EJH
;
;*******************************************************************
;
; lc007 Changed strings to EEPROM (it's not used for anything else)
;
; Added "error collector" code to catch "all" FP errors
;
; Addded macros
;
;
;*******************************************************************
;
; LC_swcal.000
; Changed to use only F628 processor
; Used internal comparator of F628 in place of LM311
; Switched relay directly by digital I/O
; Implemented software calibration via constant in EEPROM
; Re-allocated most I/O pins
; Added output munger for LCD connections (easy to re-allocate)
;
;
;*******************************************************************
;o-----o-----o-----o-----o-----o-----o-----o-----o-----o-----o-----o
;*******************************************************************
;
; Some frequently used code fragments
; Use macros to make mistreaks consistently.
;
;-------------------------------------------------------------------
; Select Register Bank 0
bank0 macro
errorlevel +302 ; Re-enable bank warning
bcf STATUS,RP0 ; Select Bank 0
endm
;-------------------------------------------------------------------
; Select Register Bank 1
bank1 macro
bsf STATUS,RP0 ; Select Bank 1
errorlevel -302 ; disable warning
endm
;-------------------------------------------------------------------
; Swap bytes in register file via W
swap macro this,that
movf this,w ; get this
xorwf that,f ; Swap using Microchip
xorwf that,w ; Tips'n Tricks
xorwf that,f ; #18
movwf this
endm
;-------------------------------------------------------------------
; Copy bytes in register file via W
copy macro from,to
MOVF from,W
MOVWF to
endm
;*******************************************************************
;
; CPU configuration
;
MESSG "Processor = 16F628"
processor 16f628
include
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC & _BODEN_ON &
_LVP_OFF
;**********************************************************
;
; I/O Assignments.
;
#define LCD0 PORTB,3
#define LCD1 PORTB,2
#define LCD2 PORTB,1
#define LCD3 PORTB,0
#define ENA PORTB,4 ; Display "E"
#define RS PORTB,5 ; Display "RS"
#define functn PORTB,6 ; 0 = "Inductor"
#define relay PORTB,7 ; Switches Ccal
;*******************************************************************
;
; file register declarations: uses only registers in bank0
; bank 0 file registers begin at 0x0c in the 16F84
; and at 0x20 in the 16F628
;
;*******************************************************************
cblock 0x20
;
; Floating Point Stack and other locations used by FP.TXT
;
; FP Stack: TOS A = AEXP:AARGB0:AARGB1:AARGB3:AARGB4
; B = BEXP:BARGB0:BARGB1:BARGB2
; C = CEXP:CARGB0:CARGB1
AARGB4
AARGB3
AARGB2
AARGB1
AARGB0
AEXP ; 8 bit biased exponent for argument A
SIGN ; save location for sign in MSB
FPFLAGS ; floating point library exception flags
BARGB2
BARGB1
BARGB0
BEXP ; 8 bit biased exponent for argument B
TEMPB3 ; 1 Unused byte
TEMPB2 ; 1 Unused byte
TEMPB1 ; Used
TEMPB0 ; 1 Unused byte
CARGB1
CARGB0 ; most significant byte of argument C
CEXP ; 8 bit biased exponent for argument C
;
; "Main" Program Storage
;
COUNT ; Bin to BCD convert (bit count)
cnt ; (BCD BYTES)
CHR
F1:2
F2:2
F3:2
bcd:4 ; BCD, MSD first
TabStop ; Used to fix bad displays.
TabTemp
FPE ; Collect FP errors in here
R_sign ; Holds "+" or " " (sign)
EEflag:1 ; Cal adjust flag
endc
cblock 0x70 ; Common RAM
cal_t:2 ; Ccal temporary value
PB_data:1 ; LCD output munger temp
links:1 ; User test links copy
COUNT1 ; Used by delay routines
; and "prescaler flush"
COUNT2 ; Timing (100ms)
endc
EXP equ AEXP ; Used by FP.TXT
TEMP equ TEMPB0
;AARG equ AARGB0 ; Unused
;BARG equ BARGB0 ; Unused
;CARG equ CARGB0 ; Unused
;*******************************************************************
;
; GENERAL MATH LIBRARY DEFINITIONS
;
;
; define assembler constants
B0 equ 0
B1 equ 1
B2 equ 2
B3 equ 3
B4 equ 4
B5 equ 5
B6 equ 6
B7 equ 7
MSB equ 7
LSB equ 0
; STATUS bit definitions
#define _C STATUS,0
#define _Z STATUS,2
;*******************************************************************
;
; FLOATING POINT literal constants
;
EXPBIAS equ D'127'
;
; floating point library exception flags
;
IOV equ 0 ; bit0 = integer overflow flag
FOV equ 1 ; bit1 = floating point overflow flag
FUN equ 2 ; bit2 = floating point underflow flag
FDZ equ 3 ; bit3 = floating point divide by zero flag
NAN equ 4 ; bit4 = not-a-number exception flag
DOM equ 5 ; bit5 = domain error exception flag
RND equ 6 ; bit6 = floating point rounding flag, 0 =
truncation
; 1 = unbiased rounding to nearest LSB
SAT equ 7 ; bit7 = floating point saturate flag, 0 =
terminate on
; exception without saturation, 1 = terminate on
; exception with saturation to appropriate value
;**********************************************************
;
; Motorola syntax branches
;
#define beq bz
#define BEQ bz
#define BNE bnz
#define bne bnz
#define BCC bnc
#define bcc bnc
#define BCS bc
#define bcs bc
#define BRA goto
#define bra goto
;**********************************************************
;
; Begin Executable Stuff(tm)
;
org 0
GO clrwdt ; 0 << Reset
call InitIO
bcf relay ; Remove Ccal
;**********************************************************
;
; Main Program
;
START CALL LCDINIT ; INITIALIZE LCD MODULE
call EE_RD ; Retrieve CCal integer value
cmdloop call HOME
;
; "Zero" the meter.
;
Chk4Z MOVLW Calibr-0x2100 ; Display's " Calibrating "
call pmsg ; to entertain the punters
call Measure ; Dummy Run to stabilise oscillator.
call MS200
call Measure ; Get freq in F3
copy F3+0,F1+0 ; Copy F3 to F1
copy F3+1,F1+1
bsf relay ; Add standard capacitor
call MS200
call Measure ; Get freq in F3
copy F3+0,F2+0 ; Copy F3 to F2
copy F3+1,F2+1
bcf relay ; Remove standard capacitor
call MS200
call Measure ; Dummy Run to stabilise oscillator.
;
; Now we resume our regular pogrom
; Read state of user test links on LCD bus
;
M_F3 bank1 ; PORTB:-
movlw b'01001111' ; LCD data bits to read
movwf TRISB ; 1 = input
bank0 ; 0 = output
call MS2 ; Settling time
copy PORTB,links
bank1
movlw b'01000000' ; restore data direction
movwf TRISB ; 1 = input
bank0 ; 0 = output
;---------------------------------------------------------------
;
; Take a break from regular duties to do something interesting
;
btfss links,0 ; Raise Ccal value
goto cal_up
btfss links,1 ; Lower Ccal value
goto cal_dn
btfss links,2 ; Test osc without Ccal
goto osc1
btfss links,3 ; Test osc with Ccal
goto osc2
;
; None of the above
;
bcf relay ; In case of osc test
btfss EEflag,0 ; Time to save Ccal value?
goto cont ; No. Back to work
bcf EEflag,0 ; To say we have done it
call EE_WR ; So, we better save it
goto cont ; Hi Ho, its off to work I go
;
; Add +10 to cal_t:2
;
cal_up bsf EEflag,0 ; Say "we're adjusting"
movlw 0x0a ; +10
addwf cal_t+1,f
bcc cont
incf cal_t+0,f
goto cont
;
; Add -10 to cal_t:2
;
cal_dn bsf EEflag,0 ; Say "we're adjusting"
movlw 0xf6 ; -10
addwf cal_t+1,f
bcc hi_byte
incf cal_t+0,f
hi_byte movlw 0xff
addwf cal_t+0,f
goto cont
;
; Measure & display osc freq for initial setup
;
osc2 bsf relay ; Add Ccal
osc1 call HOME
call Measure ; Measure Local Osc Freq.
call CLEAR
btfss INTCON,T0IF ; Set = Counter overflow?
goto Do_Disp
MOVLW ovr-0x2100 ; Over-range message
call pmsg
goto M_F3
Do_Disp clrf AARGB0 ; Copy to 24 bit number
movf F3,W ; in AARGB0, 1, 2
movwf AARGB1 ; for display
movf F3+1,W
movwf AARGB2
call Display
goto M_F3
;---------------------------------------------------------------
cont call HOME
call MS200
call Measure ; Measure F3 & leave it there
movf F3,w ; test for "too low" frequency
beq OORange ; F < 2560Hz ?
btfss INTCON,T0IF ; test for "too high" frequency
goto OK2GO ; F > 655359Hz ?
OORange MOVLW ovr-0x2100 ; Over/Under range message
call pmsg
goto M_F3
;
; Precompute major bracketed terms cos
; we need 'em both for all calculations
;
OK2GO clrf FPE ; Declare "error free"
call F1_F2
call F1_F3
;
; See what mode we are in
;
btfss functn ; 0=Inductor
goto Do_Ind
;
; OK, we've been told it's a capacitor
;
Do_Cap call C_calc
movf FPE,f ; Any FP errors?
bne complain
movlw Cintro-0x2100 ; C =
call pmsg
call C_disp
goto M_F3
;
; Now, they reckon it's a @#$*! inductor
;
Do_Ind call L_calc
movf FPE,f ; Any FP errors?
bne complain
movlw Lintro-0x2100 ; L =
call pmsg
call L_disp
goto M_F3
;
; Got a Floating Point Error of some sort
;
complain movlw ovr-0x2100 ; Over Range
call pmsg
goto M_F3
;**********************************************************
;
; Print String addressed by W
; Note: Strings are in EEPROM
; We do a lotta bank switching here.
pmsg bank1
movwf EEADR ; pointer
pm1 BSF EECON1,RD ; EE Read
MOVF EEDATA,W ; W = EEDATA, affects Z bit
bank0 ; Does not change Z bit
btfsc STATUS,Z ; ZERO = All done
return ; so quit
call DATS ; Byte -> display
bank1
INCF EEADR,F ; bump address
goto pm1
;**********************************************************
;
; Delay for 2ms (untrimmed)
;
MS2 MOVLW 0xFD ; DELAY 2ms
MOVWF COUNT1
MOVLW 0x66
MOVWF COUNT2
goto L3
;**********************************************************
;
; Delay for about 200ms or 300ms (untrimmed)
;
MS300 call MS100
MS200 call MS100
;**********************************************************
;
; Delay for about 100ms
;
MS100 MOVLW 0x7e ; Count up
MOVWF COUNT1 ; to roll-over
MOVLW 0x20 ; was 0x19, then 0x25, then 1f
MOVWF COUNT2
L3 INCFSZ COUNT2,F
GOTO L3
INCFSZ COUNT1,F
GOTO L3
RETLW 0
;**********************************************************
;
; Put a BCD nybble to display
;
PutNyb ANDLW 0x0F ; MASK OFF OTHER PACKED BCD DIGIT
ADDLW 0x30 ; Convert BIN to ASCII
;**********************************************************
;
; Put a byte to display
;
DATS decf TabStop,F ; Time to tickle bad display?
bne DAT1 ; Not yet
movwf TabTemp ; Save character
; btfss FIXIT ; Check if we got a crook one.
; CALL LINE2 ; Skip this if good
movf TabTemp,W ; Restore character
DAT1 BSF RS ; SELECT DATA REGISTER
CM MOVWF CHR ; STORE CHAR TO DISPLAY
SWAPF CHR,W ; SWAP UPPER AND LOWER NIBBLES (4 BIT MODE)
call PB_dly
MOVF CHR,W ; GET CHAR AGAIN
;**********************************************************
;
; Put 4 bits to LCD & wait (untrimmed)
;
PB_dly movwf PB_data ; Save nybble
btfss PB_data,0 ; copy LSbit
bcf LCD0
btfsc PB_data,0
bsf LCD0
btfss PB_data,1
bcf LCD1
btfsc PB_data,1
bsf LCD1
btfss PB_data,2
bcf LCD2
btfsc PB_data,2
bsf LCD2
btfss PB_data,3 ; copy MSbit
bcf LCD3
btfsc PB_data,3
bsf LCD3
BSF ENA ; ENA HIGH
NOP
BCF ENA ; ENA LOW
; goto D200us ; Fall into DELAY subroutine
;**********************************************************
;
; Delay for 200us (untrimmed)
;
D200us MOVLW 0x42 ; DELAY 200us
MOVWF COUNT1
NXT5 DECFSZ COUNT1,F
GOTO NXT5
RETLW 0
;******************************************************************
;
; Convert 24-bit binary number at into a bcd number
; at . Uses Mike Keitz's procedure for handling bcd
; adjust; Modified Microchip AN526 for 24-bits.
;
B2_BCD
b2bcd movlw .24 ; 24-bits
movwf COUNT ; make cycle counter
clrf bcd+0 ; clear result area
clrf bcd+1
clrf bcd+2
clrf bcd+3
b2bcd2 movlw bcd ; make pointer
movwf FSR
movlw .4
movwf cnt
; Mike's routine:
b2bcd3 movlw 0x33
addwf INDF,f ; add to both nybbles
btfsc INDF,3 ; test if low result > 7
andlw 0xf0 ; low result >7 so take the 3 out
btfsc INDF,7 ; test if high result > 7
andlw 0x0f ; high result > 7 so ok
subwf INDF,f ; any results <= 7, subtract back
incf FSR,f ; point to next
decfsz cnt,f
goto b2bcd3
rlf AARGB2,f ; get another bit
rlf AARGB1,f
rlf AARGB0,f
rlf bcd+3,f ; put it into bcd
rlf bcd+2,f
rlf bcd+1,f
rlf bcd+0,f
decfsz COUNT,f ; all done?
goto b2bcd2 ; no, loop
return ; yes
;*********** INITIALISE LCD MODULE 4 BIT MODE ***********************
LCDINIT CALL MS100 ; WAIT FOR LCD MODULE HARDWARE RESET
BCF RS ; REGISTER SELECT LOW
BCF ENA ; ENABLE LINE LOW
MOVLW 0x03 ; 1
call PB_dly
CALL MS100 ; WAIT FOR DISPLAY TO CATCH UP
MOVLW 0x03 ; 2
call PB_dly
MOVLW 0x03 ; 3
call PB_dly
MOVLW 0x02 ; Fn set 4 bits
call PB_dly
MOVLW 0x0C ; 0x0C DISPLAY ON
CALL ST200us
MOVLW 0x28 ; DISPLAY 2 Line , 5x7 Dot's
CALL ST200us ; New in LC628/LC006 version
MOVLW 0x06 ; 0x06 ENTRY MODE SET
CALL ST200us ; Fall into CLEAR
;************ CLEAR DISPLAY ***************************
CLEAR MOVLW 0x01 ; CLEAR DISPLAY
goto Home2 ; LONGER DELAY NEEDED WHEN CLEARING DISPLAY
;*********** MOVE TO HOME *****************************
HOME movlw 0x09 ; Count characters
movwf TabStop ; before tickling display.
MOVLW 0x02 ; HOME DISPLAY
Home2 CALL STROBE
goto MS2
;**********************************************************
;
; SENDS DATA TO LCD DISPLAY MODULE (4 BIT MODE)
;
STROBE BCF RS ; SELECT COMMAND REGISTER
GOTO CM
;************ MOVE TO START OF LINE 2 *****************
LINE2 MOVLW 0xC0 ; ADDRESS FOR SECOND LINE OF DISPLAY
ST200us CALL STROBE
goto D200us
;********************************************************************
; Initialise Input & Output devices
;********************************************************************
InitIO movlw b'00000110'
movwf CMCON ; Select Comp mode
bank1
movlw b'00000000'
movwf VRCON ; Set Volt ref mode to OFF
movlw 0x37 ; Option register
movwf OPTION_REG ; Port B weak pull-up enabled
; INTDEG Don't care
; Count RA4/T0CKI
; Count on falling edge
; Prescale Timer/counter
; divide Timer/counter by 256
; PORTA:-
movlw b'11110111' ; initialise data direction
; 1 = input
; 0 = output
;
movwf TRISA ; PORTA<0> = comp1 "-" in
; PORTA<1> = comp2 "-" in
; PORTA<2> = comp1&2 "+" in
; PORTA<3> = comp1 out
; PORTA<4> = comp2 out, T0CKI in
; PORTA<5:7> = unused
;
;
; PORTB:-
movlw b'01000000' ; initialise data direction
; 1 = input
; 0 = output
;
movwf TRISB ; PORTB<0> = LCD out "DB4"
; PORTB<1> = "DB5"
; PORTB<2> = "DB6"
; PORTB<3> = "DB7"
; PORTB<4> = E out to LCD
; PORTB<5> = RS out to LCD
; PORTB<6> = function in
; PORTB<7> = Ccal switch out
bank0
return
;**********************************************************
;
; Measure Frequency. Stash in "F3 and F3+1"
;
Measure bcf INTCON,T0IF ; Declare "Not yet Over-range"
CLRF TMR0 ; RESET INTERNAL COUNT (INCLUDING PRESCALER)
; See page 27 Section 6.0
CLRF F3 ; Ready to receive 16 bit number
CLRF F3+1
bank1
; OPEN GATE
movlw b'11100111' ; Enable RA4 output to T0CKI
movwf TRISA ; 1 = input
; 0 = output
CALL MS100 ; 100MS DELAY
; CLOSE GATE (COUNT COMPLETE)
movlw b'11110111' ; Disable RA4 output to T0CKI
movwf TRISA ; 1 = input
; 0 = output
bank0
MOVF TMR0,W ; GET HIGH BYTE
MOVWF F3 ; Copy to Big end of 16 bit result
; The comparator is "outputting" a 1 'cos we've forced it high
; so T0CKI=1.
PSC1 bank1
bsf OPTION_REG,T0SE ; Clock the prescaler
nop
bcf OPTION_REG,T0SE
bank0
DECF F3+1,F ; Decrement the counter
movf TMR0,W ; Has TMR0 changed?
xorwf F3,W ; if unchanged, XOR -> 0
beq PSC1
return ; F3 : F3+1 now holds 16 bit result
;**********************************************************
;
; Display contents of AARGB0,1,2 on LCD
; First convert to BCD, Then ASCII (nybble at a time)
;
Display CALL B2_BCD ; CONVERT COUNT TO BCD
call Swap0 ; GET NEXT DIGIT
call Move0 ; GET OTHER BCD DIGIT
call Swap1
call Move1
call Swap2
call Move2
call Swap3
goto Move3 ; includes return
;**********************************************************
;
; Formatted display of BCD work area for Capacitor
;
C_disp movf R_sign,w ; Sign
call DATS
F_C1 MOVF bcd+0,W
ANDLW 0x0F
beq F_C2
CALL PutNyb
call Swap1
call Move1
CALL DoDP ; Print DP
call Swap2
goto F_C3U
;--------------------------------------------------
F_C2 swapf bcd+1,W
ANDLW 0x0F
beq F_C3
CALL PutNyb
call Move1
CALL DoDP ; Print DP
call Swap2
call Move2
goto F_C3U ; print nF. includes RETURN
;--------------------------------------------------
F_C3 MOVF bcd+1,W
ANDLW 0x0F
beq F_C4
CALL PutNyb
CALL DoDP ; Print DP
call Swap2
call Move2
call Swap3
F_C3U movlw Unit1-0x2100 ; nF
goto pmsg ; includes RETURN
;--------------------------------------------------
F_C4 SWAPF bcd+2,W ; Digit1 == 0 ?
ANDLW 0x0F
bne NoB1_C
MOVLW 0x20 ; YES PRINT A SPACE
call DATS
MOVF bcd+2,W ; Digit2 == 0 ?
ANDLW 0x0F
bne NoB2_C
MOVLW 0x20 ; YES PRINT A SPACE
call DATS
bra NoB3_C
NoB1_C call Swap2 ; 1
NoB2_C call Move2 ; 2
NoB3_C call Swap3 ; 3
CALL DoDP ; Print DP
call Move3 ; 4
movlw Unit2-0x2100 ; pF
goto pmsg ; includes RETURN
;**********************************************************
;
; Formatted display of BCD work area for Inductor
;
L_disp movf R_sign,w ; Sign
call DATS
F_L1 MOVF bcd+0,W
ANDLW 0x0F
beq F_L2
CALL PutNyb
call Swap1
CALL DoDP ; Print DP
call Move1
call Swap2
goto F_L2U ; Print mH. includes RETURN
;--------------------------------------------------
F_L2 swapf bcd+1,W
ANDLW 0x0F
beq F_L3
CALL PutNyb
CALL DoDP ; Print DP
call Move1
call Swap2
call Move2
F_L2U movlw Unit3-0x2100 ; mH
goto pmsg ; includes RETURN
;--------------------------------------------------
F_L3 MOVF bcd+1,W
ANDLW 0x0F
beq F_L4
CALL PutNyb
call Swap2
call Move2
CALL DoDP ; Print DP
call Swap3
goto F_L4U ; Print uH. includes RETURN
;--------------------------------------------------
F_L4 SWAPF bcd+2,W ; Digit1 == 0 ?
ANDLW 0x0F
bne NoB1_L
MOVLW 0x20 ; YES PRINT A SPACE
call DATS
goto NoB2_L
NoB1_L call Swap2 ; 1
NoB2_L call Move2 ; 2
CALL DoDP ; Print DP
call Swap3 ; 3
call Move3 ; 4
F_L4U movlw Unit4-0x2100 ; uH
goto pmsg ; includes RETURN
;--------------------------------------------------
;
; Common subroutine for formatted output
;
DoDP MOVLW '.' ; Print DP
goto DATS ; Return from DATS
Swap0 SWAPF bcd+0,W ; GET NEXT DIGIT
goto PutNyb ; DISPLAY IT
Move0 MOVF bcd+0,W ; GET OTHER BCD DIGIT
goto PutNyb
Swap1 SWAPF bcd+1,W
goto PutNyb
Move1 MOVF bcd+1,W
goto PutNyb
Swap2 SWAPF bcd+2,W
goto PutNyb
Move2 MOVF bcd+2,W
goto PutNyb
Swap3 SWAPF bcd+3,W
goto PutNyb
Move3 MOVF bcd+3,W
goto PutNyb
;********************************************************************
;
; Stack operations
;
;********************************************************************
;add call FPA24
; goto S_fix
subtract call FPS24
goto S_fix
divide call FPD24
goto S_fix
multiply call FPM24
; goto S_fix
;
; Fix stack after add, subtract, divide & multiply
; AND Collect ALL Floating Point Errors in FPE
S_fix iorwf FPE,f ; W may hold Error (0xff)
copy CARGB1,BARGB1 ; C -> B
copy CARGB0,BARGB0
copy CEXP,BEXP
return
;
; Push stack (duplicates TOS)
;
S_push copy BARGB1,CARGB1 ; B -> C
copy BARGB0,CARGB0
copy BEXP,CEXP
copy AARGB1,BARGB1 ; A -> B
copy AARGB0,BARGB0
copy AEXP,BEXP
return
;
; Swap A and B
S_swap swap AARGB1,BARGB1 ; A <-> B
swap AARGB0,BARGB0
swap AEXP,BEXP
return
;********************************************************************
;
; Calculate Unknown Capacitance OR inductance
;
; Output: 24 bit positive integer (scaled)
; right justified in AARGB0, AARGB1, AARGB2
; also as BCD in bcd:bcd+1:bcd+2:bcd+3
;
;********************************************************************
C_calc call divide
call Get_Ccal ; Times 10,000 ( = 1000.0pF)
call multiply
goto PorM ; includes return
;--------------------------------------------------------------------
L_calc call multiply
call Get_Lscale ; Precomputed Scale_factor/(4*PI*PI)
call multiply
call Get_Ccal
call S_swap
call divide
L_divF1 call Get_F1 ; Divide by F1^2
call S_push
call multiply
call S_swap
call divide
;
; Handle Space or Minus in front of FP number
;
PorM btfss AARGB0,7 ; test sign
goto Pplus
Pminus movlw 0x2d ; minus
goto PMdisp
Pplus movlw 0x20 ; plus
PMdisp movwf R_sign ; save for later display
bcf AARGB0,7 ; make plus anyway
;
; Format as raw BCD string in bcd:bcd+1:bcd+2:bcd+3
;
call INT2424 ; To INT in AARGB0 etc.
iorwf FPE,f ; W may hold Error (0xff)
goto B2_BCD ; includes return
;********************************************************************
;
; Calculate (F1/F3)^2-1, leave result on stack
;
;********************************************************************
F1_F3 call Get_F3
goto F1_F1
;********************************************************************
;
; Calculate (F1/F2)^2-1, leave result on stack
;
;********************************************************************
F1_F2 call Get_F2
F1_F1 call Get_F1
call divide ; F1/Fx
call S_push
call multiply ; (F1/Fx)^2
call Get_One
call S_swap
goto subtract ; (F1/Fx)^2-1
; includes return
;********************************************************************
; Fetch assorted things used for the calculation
; of Unknown L and C
;
;********************************************************************
Get_Lscale call S_push ; make room first
movlw 0xB8 ; 2.53303e+17
movwf AEXP ; Create FP version of
movlw 0x60 ; Precomputed 1/(4*PI*PI)
movwf AARGB0 ; times any needed
movlw 0xFA ; fiddle factor (1/100)
movwf AARGB1
return
Get_One call S_push ; make room first
clrf AEXP ; Create a binary 1
clrf AARGB0
clrf AARGB1
movlw 0x01
goto LSB2stak
Get_Ccal movlw cal_t ; Get integer value
goto W2stak ; Includes stack push
Get_F1 movlw F1 ; Includes stack push
goto W2stak
Get_F2 movlw F2 ; Includes stack push
goto W2stak
Get_F3 movlw F3 ; Includes stack push
; goto W2stak
;********************************************************************
; Copy 16 bit number, pointed to by W, to stack
; and convert to FP (positive value only)
; via a 24 bit number in AARGB0,1,2
;********************************************************************
W2stak movwf FSR
call S_push ; make room first
clrf AEXP
clrf AARGB0
movf INDF,W ; Big Byte first
movwf AARGB1
incf FSR,F ; then little byte
movf INDF,W
LSB2stak movwf AARGB2
CALL FLO2424 ; 24 bit int -> 24 bit FP
iorwf FPE,f ; W may hold Error (0xff)
RETURN
;********************************************************************
; Read EEPROM into "cal_t"
;********************************************************************
EE_RD bank1
movlw cal_p-0x2100 ; Address to read
MOVWF EEADR
bank0
CALL EE_R
MOVWF cal_t+0
CALL EE_Rinc
MOVWF cal_t+1
RETURN
EE_Rinc bank1
INCF EEADR,F ; bump address
EE_R bank1
BSF EECON1,RD ; EE Read
MOVF EEDATA,W ; W = EEDATA
bank0
RETURN
;********************************************************************
; Write EEPROM from "cal_t"
;********************************************************************
EE_WR bank1
movlw cal_p-0x2100
MOVWF EEADR ; Address to write
MOVF cal_t+0,W ; Data byte #0
CALL EE_W
MOVF cal_t+1,W ; Data byte #1
CALL EE_Winc
bank0
RETURN
errorlevel -302 ; In Bank 2
EE_Winc INCF EEADR,F ; bump address
EE_W MOVWF EEDATA
BSF EECON1,WREN ; Enable Write
MOVLW 0x55 ;
MOVWF EECON2 ; Write 0x55
MOVLW 0xAA ;
MOVWF EECON2 ; Write 0xAA
BSF EECON1,WR ; Set WR bit (begin write)
EE_W2 BTFSC EECON1,WR ; Wait for write to finish
GOTO EE_W2
bank0
BCF PIR1,EEIF ; clear interrupts
bank1
RETURN
errorlevel +302
;********************************************************************
INCLUDE
;********************************************************************
;
; Text Strings (stored in data EEPROM)
;
ORG 0x2100
ovr de " Over Range ",0
Unit1 de " nF",0
Unit2 de " pF",0
Unit3 de " mH",0
Unit4 de " uH",0
Cintro de " C = ",0
Lintro de " L = ",0
Calibr de " Calibrating ",0
cal_p de 0x27,0x10 ; Initial value = 10000
END
;********************************************************************


Wyszukiwarka

Podobne podstrony:
kod programu
Kod programu
Kod programu
Kolokwium z informatyki GiG1,Miska,VB 15 04 2014 Kod programu
Piekny kod Tajemnice mistrzow programowania szppps
01 mój pierwszy program kod
App2 program1 kod
Jak pisaŠ przenoÂny kod Wstŕp do programowania wieloplatformowego
Czysty kod Podręcznik dobrego programisty
kod z WOŚP polecane chomiki by closer9
zestawy cwiczen przygotowane na podstawie programu Mistrz Klawia 6
Międzynarodowy Program Badań nad Zachowaniami Samobójczymi
CSharp Introduction to C# Programming for the Microsoft NET Platform (Prerelease)
Instrukcja Programowania Zelio Logic 2 wersja polska

więcej podobnych podstron