

Capacitance meter circuit schematic
Source code it is available for download
Resolution is 10pF in the range 0 .. 655.36 nF and 100nF in 655.36nf .. 6553.6 uF range. This capacitance meter is autocalibrating when it is power up (wait 2..3 seconds after power up then use) and measurement range is change automatically.
;================= capacimetru =======================24/11/06==
;------------------------------------------------------------
; configure programmer
LIST P=16F630;f=inhx8m
#include "P16F630.INC" ; Include header file
__CONFIG _PWRTE_ON & _WDT_OFF & _XT_OSC & _BODEN & _CP_OFF & _MCLRE_OFF
; http://www.module.ro
;------------------------------------------------------------
cblock 0x20 ; Beginn General Purpose-Register
;-------------------------- counters
count1
count2
count3
count4
;-------------------------- registrii transfer
transo
temp1
temp2
temp3
lo_temp
hi_temp
buff
range
eroare
calib
;--------------------------
endc
;--------------------------
#DEFINE scurt PORTC,0
#DEFINE chrg PORTC,1
#DEFINE sclk PORTC,4
#DEFINE sdta PORTC,3
;--- Reset --------------------------------------------------
org h'00'
goto init ; reset -> init
;--- Interrupt ----------------------------------------------
org h'04'
;************************************************************************
init call haltb
bcf STATUS,RP0 ; Bank 0
clrf PORTA
clrf PORTC
movlw 0x13 ; Turn comparator on
movwf CMCON
bsf STATUS,RP0 ; Bank 1
movlw 0x8C ; Compare with 20/32 from VDD
movwf VRCON
movlw 0xFB ; input
movwf TRISA
movlw 0x00 ; output
movwf TRISC
bcf STATUS,RP0 ; Bank 0
call lcd_ini
call ini_timers
bsf chrg
clrf calib
;************************************************************************
start clrf range
startm call unload
clrf TMR1H
clrf TMR1L
clrf TMR1IF
bcf INTCON,2
bcf PIR1,0
bsf T1CON,0 ; activeaza tmr1
btfsc range,0
bcf chrg ; daca depasire tmr1 mareste curent
bcf scurt ; activeaza incarcare condensator
movlw 0x81 ; temporizeaza la 4*16*129/fosc ( tmr1 overflow la 4*8*256/fosc)
movwf count1
wdhs btfsc CMCON,6 ; COUT = 1 ?
goto gata
btfsc PIR1,0 ;tmr1 overflow ?
goto micro
btfss INTCON,2 ;tmr0 overflow ?
goto wdhs
bcf INTCON,2
decfsz count1,F
goto wdhs
gata bcf T1CON,0
bsf chrg
btfsc range,0
goto crcok ; masoara nF
btfsc calib,0 ; masoara eroare doar la pornire
goto compa
movf TMR1L,W
movwf eroare
bsf calib,0
compa movf eroare,W ; compenseaza eroare
subwf TMR1L,F
crcok call afisare
goto start
micro bcf T1CON,0
bsf range,0
goto startm
;**********************************************************************
unload bsf scurt
call haltb
return
;**********************************************************************
ini_timers
bcf INTCON,5 ; mask tmr0 irq
bcf INTCON,6
bsf STATUS,RP0 ; Bank 1
movlw 0x83 ; clkout, 1/16 prescaler tmr0
movwf OPTION_REG
clrf PIE1 ; no peripheral irq
bcf STATUS,RP0 ; Bank 0
movlw 0x34 ; clkout, 1/8 prescaler tmr1
movwf T1CON
return
;***************************************************
;* Lcd data subroutine *
;***************************************************
afisare
call lcd_home
call iict
movlw 0x74
call act
movlw 0x40 ; Co=0, RS=1, set instruction register for next data bytes
call act
movlw 0xC3 ; C
call act
movlw 0xBA ; :
call act
movlw 0xA0 ; blank
call act
call iicp
call pause
conversie
movf TMR1L,W ; LO -> LO_TEMP
movwf lo_temp
movf TMR1H,W ; HI -> HI_TEMP
movwf hi_temp
movlw 0x27 ; verifica div. cu 10000
movwf temp3
movlw 0x10
movwf temp2
call convb
movlw 0x03 ; verifica div. cu 1000
movwf temp3
movlw 0xE8
movwf temp2
call convb
clrf temp3 ; verifica div. cu 100
movlw 0x64
movwf temp2
call convb
btfsc range,0
goto vrg1
movlw 0xAE ; afiseaza punct
movwf buff
call push_lcd
vrg1 clrf temp3 ; verifica div. cu 10
movlw 0x0A
movwf temp2
call convb
btfss range,0
goto vrg2
movlw 0xAE ; afiseaza punct
movwf buff
call push_lcd
vrg2 clrf temp3 ; verifica div. cu 1
movlw 0x01
movwf temp2
call convb
call iict
movlw 0x74
call act
movlw 0x40 ; Co=0, RS=1, set instruction register for next data bytes
call act
movlw 0xA0 ; blank
call act
btfss range,0
movlw 0xEE ; n
btfsc range,0
movlw 0xF5 ; u
call act
movlw 0xC6 ; F
call act
call iicp
return
;*****************************************
convb
clrf temp1 ; clear counter
conv_high
movf temp3,W
subwf hi_temp,W ; TEST: HI_TEMP-TEMP3 >0 ?
btfss STATUS,C
goto conv_end ; resultat negativ, exit
btfss STATUS,Z ; TEST: HI_TEMP-TEMP3 = 0 ?
goto conv_low ; test zero, goto if result > 0
movf temp2,W ; Precondition: HI-TEST is zero
subwf lo_temp,W ; TEST: LO_TEMP-TEMP2 > 0 ?
btfss STATUS,C ; skip, if true
goto conv_end ; result negativ, exit
conv_low
movf temp3,W
subwf hi_temp,F ; STORE: HI_TEMP = HI_TEMP - TEMP3
movf temp2,W
subwf lo_temp,F ; STORE: LO_TEMP = LO_TEMP - TEMP2
btfss STATUS,C ; skip, if true
decf hi_temp,F ; decrement HI
incf temp1,F ; increment counter
goto conv_high
conv_end
movlw 0xB0
addwf temp1,W ; B0 is ascii offset, add counter
movwf buff
call push_lcd
return
;*****************************************
lcd_home
call iict
movlw 0x74
call act
movlw 0x80
call act
movlw 0x02
call act
call iicp
return
;*****************************************
lcd_clear
call iict
movlw 0x74
call act
movlw 0x80
call act
movlw 0x01
call act
call iicp
return
;***************************************************
push_lcd
call iict
movlw 0x74
call act
movlw 0x40 ; Co=0, RS=1, set instruction register for next data bytes
call act
movf buff,W
call act
call iicp
return
;***************************************************
;* Lcd init commands *
;***************************************************
lcd_ini call iict ; i2c start
movlw 0x74 ; device write address (75h for read)
call act ; i2c send subroutine
movlw 0x00 ; Co,RS=0, set instruction register for multiple next command bytes
call act
movlw 0x01 ; clear DDRAM
call act
movlw 0x21 ; 1 linie mod extins
call act
movlw 0xA0 ; vlcd
call act
movlw 0x07 ; col/row connection
call act
movlw 0x24 ; 2 linii mod normal
call act
movlw 0x0F ; lcd on
call act
movlw 0x06 ; direction
call act
;***************************************************
;* Lcd icon sets off *
;***************************************************
call iict
movlw 0x74
call act
movlw 0x80 ; Co=1, RS=0 just one next command byte
call act
movlw 0x40 ; set CGRAM for icons
call act
movlw 0x40 ; Co=0, RS=1, set instruction register for multiple next data bytes
call act ; erase icons sequence
movlw 0x18
movwf count4
icon movlw 0x00
call act
decfsz count4,F
goto icon
call iicp ; i2c stop
call haltb
;***************************************************
;* Lcd cursor subroutine *
;***************************************************
call iict
movlw 0x74
call act
movlw 0x00
call act
movlw 0x30
call act
movlw 0x01 ; clears entire display and sets DDRAM address to 0 in address counter
call act
movlw 0x0C ; display on, (cursor off, cursor blink off 0C)
call act
call iicp
return
;***************************************************
act movwf transo ; iic data transmission
movlw 0x08
movwf count3
vbit bcf sclk
call pause
btfsc transo,7
bsf sdta
btfss transo,7
bcf sdta
call pause
bsf sclk
call pause
bcf sclk
call pause
rlf transo,f
decfsz count3,f
goto vbit
call ackp
return
;***************************************************
iicp bcf sdta ; stop condition module
call pause
bsf sclk
call pause
bsf sdta ; stop command
call pause
bcf sclk
call pause
return
;***************************************************
iict bsf sdta ; start condition module
bsf sclk
call pause
bcf sdta ; start command
call pause
bcf sclk
call pause
return
;***************************************************
ackp bsf sclk ; one clock step for acknowledge (not read)
call pause
bcf sclk
call pause
return
;***************************************************
pause movlw 0x10
movwf count2
d2 decfsz count2,F
goto d2
return
;***************************************************
haltb movlw 0xFA
movwf count1
j1 movlw 0xFA
movwf count2
j2 nop
decfsz count2,F
goto j2
decfsz count1,F
goto j1
return
;***************************************************
halta
movlw 0x10
movwf count3
r3 movlw 0xFA
movwf count1
r1 movlw 0xFA
movwf count2
r2 nop
decfsz count2,F
goto r2
decfsz count1,F
goto r1
decfsz count3,F
goto r3
return
;============================================================
end
;============================================================
Link: Very accurate capacitance meter with serial communication on RS232
Back to my home page
Last updated January, 2010