; Questionnement sur l'usage de RA4 en sortie pour la mesure de frequence ? ; ligne 700 .. ;9.5 Comparator Outputs ;The comparator outputs are read through the CMCON ;register. These bits are read only. The comparator ;outputs may also be directly output to the RA3 and RA4 ;I/O pins. When the CM<2:0> = 110 ; 18/01/2017 #define Alternative ; Au lieu d efaire RESET pour calibration ; mettre les 2 jump JP3 et JP4 pour faire une calibration avec un BP poussoir à 2 contacts ; voir ligne 350 ... ; Hardware : LCmetre_16F628_sch.jpg ; F0= 550Khz (100µH + 1000pF) 247 mV efficace ; F1= 100µH + 100pF + 100pF via relais => 385 Khz 110mV efficace ; Zero => 0,0 à 0,1pF ; mesure C sur colonne Breadboard adjacente : 2,2pF ; mesure C 100pF 1% => 98,9pF ; mesure L 10µH => 9,82uH ; mesure L 1000µH => 1,061mH ; 16/01/2017 ; Recuperation fichier FP.txt issu de la note AN575 ; Attention les pins RB0.RB3 sont dans l'ordre inverse LCD D7...D4 ; attention : faire file export du *.hex sinon problemo ! ; Mise sous tension .. LCD affiche "OVER RANGE" ; because erreur sur schema ... inter choix L ou C sur RB6 au lieu de RB5 ;******************************************************************* ;V.O.: http://ironbark.bendigo.latrobe.edu.au/~rice/lc/lc2.txt ; 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) ; ;******************************************************************* ; 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 ; Address Value Field Category Setting ; 2007 3F62 FOSC Oscillator Selection bits HS oscillator: High-speed crystal/resonator on RA6/OSC2/CLKOUT and RA7/OSC1/CLKIN ; WDTE Watchdog Timer Enable bit WDT disabled ; PWRTE Power-up Timer Enable bit PWRT enabled ; MCLRE RA5/MCLR pin function select RA5/MCLR pin function is MCLR ; BOREN Brown-out Reset Enable bit BOD Reset enabled ; LVP Low-Voltage Programming Enable bitRB4/PGM pin has digital I/O function, HV on MCLR must be used for programming ; CPD Data Code Protection bit Data memory code protection off ; CP Code Protection bits Program memory code protection 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 = "Self" 1="Condo" #define relay PORTB,7 ; Switches Ccal rajoute 1000pF 1% au circuit LC 100µH //1000pF ;******************************************************************* 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) COUNT3 ; for big delay LAST_One endc EXP equ AEXP ; Used by FP.TXT TEMP equ TEMPB0 ;******************************************************************* ; 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 call HOME MOVLW Schema-0x2100 call pmsg call Tempo4S call HOME MOVLW Version-0x2100 call pmsg call Tempo4S ; MOVLW .20 ; DELAY 4000mS permet une meilleure stabilisation ; MOVWF COUNT3 ;ICI ; call MS200 ; DECFSZ COUNT3,F ; GOTO ICI 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 1000pF 1% 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 program ; Read state of user test links on LCD bus ; M_F3 bank1 ; PORTB: B0,B1,B2,B3 et B6 en entrees movlw b'01001111' ; LCD data bits to read movwf TRISB ; 1 = input 0 = output bank0 call MS2 ; Settling time copy PORTB,links bank1 movlw b'01000000' ; restore PORTB: B0,B1,B2,B3 en sortie movwf TRISB ; 1 = input 0 = output bank0 ;--------------------------------------------------------------- ; ; Take a break from regular duties to do something interesting ; Aiguillage suivant le strap connecté sur J1 à J4 ; Alternative au RESET pour relancer une Calibration : Mettre les 2 strap J3 ET J4 #ifdef Alternative btfsc links,2 goto Suite btfsc links,3 goto Suite call HOME MOVLW Remove_CAL_SW-0x2100 call pmsg MOVLW .10 ; DELAY 10x200mS = 2000mS MOVWF COUNT3 call TempoX bank1 ; PORTB: B0,B1,B2,B3 et B6 en entrees movlw b'01001111' ; LCD data bits to read movwf TRISB ; 1 = input 0 = output bank0 call MS2 ; Settling time ;wait remove links Remove_links_2_3 movf PORTB,w andlw 0x0C xorlw 0x0C bnz Remove_links_2_3 bank1 movlw b'01000000' ; restore PORTB: B0,B1,B2,B3 en sortie movwf TRISB ; 1 = input 0 = output bank0 call MS2 ; Settling time goto cmdloop ; Calibration Suite #endif 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 00055530 goto osc1 btfss links,3 ; Test osc with Ccal 00038850 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 1=Condo 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 nibble 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 ; 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" ou entree link JP1 ; PORTB<1> = "DB5" ou entree link JP2 ; PORTB<2> = "DB6" ou entree link JP3 ; PORTB<3> = "DB7" ou entree link JP4 ; PORTB<4> = E out to LCD ; PORTB<5> = RS out to LCD ; PORTB<6> = function in ; PORTB<7> = Ccal switch out < Cde Relais CCAL> bank0 return ;********************************************************** ; Measure Frequency. Stored in "F3 and F3+1" ; Usage du precaler 1/256 = MSB counter + TMR0 = LSB counter 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 ;******************************************************************** subtract call FPS24 goto S_fix divide call FPD24 goto S_fix multiply call FPM24 ; 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 ;******************************************************************** ; 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 Tempo4S MOVLW .20 ; DELAY 20x200mS = 4000mS permet une meilleure stabilisation TempoX MOVWF COUNT3 ICI call MS200 DECFSZ COUNT3,F GOTO ICI RETLW 0 ;******************************************************************** INCLUDE <../common/FP.TXT> ; see MicroChip AN575 ;******************************************************************** ; Text Strings (stored in data EEPROM) ; EEPROM de 128 bytes seulement 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 Schema de "LCmetre_16F628 ",0 Version de " Version 170119 ",0 Remove_CAL_SW de "Remov CAL Switch",0 Max_Eeprom equ $ END ---------------------------------------------------------------------- Release build of project `C:\Mplab8\_Mesprojets_ASM\_LC_Meter\LCMeter_16F628_2017.mcp' started. Language tool versions: MPASMWIN.exe v5.51, mplink.exe v4.49, mplib.exe v4.49 Wed Jan 18 13:25:20 2017 ---------------------------------------------------------------------- Clean: Deleting intermediary and output files. Clean: Deleted file "C:\Mplab8\_Mesprojets_ASM\_LC_Meter\LCMeter_16F628_170118.o". Clean: Deleted file "C:\Mplab8\_Mesprojets_ASM\_LC_Meter\LCMeter_16F628_170118.err". Clean: Deleted file "C:\Mplab8\_Mesprojets_ASM\_LC_Meter\LCMeter_16F628_170118.hex". Clean: Deleted file "C:\Mplab8\_Mesprojets_ASM\_LC_Meter\LCMeter_16F628_170118.lst". Clean: Deleted file "C:\Mplab8\_Mesprojets_ASM\_LC_Meter\LCMeter_16F628_170118.cof". Clean: Deleted file "C:\Mplab8\_Mesprojets_ASM\_LC_Meter\LCMeter_16F628_170118.map". Clean: Done. Executing: "C:\Program Files (x86)\Microchip\MPASM Suite\MPASMWIN.exe" /q /p16F628 "LCMeter_16F628_170118.asm" /l"LCMeter_16F628_170118.lst" /e"LCMeter_16F628_170118.err" Message[301] C:\MPLAB8\_MESPROJETS_ASM\_LC_METER\LCMETER_16F628_170118.ASM 109 : MESSAGE: (Processor = 16F628) Executing: "C:\Program Files (x86)\Microchip\MPASM Suite\mplink.exe" /p16F628 /l"C:\Program Files (x86)\Microchip\MPLAB IDE\Device" /l"C:\Mplab8\_Mesprojets_ASM" /l"C:\Program Files (x86)\Microchip" /l"C:\Program Files (x86)\Microchip\MPLAB ASM30 Suite\lib" /k"C:\Program Files (x86)\Microchip\MPASM Suite\LKR" "LCMeter_16F628_170118.o" /z__MPLAB_BUILD=1 /m"LCMeter_16F628_170118.map" /w /aINHX8M /o"LCMeter_16F628_170118.cof" /x MPLINK 4.49, Linker Device Database Version 1.14 Copyright (c) 1998-2011 Microchip Technology Inc. Errors : 0 Loaded C:\Mplab8\_Mesprojets_ASM\_LC_Meter\LCMeter_16F628_170118.cof. ---------------------------------------------------------------------- Release build of project `C:\Mplab8\_Mesprojets_ASM\_LC_Meter\LCMeter_16F628_2017.mcp' succeeded. Language tool versions: MPASMWIN.exe v5.51, mplink.exe v4.49, mplib.exe v4.49 Wed Jan 18 13:25:22 2017 ---------------------------------------------------------------------- BUILD SUCCEEDED