background image

;*******************************************************************

;
;       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 <AARGB0,1,2>

;
;       Modified "oscillator test" so it copies F3   to <AARGB0,1,2>

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

background image

;       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

background image

        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         <p16f628.inc>

        __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

background image

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

background image

        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

background image

;**********************************************************

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

background image

        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

background image

;

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

background image

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

background image

        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.

background image

;       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 <AARGB0,1,2> into a bcd number

;       at <bcd>. Uses Mike Keitz's procedure for handling bcd 
;       adjust; Modified Microchip AN526 for 24-bits.

;

B2_BCD

background image

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

background image

        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

background image

                                ; 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

background image

        

        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

background image

        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

background image

        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

background image

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

background image

;

;********************************************************************   

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

background image

        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)

background image

                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

background image

        bank1

        RETURN  

        errorlevel      +302

;********************************************************************   

        INCLUDE <FP.TXT>

;********************************************************************
;

;       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

;********************************************************************