Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] [PIC16F84] IK3OIL 16F84 PIC Frequency Counter Files

Status
Not open for further replies.

Garyl

Full Member level 5
Joined
Mar 28, 2017
Messages
253
Helped
6
Reputation
12
Reaction score
7
Trophy points
18
Activity points
2,633
Hi,
do any know where to get the firmware or source for
The m-counter, a PIC based programmable frequency meter by Francisco IK3OIL
this project is here:
http://pic-microcontroller.com/ik3oil-16f84-pic-frequency-counter-files/
Here are the links to board and hex but they are DEAD.
http://archive.is/pvjC5

description is such:
This project proposes a simple frequency reader specifically designed for QRP rigs, also if you may
employ it also as a workbench instrument. In fact it exhibits several very interesting features, like a
maximum working frequency above 40 MHz, a 10 Hz resolution, a low consumption (15 mA) and a
very simple assembly. Moreover it is possible to program an IF value and mode simply by means of
two push buttons.
there is a PDF:
View attachment Frequenzimetro_eng_2003.pdf
and schematic:
Frequenzimetro_eng_2003.png

I want to build this project and I need at least the HEX file.
I've tried contacting author by email, but both of his email are dead.

PS: Do you think it would be possible to replicate this missing software in mikro C? I prefer it more than assembler
 

Of course you can write your own software for this. It looks like a basic implementation with three digital inputs (2 pushbuttons and the input signal). Nothing unusual there. Interesting that the link says "here's the source code" and it's a link to a hex file. I'm not sure how this can work "above 40 MHz", though. The maximum clock (and counter) frequency is 20 MHz.
 

The counter inputs in most PICs will work up to around 50MHz but the upper limit isn't guaranteed. When configured correctly, the input to the pin is sent directly to a hardware counter module so it isn't dependent on the system clock frequency. In all designs I've seen, either timer 0 or timer 1 is used as the counter and their overflow interrupts are used as a 'carry' bit to a software counter to increase their range.

I doubt you will be successful writing it in C, the overhead added by the libraries makes the execution time difficult to predict and therefore compensate for in the frequency calculation. It might work in faster PICs but the 16F84 is a relatively old and slow device by todays standards. Look at the 16F628A as one step up and the 16F1847 as it's up-to-date modern equivalent. they are all pin compatible.

Brian.
 
  • Like
Reactions: Garyl

    Garyl

    Points: 2
    Helpful Answer Positive Rating
hello

ASM could be like this one ... but with LCD data on RB4..RB7

Code:
; ------------------------------------------------------------------------
; FILE     : LCD4CNTR.ASM - variation with 4 bite LCD communication      *
; (4-bites, high nibble, RB4..RB7 data, RA0..RA2 control)                *
; CONTENTS : Simple low-cost 7-digit frequency meter using a PIC16F84    *
; COPYRIGHT: Peter Halicky  OM3CPH                                       *
; AUTHOR   : Peter Halicky  OM3CPH & Peter Halicky Jr., OM2PH ex OM2APH  *
; PCB      : Tibor Madarasz OM2ATM                                       *
;--------------------------------------------------------------------------
; E-Mail: peter@halicky.sk     or om3cph@oe3xbs.aut.eu
;
; Bratislava, Slovakia, December 1998, revised & debugged February, 2000
;--------------------------------------------------------------------------
; This is 7-digit frequency meter counting up to 35 MHz. The decimal point
; is after MHz digit, but can be at any position.
;
; Hardware is very simple:
;
; It contains     : PIC 16F84
;                   1 NPN low power HF Si transistor,
;                   16 character (2x8) in 1 Line LCD display,
;                   Xtal 1..10 MHz,
;                   some resistors, capacitors and 2 Si switching diodes...
;                   (see schematic)
; Note:
; LCD display is 16 character in 1 line LCD display PVC160101PTN which
; seems to be compatible with TWO LINES HITACHI LCD display, exept
; that that one has only 8 characters in 1 line.
;
; 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
;
; LCD interfacing was completly taken from Norm Cramer's LCD.ASM
; ------------------------------------------------------------------------
;
; This software is free for private usage. It was created for HAM radio
; community members. Commercial exploatation is allowed only with permission
; of authors.
;
; ------------------------------------------------------------------------
;
; The 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 * 100 000/4 = 25 000 x Fx
;
;        The main steps of measuring period:
;
;        1. decode 3-byte value into 7 decimal numbers,
;        2. decode decimal value of digit to chars,
;        3. set decimal point if needed,
;        4. output to PORTB (LCD),
;        5. start measurement,
;        6. test TMR0 overflow bite, if YES increase TimerH,
;        7. goto 5 until measuring period is done,
;        8. stop measurement,
;        9. shift out precounter content,
;       10. Add/substract RF according signal from optocoupler,
;       11. goto 1
;
; ------------------------------------------------------------------------
;
; Total timing formula: N = 25 000 * Fx = ((9*T1+4)*T2+4)*T3+5+9*T4+Z
;
; N = 25 000 * Fx [MHz]
;
; Example:  Fx = 4 MHz
;
; N = 25 000 * 4 = 100 000
; N = 25 000 * Fx = ((9*T1+4)*T2+4)*T3+5+9*T4+Z
;
; ------------------------------------------------------------------------

      include <p16f84.inc>

; ------------------------------------------------------------------------

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

CHAR        equ       016h         ; LCD subroutines internal use

TimerH      equ       017h         ; the highest 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

R1          equ       01Eh         ; Timing counters
R2          equ       01Fh
R3          equ       020h

; ------------------------------------------------------------------------
; LCD variables
; ------------------------------------------------------------------------

;Xtal       equ       8            ; MHz
DELAY15000  equ       .39          ; 1+15000*Xtal/4/770
DELAY4100   equ       .11          ; 1+4100*Xtal/4/770
DELAY100    equ       1            ; 1+100*Xtal/4/770

LINE0       equ       0
LINE1       equ       040h
                                   ; PORTB bits
E           equ       2            ; LCD Enable control line          RA2
R_W         equ       0            ; LCD Read/Write control line      RA0
RS          equ       1            ; LCD Register-Select control line RA1
                                   ; LCD Data are sent through  RB4 - RB7
; ------------------------------------------------------------------------

            include    <t1234lcd.inc> ; timing loop values

; ------------------------------------------------------------------------

            org        0

Start       clrf       STATUS      ; Do initialization, Select bank 0
            clrf       INTCON      ; Clear int-flags, Disable interrupts
            clrf       PCLATH      ; Keep in lower 2KByte
            clrf       PORTA       ; ALL PORT output should output Low.
            clrf       PORTB

            clrf       Index
            clrf       LEDIndex

            clrf       LED0
            clrf       LED1
            clrf       LED2
            clrf       LED3
            clrf       LED4
            clrf       LED5
            clrf       LED6

            clrf       LowB
            clrf       MidB
            clrf       HigB

            bsf        STATUS,RP0

            movlw      b'00010000' ; RA0..RA3 outputs
            movwf      TRISA       ; RA4 input

            movlw      0xF0        ; RB0..RB3 outputs, rest inputs
            movwf      TRISB

            bsf        OPTION_REG,NOT_RBPU ; Disable PORTB pull-ups

            clrwdt
            movlw      b'10100111' ; Prescaler -> TMR0,
            movwf      OPTION_REG  ; 1:256, rising edge
            bcf        STATUS,RP0  ;
                                   ; Initilize LC-Display Module
                                   ; Busy-flag is not yet valid
            clrf       PORTA       ; ALL PORT output should output Low.
                                   ; Initilize the LCD Display Module
            clrf       PORTB       ; ALL PORT output should output Low

   	    bcf        PORTA,E     ; Clear all controll lines
	    bcf        PORTA,RS
	    bcf        PORTA,R_W

            movlw      DELAY15000  ; Wait for 15ms for LCD to get powered up
            movwf      R1
            clrf       R2

LCycle      decfsz     R2,F
            goto       LCycle      ; 3*256
            decfsz     R1,F        ; 3*256+1
            goto       LCycle      ;(3*256+2)*R1=770*R1 in procesor cycles

;******************************************************************************
; Initialization of LCD display
;******************************************************************************

	    movlw      0x0F
	    andwf      PORTB,F    ; Clear the upper nibble

	    movlw      0x030      ; Command for 4-bit interface high nibble
            iorwf      PORTB      ; Send data to LCD

	    bsf        STATUS,RP0 ; Select Register page 1
	    movlw      0x0F
	    andwf      TRISB,W
	    movwf      TRISB      ; Set Port for output
	    bcf        STATUS,RP0 ; Select Register page 0

	    bsf        PORTA,E    ; Clock the initalize command to LCD module
	    bcf        PORTA,E

            movlw      DELAY4100  ; Delay for at least 4.1ms before continuing
            movwf      R1
            clrf       R2

LCycle2     decfsz     R2,F
            goto       LCycle2    ; 3*256
            decfsz     R1,F       ; 3*256+1
            goto       LCycle2    ;(3*256+2)*R1=770*R1 in procesor cycles

	    bsf        PORTA,E    ; Clock the initalize command to LCD module
	    bcf        PORTA,E

            movlw      DELAY100   ; Wait for 100 us
            movwf      R1
            clrf       R2

LCycle3     decfsz     R2,F
            goto       LCycle3     ; 3*256
            decfsz     R1,F        ; 3*256+1
            goto       LCycle3     ;(3*256+2)*R1=770*R1 in procesor cycles

	    movlw      0x0F
	    andwf      PORTB,F    ; Clear the upper nibble

            movlw      020h       ; Command for 4-bit interface high nibble
	    iorwf      PORTB      ; Send data to LCD

	    bsf        PORTA,E    ; Clock the initalize command to LCD module
	    bcf        PORTA,E

	    movlw      0x028      ; 4 bits, 2 lines, 5x7 Font
	    call       PutCMD

	    movlw      B'00001000'; disp.off, curs.off, no-blink
	    call       PutCMD

            movlw      1          ; LCD clear
            call       PutCMD

            movlw      B'00001100'; disp.on, curs.off
            call       PutCMD

            movlw      B'00000110'; auto-inc (shift-cursor)
            call       PutCMD

            goto       Go         ; to line 493

;************************************************************************
; LCD Module Subroutines
;========================================================================
; Busy: Returns when LCD busy-flag is inactive
;       PORTA returns as RA0..RA2 output, RA3,RA4 input
;************************************************************************

Busy	    bsf        STATUS,RP0 ; Select Register page 1

	    movlw      0xF0       ; Set port to input
	    iorwf      TRISB,W    ; Only set upper half of port
	    movwf      TRISB

            movlw      b'00011000' ; PORTA should be set RA0..RA2 output
            movwf      TRISA       ; RA3,RA4 input

	    bcf        STATUS,RP0 ; Select Register page 0

	    bcf        PORTA,RS   ; Set LCD for Command mode
	    bsf        PORTA,R_W  ; Setup to read busy flag
	    bsf        PORTA,E    ; Set E high
	    bcf        PORTA,E    ; Set E low
	    movf       PORTB,W    ; Read upper nibble busy flag, DDRam address
	    andlw      0xF0       ; Mask out lower nibble
	    movwf      TEMP
	    bsf        PORTA,E    ; Toggle E to get lower nibble
	    bcf        PORTA,E
	    swapf      PORTB,W    ; Read lower nibble busy flag, DDRam address
	    andlw      0x0F       ; Mask out upper nibble
	    iorwf      TEMP,W     ; Combine nibbles
	    btfsc      TEMP,7     ; Check busy flag, high = busy
	    goto       Busy       ; If busy, check again

	    bcf        PORTA,R_W
	    bsf        STATUS,RP0 ; Select Register page 1
	    movlw      0x0F
	    andwf      TRISB,W
	    movwf      TRISB      ; Set Port for output
	    bcf        STATUS,RP0 ; Select Register page 0
	    return

;========================================================================
; PUTCHAR Sends character to LCD, Required character must be in W
;========================================================================

PutCHAR     movwf      CHAR       ; Character to be sent is from W saved
            call       Busy       ; Wait for LCD to be ready
                                  ; Busy routine sets PORTB adequately
	    movlw      0x0F
	    andwf      PORTB,F    ; Clear the upper nibble
	    movf       CHAR,W
	    andlw      0xF0       ; Get upper nibble
	    iorwf      PORTB,F    ; Send data to LCD
	    bcf        PORTA,R_W  ; Set LCD to write
	    bsf        PORTA,RS   ; Set LCD to data mode
	    bsf        PORTA,E    ; toggle E for LCD
	    bcf        PORTA,E
	    movlw      0x0F
	    andwf      PORTB,F    ; Clear the upper nibble
	    swapf      CHAR,W
	    andlw      0xF0       ; Get lower nibble
	    iorwf      PORTB,F    ; Send data to LCD
	    bsf        PORTA,E    ; toggle E for LCD
	    bcf        PORTA,E
            return

;========================================================================
; PutCMD Sends command to LCD, Required command must be in W
;========================================================================

PutCMD      movwf      CHAR       ; Command to be sent is from W saved
            call       Busy       ; Wait for LCD to be ready
	    movlw      0x0F
	    andwf      PORTB,F    ; Clear the upper nibble
	    movf       CHAR,W
	    andlw      0xF0       ; Get upper nibble
	    iorwf      PORTB,F    ; Send data to LCD
	    bcf        PORTA,R_W  ; Set LCD to write
	    bcf        PORTA,RS   ; Set LCD to command mode
	    bsf        PORTA,E    ; toggle E for LCD
	    bcf        PORTA,E
	    movlw      0x0F
	    andwf      PORTB,F    ; Clear the upper nibble
	    swapf      CHAR,W
	    andlw      0xF0       ; Get lower nibble
	    iorwf      PORTB,F    ; Send data to LCD
	    bsf        PORTA,E    ; toggle E for LCD
	    bcf        PORTA,E
	    return

;************************************************************************
; End of LCD Module Subroutines
;************************************************************************
; Numeric routines
;------------------------------------------------------------------------
; 3 byte substraction of the constant from the table which sets carry if
; result is negative
;------------------------------------------------------------------------

Subc24      clrf       TEMP       ; it will TEMPorary save C
            movf       Index,W    ; pointer to low byte of constant
            movwf      HIndex     ; W -> HIndex
            call       DecTable   ; W returned with low byte of constant
            bsf        STATUS,C   ; set C
            subwf      LowB,F     ; LowB - W -> LowB
                                  ; if underflow -> C=0
            btfsc      STATUS,C
            goto       Step1
            bsf        STATUS,C
            movlw      1
            subwf      MidB,F     ; decrement MidB
                                  ; if underflow -> C=0
            btfsc      STATUS,C
            goto       Step1

            bsf        STATUS,C
            movlw      1
            subwf      HigB,F     ; decrement HigB
            btfsc      STATUS,C   ; if underflow -> C=0
            goto       Step1
            bsf        TEMP,C     ; set C

Step1       decf       HIndex,F
            movf       HIndex,W   ; pointer to middle byte of const
            call       DecTable
            bsf        STATUS,C
            subwf      MidB,F     ; MidB - W -> MidB
            btfsc      STATUS,C   ; if underflow -> C=0
            goto       Step2
            bsf        STATUS,C
            movlw      1
            subwf      HigB,1     ; decrement HigB
            btfsc      STATUS,C   ; if underflow -> C=0
            goto       Step2
            bsf        TEMP,C     ; set C

Step2       decf       HIndex,F
            movf       HIndex,W   ; pointer to middle byte of constatnt
            call       DecTable
            bsf        STATUS,C
            subwf      HigB,F     ; HigB - W -> HigB
            btfsc      STATUS,C   ; if underflow -> C=0
            goto       ClearCF
            bsf        STATUS,C
            goto       SubEnd
ClearCF     rrf        TEMP,C     ; C -> 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 C
            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,C   ; clear C
            addwf      LowB,1     ; W + LowB -> LowB
            btfss      STATUS,C   ; test overflow
            goto       Add2
            bcf        STATUS,C   ; clear C
            movlw      1
            addwf      MidB,F     ; increment MidB
            btfss      STATUS,C
            goto       Add2
            bcf        STATUS,C
            movlw      1
            addwf      HigB,F     ; increment HigB
            btfss      STATUS,C   ; test overflow
            goto       Add2
            bsf        TEMP,C     ; store C
Add2        decf       HIndex,F   ; pointer to middle byte into W
            movf       HIndex,W
            call       DecTable
            bcf        STATUS,C
            addwf      MidB,1     ; W + MidB -> MidB
            btfss      STATUS,C
            goto       Add3
            bcf        STATUS,C   ; clear C
            movlw      1
            addwf      HigB,1     ; increment HigB
            btfss      STATUS,C
            goto       Add3
            bsf        TEMP,C
Add3        decf       HIndex,F   ; pointer to higher byte into W
            movf       HIndex,W
            call       DecTable
            bsf        STATUS,C
            addwf      HigB,F     ; W + HigB -> HigB,
            btfss      STATUS,C
            goto       ClarCF
            bsf        STATUS,C
            goto       AddEnd
ClarCF      rrf        TEMP,C     ; C -> STATUS
AddEnd      retlw      0

;------------------------------------------------------------------------
; Tables for 3 byte constants
;------------------------------------------------------------------------
; Table of decades
;------------------------------------------------------------------------

DecTable    addwf      PCL,F      ; W + PCL -> PCL
            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       ;

;************************************************************************
; Entry point for main cycle
;------------------------------------------------------------------------
; Routine for the conversion of 3 byte number into 7 decimal numbers
;************************************************************************

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,C   ; add last substracted number
            goto       Add24      ; next digit
            incf       Help,F
            decf       Count,F
            btfss      STATUS,Z
            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,Z
            goto       Divide

            movf       LowB,W
            movwf      LED0       ; the rest -> LED0

;-------------------------------------------------------------------------
; registers LED0..LED6 are filled with values - ready to be displayed
;-------------------------------------------------------------------------

            movlw      6
            movwf      LEDIndex

            movlw      LINE0
            iorlw      080h       ; Position cursor leftmost on first line
            call       PutCMD

LEDCycle    movlw      LED0       ; LED0 -> W
            addwf      LEDIndex,W ; LED1 + LEDIndex -> W

            movwf      FSR        ; W -> FSR
            movf       INDF,W     ; LED(0..6) -> W

            iorlw      030h
            call       PutCHAR    ; Display character

            movlw      5           ; test for decimal point
            bsf        STATUS,Z
            subwf      LEDIndex,W
            btfss      STATUS,Z
            goto       NoDot
            movlw      '.'         ; this can be ' ' or ',' ......
            call       PutCHAR     ; Display character

NoDot       decfsz     LEDIndex,F
            goto       LEDCycle    ; continue with next number

            movlw      LED0        ; LED0 -> W
            addwf      LEDIndex,W  ; LED0 + LEDIndex -> W

            movwf      FSR         ; W -> FSR
            movf       INDF,W      ; [FSR] -> W

            iorlw      030h
            call       PutCHAR     ; Display character

            movlw      LINE1       ; continue at right half of display
            iorlw      080h        ; Function set
            call       PutCMD      ; Position cursor leftmost on first line

            movlw      ' '
            call       PutCHAR     ; Display character
            movlw      'M'
            call       PutCHAR     ; Display character
            movlw      'H'
            call       PutCHAR     ; Display character
            movlw      'z'
            call       PutCHAR     ; Display character

            movlw      LINE0
            iorlw      080h        ; Function set
            call       PutCMD

;-------------------------------------------------------------------------
; It is time to prepare new measuring cycle
;-------------------------------------------------------------------------

            clrf       TimerH
            clrf       TMR0
            nop                    ; it is SUGGESTED...
            nop

            clrf       LEDIndex

            movlw      T1          ; set initial counter values
            movwf      R1
            movlw      T2
            movwf      R2
            movlw      T3
            movwf      R3

            clrf       INTCON      ; global INT disable, TMR0 INT disable
                                   ; clear TMR0 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'00011111' ; RA0..RA4 input
            movwf      TRISA
            bcf        STATUS,RP0

; -------------------------------------------------------------------------
; It is opened now...
; -------------------------------------------------------------------------

Cycle       btfss      INTCON,2   ; 1   Test for TMR0 overflow
            goto       Nothing    ; 3
            incf       TimerH,F   ; 3
            bcf        INTCON,2   ; 4
            goto       Nxt        ; 6

Nothing     nop                   ; 4
            nop                   ; 5
            nop                   ; 6

Nxt         decfsz     R1,F       ; 7
            goto       Cycle      ; 9
            movlw      T1         ; 9*T1

            movwf      R1         ; 9*T1+1
            decfsz     R2,F       ; 9*T1+2
            goto       Cycle      ; 9*T1+4
            movlw      T2         ;(9*T1+4)*T2

            movwf      R2         ;(9*T1+4)*T2+1
            decfsz     R3,F       ;(9*T1+4)*T2+2
            goto       Cycle      ;(9*T1+4)*T2+4

; ------------------------------------------------------------------------
; Final test for TMR0 overflow
; ------------------------------------------------------------------------

            movlw      T4         ;((9*T1+4)*T2+4)*T3
            movwf      Help       ;((9*T1+4)*T2+4)*T3+1

Cycle2      btfss      INTCON,2   ; 1
            goto       Not2Do     ; 3
            incf       TimerH,F   ; 3
            bcf        INTCON,2   ; 4
            goto       Nx         ; 6

Not2Do      nop                   ; 4
            nop                   ; 5
            nop                   ; 6

Nx          decfsz     Help,F     ; 7
            goto       Cycle2     ; 9
            nop                   ; ((9*T1+4)*T2+4)*T3+1+9*T4+Z

;            nop                   ; Z times fine tuning nops

            include    <z4lcd.inc>

; ------------------------------------------------------------------------
; Stop the measurement
; ------------------------------------------------------------------------

            clrw                   ; 1
            movwf      PORTB       ; 2
            movlw      b'00010000' ; 3   RA0..RA3 = 0
            movwf      PORTA       ; 4   W -> PORTA
                                   ; ((9*T1+4)*T2+4)*T3+1+9*T4+Z+4
            bsf        STATUS,RP0  ;
            movlw      b'00010111' ;     RA3 output
            movwf      TRISA       ;     RA0..RA2,RA4 input
            bcf        STATUS,RP0  ;

; ------------------------------------------------------------------------
; Analyse precounter and store counted value in registers
; ------------------------------------------------------------------------

            movf       TMR0,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       TMR0,W      ; actual TMR0 -> W
            bcf        STATUS,Z
            subwf      MidB,W
            btfsc      STATUS,Z
            goto       CountIt
            incf       TEMP,F
            comf       TEMP,F
            incf       TEMP,F
            incf       TEMP,W

            movwf      LowB

            goto       Go          ;  start new cycle - line 434

; ------------------------------------------------------------------------

            end


**broken link removed**
and with other MCU ...
 

The counter inputs in most PICs will work up to around 50MHz but the upper limit isn't guaranteed. When configured correctly, the input to the pin is sent directly to a hardware counter module so it isn't dependent on the system clock frequency. In all designs I've seen, either timer 0 or timer 1 is used as the counter and their overflow interrupts are used as a 'carry' bit to a software counter to increase their range.

I doubt you will be successful writing it in C, the overhead added by the libraries makes the execution time difficult to predict and therefore compensate for in the frequency calculation. It might work in faster PICs but the 16F84 is a relatively old and slow device by todays standards. Look at the 16F628A as one step up and the 16F1847 as it's up-to-date modern equivalent. they are all pin compatible.

Brian.
If you read the data sheet it has minimum high time of 30nS and minimum low time of 20nS for TOclock; that's 20MHz.
 

I agree Barry but I think the data sheet is saying (ambiguously) those are the guaranteed longest periods it will recognize. In practice, almost all PIC timers will clock at 40MHz and some as high as 50MHz. The sync with internal clock is after the prescaler output so system clock doesn't restrict it until after division.

Unofficially, most PICs with external system clock inputs will run at 50% above rated speed at full supply voltage although I seriously wouldn't recommend it, especially in a production design. Back a few years ago, experimentally, I tried pushing a 16F84A to it's limit and it went to 36MHz before falling over! I wouldn't want to rely on it at that speed and I suspect dynamic currents would have required the port loading to be much reduced from normal.

Brian.
 
  • Like
Reactions: Garyl

    Garyl

    Points: 2
    Helpful Answer Positive Rating
Look at the 16F628A as one step up and the 16F1847 as it's up-to-date modern equivalent. they are all pin compatible.

That's indeed a good observation. So you say that the best option would be using the new 16F1847 and writing the code in C?


btw, I've found something strange.
The 16F1847 datasheet reads:
Code:
• 1.8V-5.5V Operation – PIC16F1847
• 1.8V-3.6V Operation – PIC16LF1847
is this really correct? The "L" letter means low-votlage only?
Afair, for the PIC18F2550 and PIC18LF2550 the "L" meant that PIC is for 1.8-5.5V operation, and the version without L was 3.6V-5.5V or something like that.
 

When counter/timer uses external input you must use synchronization, that limits the input to be half the crystal frequency when the input is 50% duty cycle. To count 20Mhz 50% duty cycle you have to use the pre-scaler and that reduces the resolution.
This website has a few samples, I tried a few and they worked. **broken link removed**

- - - Updated - - -

That's indeed a good observation. So you say that the best option would be using the new 16F1847 and writing the code in C?


btw, I've found something strange.
The 16F1847 datasheet reads:
Code:
• 1.8V-5.5V Operation – PIC16F1847
• 1.8V-3.6V Operation – PIC16LF1847
is this really correct? The "L" letter means low-votlage only?
Afair, for the PIC18F2550 and PIC18LF2550 the "L" meant that PIC is for 1.8-5.5V operation, and the version without L was 3.6V-5.5V or something like that.

You are correct, the USB PIC needs 5V supply for the 48MHz CPU and for the 3.3V regulated supply for the USB output.
 

??? 16F1847 doesn't have a USB interface!

But yes, the 'L' is a low voltage version. There is a minor 'gotcha' to be aware of, the maximum clock frequency can't be reached at the lowest voltage. The graphs in the data sheet show the speed it is limited to for different supply voltages. It does have a PLL frequency multiplier so even with a low frequency XTAL it can still process at high speed.

I use them in various projects and even have one producing a text overlay in a TV picture.

Brian.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top