PDA

View Full Version : frequency meter in PBP



savnik
- 12th June 2007, 09:14
The code below is for frequency meter 0-50Mhz.
it is posible to import in pbp;


processor 16F84a
include p16f84a.inc

RAM equ h'0C'
YES equ 1
NO equ 0

;PORTA
CONFIGA equ B'00010000'

;Port B
CONFIGB equ B'00000000'
PULLUP equ NO

;OPTION
CONFOPT equ B'00100111'

;INTERRUPTION
CONFINT equ B'00000000'

cblock RAM
Temp
Temp0
TimeOut
SaveW
Result : 4
Count
Char
Thousand : 2
BCD0
BCD1
BCD2
BCD3
N
endc


Reset START
IntReq Intserv

IncPre macro
bsf PORTA,3
bcf PORTA,3
endm

Init macro
clrf PORTA
clrf PORTB
Bank1
Movlf CONFIGA,TRISA
Movlf CONFIGB,TRISB
Movlf CONFOPT,OPTION_REG
Movlf CONFINT,INTCON
Bank0
bsf POWER
endm

InitMeasure macro
Movlf B'00000011',Thousand ; Change: Thousand=(999)10
Movlf B'11100111',Thousand+1
clrf TMR0
clrf Result+1
clrf Result
endm

Ra3_out macro
Bank1
bcf TRISA,3
Bank0
endm

Ra3_in macro
Bank1
bsf TRISA,3
Bank0
endm

TJZ16 macro file16,address
Test file16
JZ TJZ16_MSB_ZERO
nop
nop
goto TJZ16_END
TJZ16_MSB_ZERO
Test file16 +1
JZ address
TJZ16_END
endm

ClearDisp macro
movlw b'00000001'
call SEND_CMD
call T1mS
endm

DataOk macro
bsf E
bcf E
endm

DDRam macro address
movlw 0x80 + address
call SEND_CMD
endm

Disp macro charvalue
movlw charvalue
call SEND_CHAR
endm

RSCmd macro
bcf RS
endm

RSChar macro
bsf RS
endm

ShiftL macro
movlw b'00011000'
call SEND_CMD
endm

T975us
Movlf .243 ,Temp0
Loop975us
nop
decfsz Temp0,f
goto Loop975us

return

;Name : Readprescal
;Function: Read the prescaler and store the result.
;Input : tmr0 and prescaler
;Output : Result +2 (tmr0) and Result +3 (prescaler)
;Call : None
;Register: Count

Readprescal
Movlf 255,Count
Movff TMR0,Result+2

INCREMENT
IncPre
incf Count,f
CJE TMR0,Result+2,INCREMENT
movf Count,w
sublw 255
movwf Result+3
return

; Bin To BCD conversion ( 32 bit word -> 8 digits )
; Bin in Result, Result+1, Result+2, Result+3
; BCD in BCD3, BCD2, BCD1, BCD0
Bin2BCD
clrc
Movlf .32,N
clrf BCD3
clrf BCD2
clrf BCD1
clrf BCD0
LoopBB
rlf Result+3,f
rlf Result+2,f
rlf Result+1,f
rlf Result,f
rlf BCD3,f
rlf BCD2,f
rlf BCD1,f
rlf BCD0,f
decfsz N,f
goto DecAdj
return

DecAdj
Movlf BCD3,FSR
call BCDAdj
Movlf BCD2,FSR
call BCDAdj
Movlf BCD1,FSR
call BCDAdj
Movlf BCD0,FSR
call BCDAdj
goto LoopBB
BCDAdj
movlw 3
addwf INDF,w
movwf Temp
btfsc Temp,3
movwf INDF
movlw 30H
addwf INDF,w
movwf Temp
btfsc Temp,7
movwf INDF
return

; Display Frequency stored in BCD3, BCD2, BCD1 and BCD0 (LSD)

DispFreq
DDRam 3
swapf BCD0,W
andlw 0FH
call DispHex
movf BCD0,W
andlw 0FH
call DispHex
Disp '.'

swapf BCD1,W
andlw 0FH
call DispHex
movf BCD1,W
andlw 0FH
call DispHex
swapf BCD2,W
andlw 0FH
call DispHex
Disp '.'

movf BCD2,W
andlw 0FH
call DispHex
swapf BCD3,W
andlw 0FH
call DispHex
movf BCD3,W
andlw 0FH
call DispHex

return

; Display hex digit
; input : w = hex

DispHex
addlw -0AH
SkipNC
addlw 7
addlw 3AH
call SEND_CHAR

return

Intserv
retfie
;____________________________________main_________ ______________

START Init

call INIT_LCD

movlw b'00001100'
call SEND_CMD

movlw b'00101000'
call SEND_CMD

Movlf 226,TimeOut

ClearDisp

Disp 'F'
Disp 'R'
Disp 'E'
Disp 'Q'
Disp 'U'
Disp 'E'
Disp 'N'
Disp 'C'
Disp 'Y
Disp 'M'
Disp 'E'
Disp 'T'
Disp 'E'
Disp 'R'
Disp ' '

call T1S
call T1S

ClearDisp

call T100mS

Disp ' '
Disp ' '
Disp '5'
Disp '0'
Disp ' '
Disp 'M'
Disp 'H'
Disp 'z'
Disp ' '
Disp ' '

call T1S
call T1S

ClearDisp

call T100mS

Disp 'F'
Disp ' '
Disp ' '
Disp ' '
Disp ' '
Disp ' '
Disp ' '
Disp ' '
Disp ' '
Disp ' '
Disp ' '
Disp ' '
Disp ' '
Disp ' '
Disp 'H'
Disp 'z'

MEASURE InitMeasure

Ra3_in
call T975us
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop

GATE TJZ16 Thousand,STOP

WAIT call T975us
Dec16 Thousand

btfss INTCON,T0IF
goto NO_OVERFLOW_TMR0

OVERFLOW_TMR0
bcf INTCON,T0IF
incf Result+1,f
JZ INC_RESULT
nop
nop
goto GATE

INC_RESULT
incf Result,f
goto GATE

NO_OVERFLOW_TMR0
nop
nop
nop
nop
nop
goto GATE

STOP Ra3_out

READ call Readprescal
call Bin2BCD
call DispFreq

TEST Test BCD0
SkipNZ
Test BCD1
SkipNZ
Test BCD2
SkipNZ
Test BCD3
SkipNZ
goto TIME_CONTROL
clrf TimeOut
goto MEASURE

TIME_CONTROL
incf TimeOut,F
JZ MESS_TIME_OUT
goto MEASURE

MESS_TIME_OUT
ClearDisp

Disp ' '
Disp 'A'
Disp 'R'
Disp 'R'
Disp 'E'
Disp 'T'
Disp ' '
Disp 'A'
Disp 'U'
Disp 'T'
Disp 'O'

call T1S
call T1S

bcf POWER
LOOP_STOP
goto LOOP_STOP
end

mister_e
- 12th June 2007, 11:05
Yes, but why?

savnik
- 12th June 2007, 12:16
Yes, but why?
Because i want to add to code(in pbp) some others things , like to measure ADC.
I try two days now without any result.

Ioannis
- 12th June 2007, 13:18
Hi Niko!

Assembly is much more faster than any other lanquage. The code you posted I think is from an old AN from Microchip, right? I studied few years ago. My opinion is that you will need a top class PIC with the highest XTAL to reach the needed speed. Is it worth really?

Ioannis

skimask
- 12th June 2007, 13:37
Because i want to add to code(in pbp) some others things , like to measure ADC.
I try two days now without any result.

Gave up on trying to write one yourself?
You'll never get any fast counting done with a PIC and straight PBP (maybe 250khz), assembly might get you 10Mhz, if you use a 40Mhz PIC and you use one of the TMR inputs.
However, if you take my idea (from the other thread), and use a pre-divider, you'll count much higher.
And check this out....
http://members.cox.net/berniekm/super.html

Ioannis
- 12th June 2007, 13:58
Hi Skimask. If you study the Microchip AN592, you 'll see that a humble PIC 16C55 is counting up to 50 MHz!

It use a clever technique to do that. But in PBP, I think it is quite difficult to obtain.

Ioannis

skimask
- 12th June 2007, 14:04
Hi Skimask. If you study the Microchip AN592, you 'll see that a humble PIC 16C55 is counting up to 50 MHz!

It use a clever technique to do that. But in PBP, I think it is quite difficult to obtain.

Ioannis

Right, using the prescaler, I understand that, 10ns rise/fall time on the RTCC pin...works fine I'm sure (although I've never tried that particular project on that particular PIC).
And that's what I was saying in the other thread about PBP. Use an external 74193 or something similar to pre-scale the count, and PBP should be able to count a fairly high number.

savnik
- 12th June 2007, 16:19
Hi Niko!

Assembly is much more faster than any other lanquage. The code you posted I think is from an old AN from Microchip, right? I studied few years ago. My opinion is that you will need a top class PIC with the highest XTAL to reach the needed speed. Is it worth really?

Ioannis
This is not from Microchip , but i have make the an592 from Microchip with a
pic16f84a and prescaler and count until 1500 MHZ.

mister_e
- 12th June 2007, 20:27
Gave up on trying to write one yourself?
You'll never get any fast counting done with a PIC and straight PBP (maybe 250khz), assembly might get you 10Mhz, if you use a 40Mhz PIC and you use one of the TMR inputs.
However, if you take my idea (from the other thread), and use a pre-divider, you'll count much higher.
And check this out....
http://members.cox.net/berniekm/super.html
Everything is around the sampling time and the accuracy you want not much. Depending of your PIC characteristic, 50MHZ is easy to do, 1500 MHZ??? i have some doubt, but with external hardware divider, there's no real problem.
For high frequency... who want to use 1Sec time base? Nobody... 100mSec, 10mSec, 1mSec is more than possible.

Nothing hard, nothing clever at all. Set a Timer as counter, Clear it, enable it, do you samppling time,m stop it, read it display it. 4 code line or so.

@Savnik, Which PIC you want to use?

Have a look to T0CKI, T1CKI. This will reveal tons of things.

savnik
- 13th June 2007, 06:34
Depending of your PIC characteristic, 50MHZ is easy to do, 1500 MHZ???
I have use external divider(:256)


Nothing hard, nothing clever at all. Set a Timer as counter, Clear it, enable it, do you samppling time,m stop it, read it display it. 4 code line or so.
.
Yes , i use the below code(from AN592)


asm
enabletmr0 macro
clrf TMR0
bsf _trisabuf,3
movf _trisabuf,W
tris PORTA
endm

disabletmr0 macro
bcf _trisabuf,3
bcf PORTA,3
movf _trisabuf,W
tris PORTA
endm

movlw 0x10 ;initialize ddra
movwf _trisabuf ; /
disabletmr0
movlw 0x37 ;set the option register - B'00110111'
option ;to measure high freq.
clrw

enabletmr0 ;enable tmr0
call delay5mS ;wait for 5mS
disabletmr0 ;disable tmr0
call getfreq ;get freq in fhi and flo

;delay1ms, is a very accurate 1mS delay for a 4Mhz clock.
delay1mS
movlw 197
movwf _count1
nop
goto $+1
goto $+1
dly1mS
goto $+1
decfsz _count1, F
goto dly1mS
retlw 0

;delay5mS uses delay1mS to get a very accurate 5 mS delay
delay5mS
call delay1mS
call delay1mS
call delay1mS
call delay1mS
call delay1mS
movlw 4
movwf _count1
tweek5mS
decfsz _count1, F
goto tweek5mS
return

getfreq
movf TMR0,W ;get the tmr0 value
movwf _fhi ;save in fhi
clrf _count1 ;keep track of the toggles
toggle1
incf _count1, F ;inc for first
bcf PORTA,3 ;toggle the input
bsf PORTA,3 ; /
movf TMR0,W ;see if tmr0 incremented
subwf _fhi,W ; /
btfsc STATUS,Z ;yes then skip
goto toggle1 ;no then toggle again
comf _count1, F ;else complement count
incf _count1,W ;and increment
movwf _flo ;save in flo
retlw 0 ;return
endasm


@Savnik, Which PIC you want to use?
i use 16f88.