
PIC 16F84 İLE FREKENS SAYICI
Frekans sayıcı şemadanda görüleceği gibi temel olarak 16f84 ve 4051 den olşmaktadır. Bunlar dışında transistorler ve birkaç pasif eleman bulunmaktadır.
Frekans sayıcı HF bir amatör
cihazın frekansını görmek için tasarlanmıştır, ölçüm aralığı
10hz – 35
Mhz dir. Bu aralık girişine bir prescaler (örn: U664B) konularak 1.2 Ghz’e
kadar kolayca çıkarılabilir.
Yazar gösterge olarak eski bir hesap
makinesinin 7 segment göstergesini kullanmış
fakat herhangi bir ortak
katotlu gösterge kullanılabilir.
Gösterge sürücü Transistörleri
kritik olmayıp BC547 rahatlıkla iş görür.
Giriş transistörü yüksek frekanslı
bir NPN olmalıdır. BF serisi herhangi
bir transistör olabilir.
Devreyi yaparken aşagıdaki PCB, yerleşim planını kullanabilirsiniz.

Biraz da devreyi inceleyelim…
Devrede bulunan PIC 16F84 hem ölçüm hem de
göstergelerin sürülmesi işinden
sorumludur. 4051 ise pic bacak sayısı
yeterli olmadığından çoğullayıcı olarak her display
elemanını pic
komutlarına göre adresler. Belki dikkatinizi çekmiştir burada kullanılan
kristal 10Mhz'dir tabii Pic de 10Mhzlik PIC16F84 10 I/P
tipi
olmalıdır gibi bir kanı oluşabilir aslında doğrusuda budur ama hiç gerek yok
ufak bir
kandırmacayla 4 Mhzlik piyasada bol bulunan PIC16F84 – 04 I/P
ile bu işi halledebiliriz.
Yapmamız gereken tek şey programlama öncesi
programlayıcı yazılımında OSC
seçeneğinde XT yerine HS yani Hızlı
seçeneğini seçmektir. Bunu yaparsak sorunsuz bir
10 Mhz'lik pic elde
ederiz.
Pic bacaklarındaki A, B, C, D, E, F, G harfleri
display sisteminde segmentlere gidecek ve
0, 1, 2, 3, 4, 5, 6 sayıları
ise ilgili displayin ortak katoduna gidecektir.
Sistem multiplex sürme sistemini kullanmaktadır
dolayısıyla 7 gösterge elemanının aynı
olan segmentleri birbirlerine
bağlanmalı katodları ise ayrı olarak rakam grubuna sırayla
soldan sağa
gitmelidir.
Besleme voltajı olarak 2.5 – 5.0 volt denmektedir ama en sağlıklı sonuç +5V ile alınır.
Nokta sabit olarak Mhz displayinden sonraki
ilk nokta olarak yakılmalıdır. Bu bir direnç
(270 ohm) ile ilgili
bacak +5V asılarak sağlanır…
Counter.hex
dosyası compile edilmiş programı içerir, counter.asm ise
assenmbler
programdır. Siz counter.hex ile
PIC 16F84 ‘ü programlayabilirsiniz .
Assembler Listesini aşağıda veriyorum.
Counter.zip
dosyası içinde ise gerekli tüm dosyalar mevcuttur.
PICBIT yazılımının son versiyonunu picbit05.zip vermeyi ihmal etmeyelim.
Pic Counter Assembler Listesi:
;
------------------------------------------------------------------------
; FILE :
counter.asm
*
; CONTENTS : Simple low-cost 7-digit counter using a
PIC16F84
*
; COPYRIGHT: Peter Halicky
OM3CPH
*
; AUTHORS : Peter Halicky OM3CPH & Peter Halicky
Jr., OM2APH *
; PCB : Tibor Madarasz
OM2ATM
*
;--------------------------------------------------------------------------
; E-Mail: halicky@cepoe.minv.sk or om3cph@oe3xbs.aut.eu
;
peto-h@writeme.com or om2aph@om0pbm.svk.eu
;
;
Bratislava, Slovakia, February 1998
;
;--------------------------------------------------------------------------
; This is 7-digit counter counting up to 35 MHz. The decimal point
; is after MHz digit.
;
; Power consumption
with calculator display: 2.5V/9mA, 3V/13mA, 5V/35mA.
;
; Hardware is very simple:
;
; It
contains : PIC 16F84
;
4051 (BCD -> 1 of 8 decoder)
;
8 NPN low power Si transistors,
;
7-digit calculator display (common cathode),
;
some resistors, capacitors and 2 switching diodes
;
(see schematic in counter.pcx)
;
; Note:
; "Calculator display" means minimum 7 digit LED multiplexed
display.
; Both common cathode and common anode can be used.
Software is written
; for common cathode display. For common anode
displays it requires very
; slight software and hardware
modification.
;
; The counter uses internal prescaler
of PIC as low byte of counter,
; TMR0 as middle byte and some
register as high byte of counter.
;
; Some ideas were
taken from "Simple low-cost digital frequency meter
;
using a PIC 16C54" (frqmeter.asm)
;
written by James Hutchby, MadLab Ltd. 1996
;
;
------------------------------------------------------------------------
;
; This software is free for private usage. It was created
for HAM radio
; community members. Commercial exploatation is
allowed only with permission
; of authors.
;
;
------------------------------------------------------------------------
IndF
equ
00h ; Indirect addr.
register
Timer0
equ
01h ; TMR0 register
- RP0=0
OptionR
equ
01h ; Option register -
RP0=1
PC
equ
02h ; Program counter
Status
equ
03h ; Status register
FSR
equ
04h ; Pointer register
PortA
equ
05h ; Port A - RP0=0
TrisA
equ
05h ; Tris A - RP0=1
PortB
equ
06h ; Port B - RP0=0
TrisB
equ
06h ; Tris B - RP0=1
;PortC
equ
07h ; Port C - 16C54+84 not
implmented
EEData
equ
08h ; 16C84
EEAdr
equ
09h ; 16C84
PCLath
equ
0Ah ; 16C84
IntCon
equ
0Bh ; 16C84
Index
equ
0Ch ; dummy register
Count
equ
0Dh ; inkremental register
Help
equ
0Eh ; dummy register
LED0
equ 0Fh
LED1
equ 010h
LED2
equ 011h
LED3
equ 012h
LED4
equ 013h
LED5
equ 014h
LED6
equ 015h
LED7
equ 016h
TimerH equ 017h ; higher byte of SW counter
LowB
equ
018h ; low byte of resulted
frequency
MidB
equ
019h ; middle byte of resulted
frequency
HigB
equ
01Ah ; high byte of resulted
frequency
Temp
equ
01Bh ; temporary register
HIndex
equ
01Ch ; index register
LEDIndex equ
01Dh ; LED pointer
; ------------------------------------------------------------------------
; timing loop values
; must be from 1 to 255!!!
T1
equ
.70 ; rough timing
loop
T2
equ
.3 ; timing
loop
T3
equ
.20 ; fine timing
loop
; values for 4 194 kHz
;
------------------------------------------------------------------------
;
; Measuring period is 100 000 us.
; Procesor
cycle is T = 4/fx us [MHz], fx is Xtal frequency
;
; Number of procesor cycles per measuring period:
;
; N = 100 000/T procesor
cycles
; N = fx x 100
000/4 = 25 000 x fx
;
; The main steps of measuring
period:
;
;
1. start measurement,
;
2. precode decimal value of digit to segments,
; 3. if it's 5th digit set
decimal point,
; 4.
output to PortB,
; 5.
output digit number to PortA
; (numbers
from left to right are 6543210),
; 6. test TMR0 overflow bite,
if YES increase TimerH,
;
7. leave digit to light,
; 8. increase digit
number,
; 9. if <7
goto 2,
; 10. else zero digit
number,
; decrease
counter and goto 2,
; 11. stop
measurement,
; 12. shift out
precounter content,
; 13.
precode 3-byte value into 7 decimal numbers,
; 14. goto 1
;
;
------------------------------------------------------------------------
;
; Total timing formula:
;
; N =
25 000 x fx = 60x[(36 + 3xT1 + X)x7 + 2 + 3xT2 + Y] + 19 + 3xT3 + Z
;
; where T1,T2,T3 are initial values of timing loops,
; X, Y, Z are additional tunig
NOPs.
;
;
------------------------------------------------------------------------
W
equ
0 ; destination is
accumulator
F
equ
1 ; register
; ------------------------------------------------------------------------
; Flag bits:
CF
equ
0 ; Carry
DC
equ
1 ; DC
ZF
equ
2 ; Zero
RP0
equ 5
RP1
equ 6
IRP
equ 7
;
------------------------------------------------------------------------
org 0
Start
clrf Index
clrf LEDIndex
clrf LED0
clrf LED1
clrf LED2
clrf LED3
clrf LED4
clrf LED5
clrf LED6
clrf LED7
clrf LowB
clrf MidB
clrf HigB
bsf Status,RP0
movlw b'00010000' ; RA0..RA3
outputs
movwf TrisA ;
RA4 input
movlw b'00000000' ; RB0..RB7
outputs
movwf TrisB
clrwdt
;
movlw b'00100111' ; Prescaler -> Timer0,
movwf OptionR ; 1:256,
rising edge
bcf Status,RP0 ;
goto Go
;------------------------------------------------------------------------
; 3 byte substraction of the constant from the table which sets carry
if
; result is negative
;------------------------------------------------------------------------
Subc24
clrf
Temp ; it will temporary save CF
movf Index,W ;
pointer to low byte of constant
movwf HIndex ; W
-> HIndex
call DecTable ; W returned
with low byte of constant
bsf Status,CF ; set
CF
subwf LowB,F ; LowB
- W -> LowB
; if underflow -> CF=0
btfsc Status,CF
goto Step1
bsf Status,CF
movlw 1
subwf MidB,F ;
decrement MidB
; if underflow -> CF=0
btfsc Status,CF
goto Step1
bsf Status,CF
movlw 1
subwf HigB,F ;
decrement HigB
btfsc Status,CF ; if underflow ->
CF=0
goto Step1
bsf Temp,CF ;
set CF
Step1
decf HIndex,F
movf HIndex,W ; pointer to
middle byte of const
call DecTable
bsf Status,CF
subwf MidB,F ; MidB
- W -> MidB
btfsc Status,CF ; if underflow ->
CF=0
goto Step2
bsf Status,CF
movlw 1
subwf HigB,1 ;
decrement HigB
btfsc Status,CF ; if underflow ->
CF=0
goto Step2
bsf Temp,CF ;
set CF
Step2
decf HIndex,F
movf HIndex,W ; pointer to
middle byte of constatnt
call DecTable
bsf Status,CF
subwf HigB,F ; HigB
- W -> HigB
btfsc Status,CF ; if underflow ->
CF=0
goto ClearCF
bsf Status,CF
goto SubEnd
ClearCF
rrf Temp,CF ;
CF -> Status
SubEnd
retlw 0
;
------------------------------------------------------------------------
; 3 byte addition of the constant from the table which sets carry
if
; result overflows
;
------------------------------------------------------------------------
Addc24
clrf
Temp ; register for temporary storage
of CF
movf Index,W ;
pointer to lower byte of const into W
movwf HIndex ; save
it into HIndex
call DecTable ; W contains
low byte of const
bcf Status,CF ; clear
CF
addwf LowB,1 ; W +
LowB -> LowB
btfss Status,CF ; test overflow
goto Add2
bcf Status,CF ; clear
CF
movlw 1
addwf MidB,F ;
increment MidB
btfss Status,CF
goto Add2
bcf Status,CF
movlw 1
addwf HigB,F ;
increment HigB
btfss Status,CF ; test overflow
goto Add2
bsf Temp,CF ;
store CF
Add2
decf HIndex,F ; pointer to
middle byte into W
movf HIndex,W
call DecTable
bcf Status,CF
addwf MidB,1 ; W +
MidB -> MidB
btfss Status,CF
goto Add3
bcf Status,CF ; clear
CF
movlw 1
addwf HigB,1 ;
increment HigB
btfss Status,CF
goto Add3
bsf Temp,CF
Add3
decf HIndex,F ; pointer to
higher byte into W
movf HIndex,W
call DecTable
bsf Status,CF
addwf HigB,F ; W +
HigB -> HigB,
btfss Status,CF
goto ClarCF
bsf Status,CF
goto AddEnd
ClarCF
rrf Temp,CF ;
CF -> Status
AddEnd
retlw 0
;
------------------------------------------------------------------------
; Tables for 3 byte constants
;
------------------------------------------------------------------------
; Table of decades
;
------------------------------------------------------------------------
DecTable
addwf
PC,F ; W + PC -> PC
retlw
0 ; 10
retlw
0 ;
retlw
0Ah ;
retlw
0 ;
100
retlw
0 ;
retlw
064h ;
retlw
0 ; 1
000
retlw
03h ;
retlw
0E8h ;
retlw
0 ; 10
000
retlw
027h ;
retlw
010h ;
retlw
01h ; 100 000
retlw
086h ;
retlw
0A0h ;
retlw
0Fh ; 1 000
000
retlw
042h ;
retlw
040h ;
;
------------------------------------------------------------------------
; Conversion BCD -> 7 segments
;
------------------------------------------------------------------------
LEDTable
addwf
PC,F ; W + PC -> PC
retlw b'00111111' ; ..FEDCBA = '0'
retlw b'00000110' ; .....CB. = '1'
retlw b'01011011' ; .G.ED.BA = '2'
retlw b'01001111' ; .G..DCBA = '3'
retlw b'01100110' ; .GF..CB. = '4'
retlw b'01101101' ; .GF.DC.A = '5'
retlw b'01111101' ; .GFEDC.A = '6'
retlw b'00000111' ; .....CBA = '7'
retlw b'01111111' ; .GFEDCBA = '8'
retlw b'01100111' ; .GF..CBA = '9'
retlw b'10000000' ; H....... = '.'
;
------------------------------------------------------------------------
; Table for RF shift
; example: 10.7 MHz is set as 1 070
000 = 10 53 B0 hex
;
------------------------------------------------------------------------
MFTable
addwf PC,F
retlw 010h
retlw 053h
retlw 0B0h
;
------------------------------------------------------------------------
; Routine for conversion of 3 byte number into 7 digits
;
------------------------------------------------------------------------
Go
movlw 6*3-1 ;
pointer to dec. table
movwf Index ;
6*3-1 -> Index
movlw
9 ; maximum of
substractions
movwf Count ;
9 -> Count
clrf Help
movlw 6
movwf LEDIndex
Divide
call Subc24 ;
substract untill result is negative,
btfsc Status,CF ; add last substracted
number
goto
Add24 ; next digit
incf Help,F
decf Count,F
btfss Status,ZF
goto Divide
movlw 3
subwf Index,F
goto Next
Add24
call Addc24
movlw 03h
subwf Index,F
Next
movlw 9
movwf Count
movlw
LED1 ; LED1 -> W
addwf LEDIndex,W ; LED1 + LEDIndex ->
W
movwf Temp
decf Temp,F ;
LEDIndex+LED1-1 -> TEMP
movf Temp,W
movwf
FSR ; W ->
FSR
movf Help,W ;
Help -> W
clrf
Help ; save result at LEDx
movwf
IndF ; W -> LED(6..1)
decf LEDIndex,F
movlw 1
addwf Index,W
btfss Status,ZF
goto Divide
movf LowB,W
movwf
LED0 ; the rest -> LED0
;
-------------------------------------------------------------------------
; registers LED0..LED6 are filled with values
;
-------------------------------------------------------------------------
clrf TimerH
clrf Timer0
nop
nop
clrf LEDIndex
movlw
.60 ; set initial counter
value
movwf Index ;
60 -> Index
clrf IntCon ;
global INT disable, Timer0 INT disable
; clear Timer0 overflow bite
;
------------------------------------------------------------------------
; Start measurement: RA3 + RA4 set input
;
------------------------------------------------------------------------
movlw b'00010000' ; all ports set L, RA4 set
H
movwf PortA
bsf Status,RP0
movlw b'00011000' ; RA0..RA2 output,RA3,RA4
input
movwf TrisA
bcf Status,RP0
;
-------------------------------------------------------------------------
; 7-step cycle of digits
;
-------------------------------------------------------------------------
LEDCycle
movlw LED0
addwf LEDIndex,W ; LED1 + LEDIndex ->
W
movwf
FSR ; W ->
FSR
movf IndF,W ;
LED(0..6) -> W
call LEDTable ; W contains
segments
movwf
Temp ; test for decimal
point
movlw 5
bsf Status,ZF
subwf LEDIndex,W
btfss Status,ZF
goto NoDot
bsf Temp,7
NoDot
movf Temp,W
movwf PortB ;
segments -> PortB
movf LEDIndex,W ; LEDIndex ->
W
nop
movwf PortA ;
digit number -> PortA
;
------------------------------------------------------------------------
; Test for TMR0 overflow
;
------------------------------------------------------------------------
btfss IntCon,2
goto DoNothing
incf TimerH,F ; YES!
Increment SW counter
bcf IntCon,2 ; clear
overflow bite
goto O_K
DoNothing
nop
nop
nop
;
------------------------------------------------------------------------
; The first timing loop 2+3*T1+X procesor cycles
;
------------------------------------------------------------------------
O_K
movlw T1
movwf Temp
Pause
decfsz Temp,F
goto Pause
nop
;
nop
; X times NOP
;
nop
; ------------------------------------------------------------------------
incf LEDIndex,F
movlw
7 ; is 7th?
bcf Status,ZF
subwf LEDIndex,W
btfss Status,ZF
goto LEDCycle ; next
digit
nop
;
------------------------------------------------------------------------
; The second timing loop 2+3*T2+Y procesor cycles
;
------------------------------------------------------------------------
movlw T2
movwf Temp
Again
decfsz Temp,F
goto Again
nop
nop
; Y times NOP
nop
; ------------------------------------------------------------------------
clrf LEDIndex
decfsz Index,F
goto LEDCycle ; next
7xLED
nop
;
------------------------------------------------------------------------
; The third timing loop 2+3*T3+Z procesor cycles
;
------------------------------------------------------------------------
movlw T3
movwf Temp
EndPause
decfsz Temp,F
goto EndPause
nop
nop
; Z times NOP
nop
;
------------------------------------------------------------------------
; Final test for TMR0 overflow
;
------------------------------------------------------------------------
btfss IntCon,2
goto Nothing2Do
incf TimerH,F
bcf IntCon,2
goto Nx
Nothing2Do
nop
nop
nop
;
------------------------------------------------------------------------
; Stop the measurement
;
------------------------------------------------------------------------
Nx clrw
movwf PortB
movlw b'00010000' ; RA0..RA3 = 0
movwf PortA ;
W -> PortA
bsf Status,RP0
movlw b'00010000' ; RA0..RA3 output
movwf TrisA ;
RA4 input
bcf Status,RP0
;
------------------------------------------------------------------------
; Analyse precounter and store counted value in registers
;
------------------------------------------------------------------------
movf Timer0,W
movwf
MidB ; TMR0 -> MidB
movf TimerH,W
movwf
HigB ; TimerH -> HigB
clrf Temp
CountIt
incf Temp,F
bsf PortA,3 ;
_| false impulz
bcf PortA,3
; |_
bcf IntCon,2
movf Timer0,W ; actual
Timer0 -> W
bcf Status,ZF
subwf MidB,W
btfsc Status,ZF
goto CountIt
incf Temp,F
comf Temp,F
incf Temp,F
incf Temp,W
movwf LowB
goto Go ; start new cycle
; ------------------------------------------------------------------------
org 0
KAYNAK : http://www21.brinkster.com/serkansah