;******************************************************************* ; ;Inductance & Capacitance Meter with Software calibration ; ;******************************************************************* ; ; 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. ;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 ; ;******************************************************************* ; ; lc007Changed 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 16F628 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) ; ;******************************************************************* ; ; LC_swcal.001 ;Reintroduced code to handle 8x2(=16x1) displays ; ;******************************************************************* ; ; LC_swcal.002 ;Added code to use PortB5 as a display config input. ;(Connect 1K from B5 to Ground for 8x2(=16x1) display.) ; ;Modified calibration sequence by adding a dummy read ;when applying the calibration capacitor. ; ;******************************************************************* ; ; LC_swcal.003 ;Modified frequency counting code, by using the 32 bit ;"frequency engine" from the "newer" frequency meter ;F1, F2, F3 changed from 16 bit to 32 bit ;W2Stak now copies 32 bit to 24 bit to FP on stack ;Test mode now handles 24 bit freq count (I hope). ;655350 Hz restriction on oscillator now lifted. ;it is now (2^24 - 1)*10 ie. about 167MHz ; ;Modified counting code agian. Now, the T0CKI is left ;counting for most of the time (even when not "counting"). ;It is only halted while it is being read. ;It is reset "on the fly" (which defines the start of the ;counting period.) This should improve oscillator stability. ; ;******************************************************************* ; ; LC_swcal.004 ;32 bit copy macro added. ; ; ; ; ;******************************************************************* ;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 bank0macro errorlevel+302; Re-enable bank warning bcfSTATUS,RP0; Select Bank 0 endm ;------------------------------------------------------------------- ;Select Register Bank 1 bank1macro bsfSTATUS,RP0; Select Bank 1 errorlevel-302; disable warning endm ;------------------------------------------------------------------- ;Swap bytes in register file via W swapmacrothis,that movfthis,w; get this xorwfthat,f; Swap using Microchip xorwfthat,w; Tips'n Tricks xorwfthat,f; #18 movwfthis endm ;------------------------------------------------------------------- ;Copy bytes in register file via W copymacrofrom,to MOVFfrom,W MOVWFto endm ;------------------------------------------------------------------- ;Copy words in register file via W copy16macrofrom,to MOVFfrom,W MOVWFto MOVFfrom+1,W MOVWFto+1 endm ;------------------------------------------------------------------- ;Copy medium words in register file via W copy24macrofrom,to MOVFfrom,W MOVWFto MOVFfrom+1,W MOVWFto+1 MOVFfrom+2,W MOVWFto+2 endm ;------------------------------------------------------------------- ;Copy big words in register file via W copy32macrofrom,to MOVFfrom,W MOVWFto MOVFfrom+1,W MOVWFto+1 MOVFfrom+2,W MOVWFto+2 MOVFfrom+3,W MOVWFto+3 endm ;******************************************************************* ; ;CPU configuration ; MESSG"Processor = 16F628" processor16f628 include<p16f628.inc> __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _HS_OSC & _BODEN_ON & _LVP_OFF ;********************************************************** ; ;I/O Assignments. ; #defineLCD0PORTB,3 #defineLCD1PORTB,2 #defineLCD2PORTB,1 #defineLCD3PORTB,0 #defineENAPORTB,4; Display "E" #defineRSPORTB,5; Display "RS" & Disp type link #definefunctnPORTB,6; 0 = "Inductor" #define relayPORTB,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 ; ;******************************************************************* cblock0x20 ; ; Floating Point Stack and other locations used by FP.TXT ; ;FP Stack: TOSA = AEXP:AARGB0:AARGB1:AARGB2: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:4 F2:4 F3:4 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 cblock0x70; Common RAM cal_t:2; Ccal temporary value PB_data:1; LCD output munger temp links:1; User test links copy DispType:1; Initial copy of test links COUNT1; Used by delay routines ; and "prescaler flush" COUNT2; Timing (100ms) COUNT3 endc EXPequAEXP; Used by FP.TXT TEMPequTEMPB0 ;AARGequAARGB0; Unused ;BARGequBARGB0; Unused ;CARGequCARGB0; Unused ;******************************************************************* ; ; GENERAL MATH LIBRARY DEFINITIONS ; ; ;define assembler constants B0equ0 B1equ1 B2equ2 B3equ3 B4equ4 B5equ5 B6equ6 B7equ7 MSBequ7 LSBequ0 ; STATUS bit definitions #define_CSTATUS,0 #define_ZSTATUS,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 NANequ4; bit4 = not-a-number exception flag DOMequ5; 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 ; #definebeqbz #defineBEQbz #defineBNEbnz #definebnebnz #defineBCCbnc #definebccbnc #defineBCSbc #definebcsbc #defineBRAgoto #definebragoto ;********************************************************** ; ;Begin Executable Stuff(tm) ; org0 GOclrwdt; 0 << Reset bsfFPFLAGS,RND; FP round to nearest bsfFPFLAGS,SAT; FP Saturate to appropriate callInitIO bcfrelay; Remove Ccal ;Read state of PortB links so we can display "Calibrating" bank1; PORTB:- movlwb'01101111'; LCD data bits to read movwfTRISB; 1 = input bank0; 0 = output callMS2; Settling time copyPORTB,DispType bank1 movlwb'01000000'; restore data direction movwfTRISB; 1 = input bank0; 0 = output ;********************************************************** ; ;Main Program ; STARTCALLLCDINIT ; INITIALIZE LCD MODULE callEE_RD; Retrieve CCal integer value cmdloopcallHOME ; ;"Zero" the meter. ; Chk4ZMOVLW Calibr-0x2100; Display " Calibrating " callpmsg; to entertain the punters callMeasure; Dummy Run to stabilise oscillator. callMS200 callMeasure; Get freq in F3 copy32F3,F1; Copy F3 to F1 ;copyF3+0,F1+0; Copy F3 to F1 ;copyF3+1,F1+1 ;copyF3+2,F1+2 ;copyF3+3,F1+3 bsfrelay; Add standard capacitor callMS200 callMeasure; Dummy Run to stabilise oscillator. callMS200 callMeasure; Get freq in F3 copy32F3,F2; Copy F3 to F2 ;copyF3+0,F2+0; Copy F3 to F2 ;copyF3+1,F2+1 ;copyF3+2,F2+2 ;copyF3+3,F2+3 bcfrelay; Remove standard capacitor callMS200 callMeasure; Dummy Run to stabilise oscillator. ; ;Now we resume our regular pogrom ;Read state of user test links on LCD bus ; M_F3bank1; PORTB:- movlwb'01101111'; LCD data bits to read movwfTRISB; 1 = input bank0; 0 = output callMS2; Settling time copyPORTB,links bank1 movlwb'01000000'; restore data direction movwfTRISB; 1 = input bank0; 0 = output ;--------------------------------------------------------------- ; ;Take a break from regular duties to do something interesting ; btfsslinks,0; Raise Ccal value gotocal_up btfsslinks,1; Lower Ccal value gotocal_dn btfsslinks,2; Test osc without Ccal gotoosc1 btfsslinks,3; Test osc with Ccal gotoosc2 ; ;None of the above ; bcfrelay; In case of osc test btfssEEflag,0; Time to save Ccal value? gotocont; No. Back to work bcfEEflag,0; To say we have done it callEE_WR; So, we better save it gotocont; Hi Ho, its off to work I go ; ;Add +10 to cal_t:2 ; cal_upbsfEEflag,0; Say "we're adjusting" movlw0x0a; +10 addwfcal_t+1,f bcccont incfcal_t+0,f goto cont ; ;Add -10 to cal_t:2 ; cal_dnbsfEEflag,0; Say "we're adjusting" movlw0xf6; -10 addwfcal_t+1,f bcchi_byte incfcal_t+0,f hi_bytemovlw0xff addwfcal_t+0,f gotocont ; ;Measure & display osc freq for initial setup ; osc2bsfrelay; Add Ccal osc1callHOME callMeasure; Measure Local Osc Freq. callCLEAR movfF3+1,W; Copy F3 to 24 bit number movwfAARGB0; in AARGB0, 1, 2 movfF3+2,W; for display movwfAARGB1; NB; Ignore MSByte of F3 movfF3+3,W; It should be zero movwfAARGB2 callDisplay gotoM_F3 ;--------------------------------------------------------------- contcallHOME callMS200 callMeasure; Measure F3 & leave it there movfF3+0,w; Test for "too low" frequency iorwfF3+1,w iorwfF3+2,w bneOK2GO; F < 2560Hz ? OORangeMOVLWovr-0x2100; Over/Under range message callpmsg gotoM_F3 ; ;Precompute major bracketed terms cos ;we need 'em both for all calculations ; OK2GOclrfFPE; Declare "error free" callF1_F2 callF1_F3 ; ;See what mode we are in ; btfssfunctn; 0=Inductor gotoDo_Ind ; ;OK, we've been told it's a capacitor ; Do_CapcallC_calc movfFPE,f; Any FP errors? bnecomplain movlwCintro-0x2100; C = callpmsg callC_disp gotoM_F3 ; ;Now, they reckon it's a @#$*! inductor ; Do_IndcallL_calc movfFPE,f; Any FP errors? bnecomplain movlwLintro-0x2100; L = callpmsg callL_disp gotoM_F3 ; ;Got a Floating Point Error of some sort ; complainmovlwovr-0x2100; Over Range callpmsg gotoM_F3 ;********************************************************** ; ;Print String addressed by W ;Note: Strings are in EEPROM ;We do a lotta bank switching here. pmsgbank1 movwfEEADR; pointer pm1BSF EECON1,RD ; EE Read MOVF EEDATA,W ; W = EEDATA, affects Z bit bank0; Does not change Z bit btfscSTATUS,Z; ZERO = All done return; so quit callDATS; Byte -> display bank1 INCF EEADR,F ; bump address gotopm1 ;********************************************************** ; ;Delay for 2ms (untrimmed) ; MS2MOVLW0xFD; DELAY 2ms MOVWFCOUNT1 MOVLW0x66 MOVWFCOUNT2 gotoL3 ;********************************************************** ; ;Delay for about 200ms or 300ms (untrimmed) ; MS300callMS100 MS200callMS100 ;********************************************************** ; ;Delay for about 100ms ; MS100MOVLW0x7e; Count up MOVWFCOUNT1; to roll-over MOVLW0x20; was 0x19, then 0x25, then 1f MOVWFCOUNT2 L3INCFSZCOUNT2,F GOTOL3 INCFSZCOUNT1,F GOTOL3 RETLW0 ;********************************************************** ; ;Put a BCD nybble to display ; PutNybANDLW0x0F; MASK OFF OTHER PACKED BCD DIGIT ADDLW0x30; Convert BIN to ASCII ;********************************************************** ; ;Put a byte to display ; MESSG"PortB5 = Display select link." DATSbtfscDispType,5; Check display type gotoDAT1 decfTabStop,F; Time to tickle 8x2 display? bneDAT1; Not yet movwfTabTemp; Save character CALLLINE2; Move to Line 2 movfTabTemp,W; Restore character DAT1BSFRS; SELECT DATA REGISTER CMMOVWFCHR; STORE CHAR TO DISPLAY SWAPFCHR,W; SWAP UPPER AND LOWER NIBBLES (4 BIT MODE) callPB_dly MOVFCHR,W; GET CHAR AGAIN ;********************************************************** ; ;Put 4 bits to LCD & wait (untrimmed) ; PB_dlymovwfPB_data; Save nybble btfssPB_data,0; copy LSbit bcfLCD0 btfscPB_data,0 bsfLCD0 btfssPB_data,1 bcfLCD1 btfscPB_data,1 bsfLCD1 btfssPB_data,2 bcfLCD2 btfscPB_data,2 bsfLCD2 btfssPB_data,3; copy MSbit bcfLCD3 btfscPB_data,3 bsfLCD3 BSFENA; ENA HIGH NOP BCFENA; ENA LOW ;gotoD200us; Fall into DELAY subroutine ;********************************************************** ; ;Delay for 200us (untrimmed) ; D200usMOVLW0x42; DELAY 200us MOVWFCOUNT1 NXT5DECFSZCOUNT1,F GOTONXT5 RETLW0 ;****************************************************************** ; ;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 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 CALLMS100; WAIT FOR LCD MODULE HARDWARE RESET BCFRS; REGISTER SELECT LOW BCFENA; ENABLE LINE LOW MOVLW0x03; 1 callPB_dly CALLMS100; WAIT FOR DISPLAY TO CATCH UP MOVLW0x03; 2 callPB_dly MOVLW0x03; 3 callPB_dly MOVLW0x02; Fn set 4 bits callPB_dly MOVLW0x0C; 0x0C DISPLAY ON CALLST200us MOVLW0x28; DISPLAY 2 Line , 5x7 Dot's CALLST200us; New in LC628/LC006 version MOVLW0x06; 0x06 ENTRY MODE SET CALLST200us; Fall into CLEAR ;************ CLEAR DISPLAY *************************** CLEARMOVLW0x01; CLEAR DISPLAY gotoHome2; LONGER DELAY NEEDED WHEN CLEARING DISPLAY ;*********** MOVE TO HOME ***************************** HOMEmovlw0x09; Count characters movwfTabStop; before tickling display. MOVLW0x02; HOME DISPLAY Home2CALLSTROBE gotoMS2 ;********************************************************** ; ;SENDS DATA TO LCD DISPLAY MODULE (4 BIT MODE) ; STROBEBCFRS; SELECT COMMAND REGISTER GOTOCM ;************ MOVE TO START OF LINE 2 ***************** LINE2MOVLW0xC0; ADDRESS FOR SECOND LINE OF DISPLAY ST200usCALLSTROBE gotoD200us ;******************************************************************** ; Initialise Input & Output devices ;******************************************************************** InitIOmovlwb'00000110' movwfCMCON ; Select Comp mode bank1 movlwb'00000000' movwfVRCON ; Set Volt ref mode to OFF movlw0x37; Option register movwfOPTION_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:- movlwb'11100111'; initialise data direction ; 1 = input ; 0 = output ; movwfTRISA; 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:- movlwb'01000000'; initialise data direction ; 1 = input ; 0 = output ; movwfTRISB; 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:4" ; MESSG"32 bit counting engine" MeasureCLRFTMR0; RESET INTERNAL COUNT (INCLUDING PRESCALER) ; See page 27 Section 6.0 bcfINTCON,T0IF; Clear any previous overflow CLRFF3+0; Ready to receive 32 bit number CLRFF3+1 CLRFF3+2 CLRFF3+3 CALLMS400; 400MS DELAY (now 100ms) bank1 movlwb'11110111'; Disable RA4 output to T0CKI movwfTRISA; 1 = input ; 0 = output bank0 nop; and allow time for nop; the registers to catch up nop nop nop callRollOver; Final check, just in case MOVFTMR0,W MOVWFF3+2 ;Now empty the prescaler PSC1bank1 bcfOPTION_REG,T0SE; Clock the prescaler nop bsfOPTION_REG,T0SE bank0 DECFF3+3,F; Decrement the counter movfTMR0,W; Has TMR0 changed? xorwfF3+2,W; if unchanged, XOR -> 0 beqPSC1 ; F3 : F3+1 : F3+2 : F3+3 now holds 32 bit result ; Rollover subroutine has set F3+0 and F3+1 suitably. bank1 ; OPEN GATE movlwb'11100111'; Enable RA4 output to T0CKI movwfTRISA; 1 = input ; 0 = output bank0 return ;********************************************************** ; ;Delay for 100ms (trimmed for actual clock freq) ;Check for Timer register roll over and count 'em ; ;Uses: W, COUNT1, COUNT2, COUNT3 & others ; ;********************************************************** MS400MOVLW0xff; 100 MS DELAY LOOP MOVWFCOUNT1; 4 MHZ XTAL MOVLW0x7f; Count up MOVWFCOUNT2; to 24 bit overflow MOVLW0xf5 MOVWFCOUNT3 L3aINCFSZCOUNT3,F GOTOL3a callRollOver; Check for Timer0 RollOver INCFSZCOUNT2,F GOTOL3a INCFSZCOUNT1,F GOTOL3a RETLW0 ;********************************************************** ; ;Account for TMR0 overflows when counting ;Check at regular intervals and handle as ;necessary. ; ;Needs to be done at less than 936us (@ 70MHz in) ;intervals, or else it can lose counts. ; RollOver btfssINTCON,T0IF; Rolled over? gotoRO3; No RO1bcfINTCON,T0IF; Yes. ACK! INCFF3+1,f; Count it bneRO2; Overflowed? incfF3+0,f; No need to check RO2return ;Balance path lengths RO3nop nop gotoRO2 ;********************************************************** ; ;Display contents of AARGB0,1,2 on LCD ;First convert to BCD, Then ASCII (nybble at a time) ; DisplayCALLB2_BCD; CONVERT COUNT TO BCD callSwap0; GET NEXT DIGIT callMove0; GET OTHER BCD DIGIT callSwap1 callMove1 callSwap2 callMove2 callSwap3 gotoMove3; includes return ;********************************************************** ; ;Formatted display of BCD work area for Capacitor ; C_dispmovfR_sign,w; Sign callDATS F_C1MOVFbcd+0,W ANDLW0x0F beqF_C2 CALLPutNyb callSwap1 callMove1 CALLDoDP; Print DP callSwap2 gotoF_C3U ;-------------------------------------------------- F_C2swapfbcd+1,W ANDLW0x0F beqF_C3 CALLPutNyb callMove1 CALLDoDP; Print DP callSwap2 callMove2 gotoF_C3U; print nF. includes RETURN ;-------------------------------------------------- F_C3MOVFbcd+1,W ANDLW0x0F beqF_C4 CALLPutNyb CALLDoDP; Print DP callSwap2 callMove2 callSwap3 F_C3UmovlwUnit1-0x2100; nF gotopmsg; includes RETURN ;-------------------------------------------------- F_C4SWAPFbcd+2,W; Digit1 == 0 ? ANDLW0x0F bneNoB1_C MOVLW0x20; YES PRINT A SPACE callDATS MOVFbcd+2,W; Digit2 == 0 ? ANDLW0x0F bneNoB2_C MOVLW0x20; YES PRINT A SPACE callDATS braNoB3_C NoB1_CcallSwap2; 1 NoB2_CcallMove2; 2 NoB3_CcallSwap3; 3 CALLDoDP; Print DP callMove3; 4 movlwUnit2-0x2100; pF gotopmsg; includes RETURN ;********************************************************** ; ;Formatted display of BCD work area for Inductor ; L_dispmovfR_sign,w; Sign callDATS F_L1MOVFbcd+0,W ANDLW0x0F beqF_L2 CALLPutNyb callSwap1 CALLDoDP; Print DP callMove1 callSwap2 gotoF_L2U; Print mH. includes RETURN ;-------------------------------------------------- F_L2swapfbcd+1,W ANDLW0x0F beqF_L3 CALLPutNyb CALLDoDP; Print DP callMove1 callSwap2 callMove2 F_L2UmovlwUnit3-0x2100; mH gotopmsg; includes RETURN ;-------------------------------------------------- F_L3MOVFbcd+1,W ANDLW0x0F beqF_L4 CALLPutNyb callSwap2 callMove2 CALLDoDP; Print DP callSwap3 gotoF_L4U; Print uH. includes RETURN ;-------------------------------------------------- F_L4SWAPFbcd+2,W; Digit1 == 0 ? ANDLW0x0F bneNoB1_L MOVLW0x20; YES PRINT A SPACE callDATS gotoNoB2_L NoB1_LcallSwap2; 1 NoB2_LcallMove2; 2 CALLDoDP; Print DP callSwap3; 3 callMove3; 4 F_L4UmovlwUnit4-0x2100; uH gotopmsg; includes RETURN ;-------------------------------------------------- ; ;Common subroutine for formatted output ; DoDPMOVLW'.'; Print DP gotoDATS; Return from DATS Swap0SWAPFbcd+0,W; GET NEXT DIGIT gotoPutNyb; DISPLAY IT Move0MOVFbcd+0,W; GET OTHER BCD DIGIT gotoPutNyb Swap1SWAPFbcd+1,W gotoPutNyb Move1MOVFbcd+1,W gotoPutNyb Swap2SWAPFbcd+2,W gotoPutNyb Move2MOVFbcd+2,W gotoPutNyb Swap3SWAPFbcd+3,W gotoPutNyb Move3MOVFbcd+3,W gotoPutNyb ;******************************************************************** ; ;Stack operations ; ;******************************************************************** ;addcallFPA24 ;gotoS_fix subtractcallFPS24 gotoS_fix dividecallFPD24 gotoS_fix multiplycallFPM24 ;gotoS_fix ; ;Fix stack after add, subtract, divide & multiply ;AND Collect ALL Floating Point Errors in FPE S_fixiorwfFPE,f; W may hold Error (0xff) copyCARGB1,BARGB1; C -> B copyCARGB0,BARGB0 copyCEXP,BEXP return ; ;Push stack (duplicates TOS) ; S_pushcopyBARGB1,CARGB1; B -> C copyBARGB0,CARGB0 copyBEXP,CEXP copyAARGB1,BARGB1; A -> B copyAARGB0,BARGB0 copyAEXP,BEXP return ; ;Swap A and B S_swapswapAARGB1,BARGB1; A <-> B swapAARGB0,BARGB0 swapAEXP,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_calccalldivide callGet_Ccal; Times 10,000 ( = 1000.0pF) callmultiply gotoPorM; includes return ;-------------------------------------------------------------------- L_calccallmultiply callGet_Lscale; Precomputed Scale_factor/(4*PI*PI) callmultiply callGet_Ccal callS_swap calldivide L_divF1callGet_F1; Divide by F1^2 callS_push callmultiply callS_swap calldivide ; ;Handle Space or Minus in front of FP number ; PorMbtfssAARGB0,7; test sign gotoPplus Pminusmovlw0x2d; minus gotoPMdisp Pplusmovlw0x20; plus PMdispmovwfR_sign; save for later display bcfAARGB0,7; make plus anyway ; ;Format as raw BCD string in bcd:bcd+1:bcd+2:bcd+3 ; callINT2424; To INT in AARGB0 etc. iorwfFPE,f; W may hold Error (0xff) gotoB2_BCD; includes return ;******************************************************************** ; ;Calculate (F1/F3)^2-1, leave result on stack ; ;******************************************************************** F1_F3callGet_F3 gotoF1_F1 ;******************************************************************** ; ;Calculate (F1/F2)^2-1, leave result on stack ; ;******************************************************************** F1_F2callGet_F2 F1_F1callGet_F1 calldivide; F1/Fx callS_push callmultiply; (F1/Fx)^2 callGet_One callS_swap gotosubtract; (F1/Fx)^2-1 ; includes return ;******************************************************************** ;Fetch assorted things used for the calculation ;of Unknown L and C ; ;******************************************************************** Get_LscalecallS_push; make room first movlw0xB8; 2.53303e+17 movwfAEXP; Create FP version of movlw0x60; Precomputed 1/(4*PI*PI) movwfAARGB0; times any needed movlw0xFA; fiddle factor (1/100) movwfAARGB1 return Get_OnecallS_push; make room first clrfAEXP; Create a binary 1 clrfAARGB0 clrfAARGB1 movlw0x01 gotoLSB2stak ;******************************************************************** ;Copy 16 bit numbers to stack ;and convert to FP (positive value only) ;via a 24 bit number in AARGB0,1,2 ;******************************************************************** Get_Ccalmovlwcal_t; Get integer value ;******************************************************************** ;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 ;******************************************************************** W16toStakmovwfFSR callS_push; make room first clrfAEXP clrfAARGB0 gotow16toS ;******************************************************************** ;Copy 32 bit numbers to stack ;and convert to FP (positive value only) ;via a 24 bit number in AARGB0,1,2 ;Assumes MSB of 32 bit number is zero (and discards it). ; ;******************************************************************** Get_F1movlwF1; Includes stack push gotoW2stak Get_F2movlwF2; Includes stack push gotoW2stak Get_F3movlwF3; Includes stack push ;gotoW2stak ;******************************************************************** ; ;Copy 32 bit number, pointed to by W, to stack ;and convert to FP (positive value only) ;via a 24 bit number in AARGB0,1,2 ;Assumes MSB of 32 bit number is zero (and discards it). ; ;******************************************************************** W2stakaddlw0x01; skip first byte movwfFSR callS_push; make room first clrfAEXP movfINDF,W; Second biggest Byte first movwfAARGB0 incfFSR,F; then next byte w16toSmovfINDF,W movwfAARGB1 incfFSR,F; then little byte movfINDF,W LSB2stakmovwfAARGB2 CALLFLO2424; 24 bit int -> 24 bit FP iorwfFPE,f; W may hold Error (0xff) RETURN ;******************************************************************** ;Read EEPROM into "cal_t" ;******************************************************************** EE_RDbank1 movlwcal_p-0x2100; Address to read MOVWFEEADR bank0 CALLEE_R MOVWFcal_t+0 CALLEE_Rinc MOVWFcal_t+1 RETURN EE_Rincbank1 INCFEEADR,F; bump address EE_Rbank1 BSFEECON1,RD; EE Read MOVFEEDATA,W; W = EEDATA bank0 RETURN ;******************************************************************** ;Write EEPROM from "cal_t" ;******************************************************************** EE_WRbank1 movlwcal_p-0x2100 MOVWFEEADR; Address to write MOVFcal_t+0,W; Data byte #0 CALLEE_W MOVFcal_t+1,W; Data byte #1 CALLEE_Winc bank0 RETURN errorlevel-302; In Bank 2 EE_WincINCFEEADR,F; bump address EE_WMOVWFEEDATA BSFEECON1,WREN; Enable Write MOVLW0x55; MOVWFEECON2; Write 0x55 MOVLW0xAA; MOVWFEECON2; Write 0xAA BSFEECON1,WR; Set WR bit (begin write) EE_W2BTFSCEECON1,WR; Wait for write to finish GOTOEE_W2 bank0 BCFPIR1,EEIF; clear interrupts bank1 RETURN errorlevel+302 ;******************************************************************** INCLUDE <FP.TXT> ;******************************************************************** ; ;Text Strings (stored in data EEPROM) ; ORG 0x2100 ovrde" Over Range ",0 Unit1de" nF",0 Unit2de" pF",0 Unit3de" mH",0 Unit4de" uH",0 Cintrode" C = ",0 Lintrode" L = ",0 Calibr de" Calibrating ",0 cal_pde0x27,0x10; Initial value = 10000 END ;********************************************************************
0
You can add this document to your study collection(s)
Sign in Available only to authorized usersYou can add this document to your saved list
Sign in Available only to authorized users(For complaints, use another form )