Otomatik Kademeli Kapasitemetre

kapasitans_metre

Kaynak Kodu :

 ;                  software: ver.6  
 ;***************** Dec. 3rd. 2002 **************************
 ;           Written by Flemming Jensen
 ; Zeroing on pwr-up
 ; Low battery indicator
 ; 
 ; No diode in series with "nF" range resistor
 ; (instead the Pic pin connected to the nF resistor
 ; is programmed as input when not used, i.e. made Hi-Z)
 ;  
 ; pF/nF/uF and up to >1F
 ; rolls over from 999pF to 1.00nF and 9.99nF to 10nF etc.  
 ; pF procedure is run twice, mean value is used. This way
 ; hum influence is reduced.     
 ; (uF range selected via a pnp, and so 1=off, 0=on)
 ;  In mF procedure, is "wait" signalled when measuring.
 ;  "ready" is shown when mF procedure has been run 4 times.
 ;  meter has to be reset by on/off when ready has been shown.
 ; p.g.a. for stor fejlvisning over 5000uF er der nu indlagt
 ; en "wait" på 1500mS i uF proceduren
 ;
 ;*************************************************************


#compiler clock = 20000   ; 20    MHz clock
#ASM list p=16C84
#fuse CP_OFF + PWRT_ON + WDT_OFF + XT_OSC



var charout  : byte		; character output to lcd
var flags    : byte		; boolean byte
var lcdData  : bit 0 of flags	; T = data or F = command
var lcdbusy  : bit 1 of flags	; lcd busy flag
var talx         : word		; contains the cap. value
var talx1         : word	
var talx2         : word	
var a            : byte		; holds number of 1000's
var nb           : byte		; holds number of 100's
var c            : byte		; holds number of 10's
var d            : byte		; holds number of 1's
var p            : byte		; prefix ( p n u m )		
var y            : byte         ; insert dec.point ?
var z            : word         ; open lead cap. 
var zz           : word         ; open lead cap. 
var tempcount    : byte         ; for delay uF range
var delaycount   : byte         
var q            : byte         ; holds batt. condition 
var rdy          : byte         ; holds how many F proc.
var proc         : byte


alias(RB4,lcdportD4)	   ; rename port RBx to lcdportDx
alias(RB5,lcdportD5)
alias(RB6,lcdportD6)
alias(RB7,lcdportD7)


alias(RA0,lcd_rs)	   ; lcd register select
alias(RA1,lcd_en)	   ; lcd enable
alias(RA2,lcd_rw)	   ; lcd read/write

alias(RB0,bat)             ; RB0 lo bat
alias(RB1,range_uF)        ; range select
alias(RB2,range_nF)
alias(RB3,reset)           ; reset 555


alias(RA3,trig)            ;trigger for 555
alias(RA4,out_555)         ;output pulse from 555


procedure(MAIN)
InitPort		   ; set up ports
InitLCD			   ; initialise lcd display
reset = 1              ; reset 555 high 
trig = 1
clr(z)                  ; reset zeroing var
clr(rdy)                ; rdy reset

pFzero                 ; open leads cap is stored just after pwr-up


while true
 
   clr(proc)
  pF                   ; pF procedure (000pF-9,99nF)

if proc = 0 then
begin 
  talx1 = talx              ; 2 times meas. (hum reduction)
  wait(10)
  pF
  talx2 = talx
  wait(10)
  talx = (talx1 + talx2)/2 
end
  DoMessage
loop 



procedure(pFzero)          ; incr. talx, when 555 is high
  
clr(y)                 ; no dec. point

input(range_nF)     ; nF is made Hi-z by converting pic pin as input                  
;range_nF = 0       ; nF,uF deselected,(uF=pnp=off)
range_uF = 1        ; pF is hardwired high

resettrig
  
while (b'00010000' and PortA) ;RA4 is read,(555 output) 
  inc(z)                     ;if high,increment talx
 
 if z >= 9999 then          ;if >9999pF,shift to nF
 begin
   nF
 end
loop 

                        
                            ;the open 
zz = z                      ;leads caps need to be stored twice is stored in z 
                            ; (compiler peculiarities?)
          


procedure(pF)          ; incr. talx, when 555 is high
  
z = zz                 ; Restoring open leads cap after having been in nF proc   
p = 'p' 
clr(y)                 ; no dec. point

input(range_nF)                        
;range_nF = 0        ; nF,uF deselected,(uF=pnp=off)
range_uF = 1        ; pF is hardwired high

resettrig
  
while (b'00010000' and PortA) ;RA4 is read,(555 output) 
inc(talx)                     ;if high,increment talx
 
if talx >= 9999 then          ;if >9999pF,shift to nF
begin
   nF
end
loop 



talx = talx-z                 ;and subtracted from result

while talx > 9999             ;ensures that talx-z doesn't
  talx = talx + 1             ;go below zero
loop

  
 
if talx >= 1000 then         ;remove a decade and insert
  begin                      ;a dec.point 
   talx = talx/10
p = 'n'                      ; n for (n)F
y = 1                        ; insert dec.point     
end                          ; 9999pF becomes 9,99nF


if (b'00000001' and PortB) then
begin
 q = 1
end
else                            ;RB0 testing batt. 
begin
 q = 0
end

if q = 0 then
begin
  lo_mess
end  

    


procedure(nF)      ; procedure nF same as pF procedure 
p = 'n'            ; except (n)F 
clr(y)             
clr(z)
proc = 1

output(range_nF)                       
range_nF = 1       ; nF range resistor selected
range_uF = 1       ; uF=pnp=off

resettrig

while (b'00010000' and PortA)  
  inc(talx)

if talx >= 9999 then
begin
  uF
end

loop

if talx >= 1000 then         
begin 
  talx = talx/10
  p = 'u'
  y = 1                         
end                         

procedure(uF)          
proc = 1
p = 'u' 
clr(y)             
clr(z)

input(range_nF)
;range_nF = 0
range_uF = 0           ;uF(pnp=0=on)
  
clr(talx)

rst                  ; 555 reset procedure  
trig = 1
Wait(1500)
trig = 0 
delay
trig = 1  

while (b'00010000' and PortA) 

clr(tempcount)                 

  while tempcount <= 92    ; div. by 78, caused by the long      
    inc(tempcount)         ; timing pulse in uF range
  loop                     ; calibrated for proper reading

inc(talx)
 
if talx >= 9999 then
begin
    mF                     ; goto mF routine if talx exceeds
end                        ; 9999
               
loop

if talx >= 1000 then         ; same as in pF,nF
begin 
  talx = talx/10


  p = 'm'
  y = 1                               
end                                       


procedure(mF)       
inc(rdy)
proc = 1

p = 'm' 
clr(y)
clr(z)            
                      
;range_nF = 0                             
;range_uF = 0         ;uF range (pnp=0=on)

clr(talx)
 
rst                  ; 555 reset procedure
waitmessage   
trig = 1
Wait(60000)          ; due to the long timingpulse   
trig = 0             ; an extra long wait must be
delay
trig = 1             ; inserted

while (b'00010000' and PortA) ;if high, increment talx  
 wait(194)           ;incr. has to be slowed down in mF 
 inc(talx)

loop

if talx >= 1000 then         ; same as in pF,nF
begin 
  talx = talx/10
  p = ' '
  y = 1                               
end                                       


while rdy = 4
ReadyMessage
loop


procedure(resettrig)

  
clr(talx)

rst                  ; 555 reset procedure  
trig = 1
Wait(100)
trig = 0 
delay
trig = 1  



procedure(rst)
reset = 1
reset = 0
wait(1)
reset = 1

procedure(delay)

clr(delaycount)                 
while delaycount <= 1   ; Delay for trig pulse 
  inc(delaycount)        ; 
loop  



Procedure(ReadyMessage)
lcdData = false			; sending command
charout = b'11000000'		; cursor to 2nd line position 1
LCDout
lcdData = true	

charout = ' '
LCDout
charout = ' '                   ;move display 5 spaces
LCDout                          ;to the left
charout = ' '
LCDout
charout = ' '
LCDout
charout = ' '
LCDout
charout = 'R'
LCDout
charout = 'e'                   
LCDout                          
charout = 'a'
LCDout
charout = 'd'
LCDout
charout = 'y'
LCDout


Procedure(WaitMessage)
lcdData = false			; sending command
charout = b'11000000'		; cursor to 2nd line position 1
LCDout
lcdData = true	

charout = ' '                   ;move display 5 spaces
LCDout                          ;to the left
charout = ' '
LCDout
charout = ' '
LCDout
charout = ' '
LCDout
charout = ' '                   
LCDout 
charout = ' '                   
LCDout                          
charout = 'W'
LCDout
charout = 'a'
LCDout
charout = 'i'
LCDout
charout = 't'                   
LCDout                         


Procedure(lo_mess)
lcdData = false			; sending command
charout = b'11000000'		; cursor to 2nd line position 1
LCDout
lcdData = true	

charout = ' '                   ;move display 2 spaces
LCDout                          ;to the left
charout = ' '
LCDout
charout = ' '
LCDout
charout = ' '
LCDout
charout = ' '
LCDout
charout = 'B'                   
LCDout                          
charout = 'A'
LCDout
charout = 'T'
LCDout           

procedure(doMessage)
lcdData = false		    ; setup lcd for command receive
charout = b'10000000'	    ; cursor to 'home' line 1 pos 1
LCDout			    ; send to lcd
charout = b'00000001'       ; clear display
LCDout
lcdData = true		    ; lcd,receive data

clr(a)			    ; reset var
clr(nb)
clr(c)         
clr(d)

charout = ' '                   ;move display 4 spaces
LCDout                          ;to the left
charout = ' '
LCDout
charout = ' '
LCDout
charout = ' '
LCDout

;********** converts talx to decimals ****************
; by counting, how many 1000's,100's,10's and 1's
;*****************************************************

while talx >= 1000	        ;How many 1000's 
  inc(a)			;is put in a
  talx = talx - 1000	
loop
if a = 0 then			;if no 1000's
begin
  charout = ' '			;write a 'space' 
end
else
begin
  charout = a + 48	        ;convert to ascii 
end
LCDout				; send to lcd
while talx >= 100	        ; how many 100's
  inc(nb)			; is put in b
  talx = talx - 100			
loop

if (nb=0) and (a=0) then        ;if no 100's
begin
  charout = ' '		        ; write a 'space'
end
else
begin
  charout = nb + 48		; convert to ascii
end
LCDout
if y = 1 then                   ;insert dec.point
begin
  charout = '.'                 ;if y = 1
  LCDout
end

					
while talx >= 10		;how many 10's 
  inc(c)		        ;is put in c
  talx = talx - 10		
loop
if (c=0) and (nb=0) and (a=0) then	;if no 10's
begin
  charout = ' '				;write a space
end
else
begin
  charout = c + 48		;convert to ascii 
end
LCDout				;send to lcd
  d = talx			;d=how many 1's
charout = d + 48		;convert d to ascii
LCDout				;send to lcd

charout = ' '			;space
LCDout
charout = p			;prefix var ( p n u m )
LCDout
charout = 'F'			;F for farad
LCDout



procedure(InitPort)
output(lcd_rs)      ; lcd register select output
output(lcd_en)      ; lcd enable output
output(lcd_rw)      ; lcd read/write output
output(lcdportD4)   ; make port RB4 output
output(lcdportD5)   ; make port RB5 output    
output(lcdportD6)   ; make port RB6 output
output(lcdportD7)   ; make port RB7 output             

output(range_uF)                        ; make port output
output(range_nF)
output(reset)

output(trig)                            ;make RA3 output
input(out_555)                          ;make RA4 input
input(bat)                       ;make RB0 input


procedure(InitLCD)
wait(15)		; Ændring fra før.
charout = b'00110000' ; 8 bit mode
InitLCDout            ; initialise LCD
charout = b'00110000' 
InitLCDout            
charout = b'00110000'
InitLCDout
charout = b'00100000'	; Ændring fra før.
InitLCDout
lcdData = false       ; sending command
charout = b'00101000' ; 4 bit, 2 lines, 5x7 font
LCDout                ; 4 bit data transfer
charout = b'00011000' ; cursor move, right shift
LCDout
charout = b'00001100' ; display on, cursor+blink off
LCDout
charout = b'00000100' ; entry mode
LCDout 
charout = b'00000001' ; clear display
LCDout

procedure(LCDout)
busywait              ; is lcd busy
if lcdData = false then
begin
   lcd_rs = 0     ; 0 - instruction register
   lcd_rw = 0     ; 0 - writing to lcd
end
else
begin
  lcd_rs = 1      ; 1 - data register
  lcd_rw = 0      ; 0 - writing to lcd
end
send4bits         ; call routine to output 4 bits
swap(charout)     ; swap lower 4 bits
send4bits         ; call routine to output 4 bits

procedure(send4bits)
lcdportD4 = charout AND b'00010000'    ; send 4 bits
lcdportD5 = charout AND b'00100000'    ; send 4 bits    
lcdportD6 = charout AND b'01000000'    ; send 4 bits    
lcdportD7 = charout AND b'10000000'    ; send 4 bits    
lcd_en = 1  ; Lcd enable high to low
lcd_en = 0  ; data valid

procedure(busywait)
lcd_rw = 1        ; 1 - reading from lcd
lcd_rs = 0        ; 0 - instruction register

input(lcdportD4)  ; make port input 
input(lcdportD5)  ; make port input 
input(lcdportD6)  ; make port input 
input(lcdportD7)  ; make port input 
LCDwait
output(lcdportD4) ; make port output
output(lcdportD5) ; make port output
output(lcdportD6) ; make port output
output(lcdportD7) ; make port output

procedure(LCDwait)
lcdbusy = true
while lcdbusy = true  ; true = lcd busy, false = ready
 lcd_en = 1            ; read data
 lcdbusy = lcdportD7   ; receive upper 4 bits first
 lcd_en = 0
 lcd_en = 1            ; not interested in lower 4
 lcd_en = 0            ; bits of status byte
loop

procedure(InitLCDout)
wait(10)     ; wait 4 msec (no busy flag)
lcd_rw = 0  ; 0 - writing to lcd
lcd_rs = 0  ; 0 - instruction register
send4bits   ; call output 4 bits 

Malzeme Listesi :

Resistors:
R1 = 120Ω
R2 = 5kΩ6
R3 = 5MΩ6
R4 = 1kΩ
R5 = 39kΩ
R6 = 10kΩ
R7 = 470Ω 1W (see text)
P1 = 1MΩ 10-turn multiturn preset,vertical mounting
P2 = 1kΩ 10-turn multiturn preset,vertical mounting
P3 = 100Ω 10-turn multiturn preset,vertical mounting
P4 = 22kΩ

Capacitors:
C1 = 47nF
C2,C7 = 100nF
C3,C4 = 4pF7
C5,C6 = 330nF

Capacitors:
C1 = 47nF
C2,C7 = 100nF
C3,C4 = 4pF7
C5,C6 = 330nF
IC2 = PIC16F84A-20/P, programmed,order code 020144-41
IC3 = 78L05
T1 = BC559B

Miscellaneous:
BT1 = 9V PP3 (6F22) battery with clip-on connector
JP1 = 2-way pinheader with jumper
K1 = two 7-way socket strips, lead pitch 0.1 inch
K2 = 16-way boxheader
K3 = PCB solder terminals
S1 = on/off switch
X1 = 20MHz quartz crystal
LCD display, 2×16 characters, e.g.,
Trimods 1536, Farnell # 142-554 Length of 16-way flat cable with IDC socket
Enclosure: e.g., Pactec HPS and HPLS series, type HPS-9VB (28x53x91x146 mm), Farnell # 736-351, see also www.pactecenclosures.com
PCB, order code 020144-1 (see Readers Services page) Disk, source code and hex files, order code 020144-11 or Free Download


Yayımlandı

kategorisi

yazarı:

Etiketler: