Frequency Counter

Page: 12 > Showing page 1 of 2
Author
crs
New Member
  • Total Posts : 13
  • Reward points : 0
  • Joined: 2007/08/03 08:44:28
  • Location: Gurdon Arkansas USA
  • Status: offline
2011/08/01 13:45:09 (permalink)
0

Frequency Counter

Building frequency counter with the following code:
int main(void)
{
     char string[16];
     long x;
 
     TRISA = 0x0f;
     TRISB = 0x0fbf;
     LATAbits.LATA4 = 0;
     CLKDIVbits.RCDIV0 = 0;
     CLKDIVbits.RCDIV1 = 0;
     CLKDIVbits.RCDIV2 = 0;
     RPINR3 = 5;
     mSec_delay(500);
     init_lcd();
     while (1)
     {
          T2CON = 0x000a;
          PR2 = 0xffff;
          PR3 = 0xffff; 
          TMR3HLD = 0;
          TMR2 = 0; 
          T1CON = 0x0030;
          PR1 = 62500;
          TMR1 = 0;
          IFS0bits.T1IF = 0;
          T1CONbits.TON = ON;
          T2CONbits.TON = ON;
          while(IFS0bits.T1IF == 0);
          T2CONbits.TON = OFF;
          T1CONbits.TON = OFF;
          x = TMR2; 
          x = x + TMR3HLD  * 65536          
          sprintf(string, "%ld", x);
          lcd_print_xy(1, 1, "          "); 
          lcd_print_xy(1, 1, string); 
     }
 return 0; 
}
 
If I set T2CON to 0x0008 and read Tcy, it reads 16000005, so it reads Tcy ok. If I set T2CON to 0x000a and put a signal at 9.6 Mhz on RP5 it reads 6398333. It is just breadboarded but the reading is stable so I don't think it is noise on the pin. Using 24fj64ga002. Anyone know what might wrong?
 
Charles
post edited by crs - 2011/08/03 21:25:41
#1

26 Replies Related Threads

    crs
    New Member
    • Total Posts : 13
    • Reward points : 0
    • Joined: 2007/08/03 08:44:28
    • Location: Gurdon Arkansas USA
    • Status: offline
    Re:Frequency Counter 2011/08/04 09:19:40 (permalink)
    0
    If I put the 8 Mhz clock to the input pin it reads 8000001. If I engage the divide by 8 it reads 1200001(with the 9.6 Mhz clock), so I think it might be that the 9.6 Mhz is to high for the input or it needs syncing to the clock. Anyone know what  the maximum frequency that can be input?
     
    Charles
    #2
    Antipodean
    Super Member
    • Total Posts : 1536
    • Reward points : 0
    • Joined: 2008/12/09 10:19:08
    • Location: Didcot, United Kingdom
    • Status: offline
    Re:Frequency Counter 2011/08/04 09:30:29 (permalink)
    0
    crs

    If I put the 8 Mhz clock to the input pin it reads 8000001. If I engage the divide by 8 it reads 1200001(with the 9.6 Mhz clock), so I think it might be that the 9.6 Mhz is to high for the input or it needs syncing to the clock. Anyone know what  the maximum frequency that can be input?
     
    Charles


    You should be able to tell that from the data sheet timing figures.
     
     

    Do not use my alias in your message body when replying, your message will disappear ...

    Alan
    #3
    peterpan73
    New Member
    • Total Posts : 9
    • Reward points : 0
    • Joined: 2011/10/13 18:23:14
    • Location: 0
    • Status: offline
    Re:Frequency Counter 2011/10/13 18:33:08 (permalink)
    0
    Hi I want to build the freq coutner mentioned here http://www.radiolocman.com/shem/schematics.html?di=106947 and here http://www.qsl.net/y/yo5ofh//pic/digiscale.htm but the coding is for common cathode. I am a noob when it comes to code. How do you make this work for a common anode display setup form the code below that the author has constructed - 
     
    ; 8DGTCACC.INC: 8 digits CA or CC 7-segments LED display
    ; using conditional assembly
    ;-------------------- keywords for conditional assembly -----------------
    ; uncomment only one among these two directives
    ;#define useCAdisplay  ; if using Common Anode 7-segment display
    #define useCCdisplay  ; if using Common Cathode 7-segment display
    ; uncomment only one among these five directives
    ;#define PORTX 5  ; if using PORTA (full 8 bits, example: PIC16F628)
    #define PORTX 6  ; if using PORTB (any 18 pins mid-range PICmicro)
    ;#define PORTX 7  ; if using PORTC (any 28 pins mid-range PICmicro)
    ;#define PORTX 8  ; if using PORTD (any 40 pins mid-range PICmicro)
    ;#define PORTX 9  ; if using PORTE (any 40 pins mid-range PICmicro)
    ;------------------------------------------------------------------------
    ; declare in the main file:
    ;------------------------------------------------------------------------
    ; numdgt   ; .128, then .64, .32, .16, .8, .4, .2, .1
    ; rlfcnt   ; .8, then .7, .6, .5, .4, .3, .2, .1
    ; affvis   ; ratio display visible
    ; dgtvis   ; digit currently displayed
    ;
    ; dgtDS7   ; digit #7 (left most digit)
    ; dgtDS6   ; digit #6
    ; dgtDS5   ; digit #5
    ; dgtDS4   ; digit #4
    ; dgtDS3   ; digit #3
    ; dgtDS2   ; digit #2
    ; dgtDS1   ; digit #1
    ; dgtDS0   ; digit #0 (right most digit)
    ;
    ;------------------------------------------------------------------------
    ; macro to prepare input parameters to "Disp" routine
    ;------------------------------------------------------------------------
    DISPDGT macro posdgt, dgt
     MOVLW posdgt
     MOVWF rlfcnt
     MOVF dgt, w
     CALL Disp
     endm
    ;------------------------------------------------------------------------
    ;config. RBx & CC as outputs, (if Common Cathode), then RBx=HIGH & CC=LOW
    ;Config. RBx & CA as outputs, (if Common Anode), then RBx=LOW & CA=HIGH
    ;------------------------------------------------------------------------
    SEGx macro REGx, RBx, jump, configRB, dgtX
     BTFSC dgtX, RBx
     GOTO  jump
    #ifdef useCCdisplay
     BTFSS REGx, RBx  ; conditional assembly
    #endif
    #ifdef useCAdisplay
     BTFSC REGx, RBx  ; conditional assembly
    #endif
     
     GOTO  jump
     BSF STATUS, RP0  ; flip to bank1
     MOVLW configRB
     XORWF dgtX, w
     MOVWF PORTX
     BCF STATUS, RP0  ; go back to bank0
     MOVLW configRB
    #ifdef useCCdisplay 
     XORLW 0FFh  ; complement W (conditional assembly)
    #endif
     
     MOVWF PORTX
     MOVLW .128  ; internal delay = 0.5 ms (quartz 4 MHz)
     ADDLW 0FFh  ; W--
     BTFSS STATUS, Z ; bit Z=1 (i.e. W = 0 ?)
     GOTO $-2  ; loop = 4 * 128 = 512 us
     
     endm
    ;-----------------------------------------------------------------------
    ; Routine to display 8 digits
    ; (one digit at a time, segment by segment individually)
    ;-----------------------------------------------------------------------
    Display
     MOVLW .15
     MOVWF affvis
    dispdgts
     DISPDGT .8, dgtDS7
     DISPDGT .7, dgtDS6
     DISPDGT .6, dgtDS5
     DISPDGT .5, dgtDS4
     DISPDGT .4, dgtDS3
     DISPDGT .3, dgtDS2
     DISPDGT .2, dgtDS1
     DISPDGT .1, dgtDS0 
     
     DECFSZ affvis, f
     GOTO dispdgts
     RETURN
    ;-----------------------------------------------------------------------
    ; Common Cathode digit, light segment by segment
    ; Common Anode digit, light segment by segment
    ;-----------------------------------------------------------------------
    Disp
     MOVWF   dgtvis
     MOVLW high Tab7seg
     MOVWF PCLATH
     MOVF dgtvis, w ; (dgtvis) -> W
     CALL Tab7seg  ; convert
     MOVWF dgtvis  ; (dgtvis) converted to 7 segments code
     
    #ifdef useCAdisplay
     COMF dgtvis, f ; conditional assembly (for Common Anode)
    #endif
     CLRF numdgt
     BSF dgtvis, 7
     BSF STATUS, C
    rlfloop
     RLF numdgt, f
     RLF dgtvis, f
     BTFSC STATUS, C
     GOTO setBit0
     BCF dgtvis, 0
     GOTO rlfnext
    setBit0
     BSF dgtvis, 0 
    rlfnext
     BCF STATUS, C
     DECFSZ rlfcnt, f
     GOTO rlfloop
     
    DispsegA SEGx dgtvis,0,DispsegB,0FEh, numdgt ; Disp. dgtvis, bit0
    DispsegB SEGx dgtvis,1,DispsegC,0FDh, numdgt ; Disp. dgtvis, bit1
    DispsegC SEGx dgtvis,2,DispsegD,0FBh, numdgt ; Disp. dgtvis, bit2
    DispsegD SEGx dgtvis,3,DispsegE,0F7h, numdgt ; Disp. dgtvis, bit3
    DispsegE SEGx dgtvis,4,DispsegF,0EFh, numdgt ; Disp. dgtvis, bit4
    DispsegF SEGx dgtvis,5,DispsegG,0DFh, numdgt ; Disp. dgtvis, bit5
    DispsegG SEGx dgtvis,6,DispsegX,0BFh, numdgt ; Disp. dgtvis, bit6
    DispsegX SEGx dgtvis,7,Dispoff, 07Fh, numdgt ; Disp. dgtvis, bit7
    Dispoff
     CLRF PORTX  ; clear portX
     RETURN

    ; 8DGTCNT.ASM: main file to test display file "8DGTCACC.INC"
    ;------------------------------------------------------------------------------
     list P = 16F628A
    #include <p16f628a.inc>
     __CONFIG _CP_OFF &_BODEN_OFF &_PWRTE_ON &_WDT_OFF &_LVP_OFF &_MCLRE_OFF &_INTRC_OSC_NOCLKOUT
    ;---------------------- DEFINE HARDWARE ---------------------------------------
    #define BTN PORTA, 4 ; push button connected to RA4
    ;--------------------- DEFINE VARIABLES ---------------------------------------
     CBLOCK 0x70  ; common RAM [16 bytes, 0x70 to 0x7F]
     numdgt   ; .128, puis .64, .32, .16, .8, .4, .2, .1
     rlfcnt   ; .8, puis .7, .6, .5, .4, .3, .2, .1
     affvis   ; ratio display visible
     dgtvis   ; digit currently displayed
     
     dgtDS7   ; digit #7 (left most digit)
     dgtDS6, dgtDS5, dgtDS4 ; digit #6, digit #5, digit #4
     dgtDS3, dgtDS2, dgtDS1 ; digit #3, digit #2, digit #1
     dgtDS0   ; digit #0 (right most digit)
     ENDC
    ;------------------------------------------------------------------------------
    ; increment one digit from 0 to maxi-1 ; if maxi, then wrap to 0
    ;------------------------------------------------------------------------------
    INC1 macro digitX, maxi, jump
     INCF digitX, f ; increment digitX
     MOVLW maxi
     XORWF digitX, w
     BTFSS STATUS, Z ; digitX = maxi ?
     GOTO jump  ; no
     CLRF digitX  ; yes, then clear digitX
     endm
    ;//////////////////////////////////////////////////////////////////////////////
     ORG  0x00  ; reset vector
     GOTO Start
    ;------------------------------------------------------------------------
    ; L.U.T. to convert a decimal value into the corresponding 7 segment code
    ;------------------------------------------------------------------------
    Tab7seg
     ADDWF PCL, f  ; display 7 segments GFEDCBA
     DT 3Fh, 06h, 5Bh, 4Fh, 66h, 6Dh, 7Dh, 07h, 7Fh, 6Fh
    ;///////////////////////////////////////////////////////////////////////////////// 
    #include "8DGTCACC.INC"
    ;/////////////////////////////////////////////////////////////////////////////////
    Start
     bsf STATUS, RP0 ; flip to Bank 1
     bsf BTN  ; config. BTN as input
     bcf STATUS, RP0 ; back to Bank 0
     clrf dgtDS7
     clrf dgtDS6
     clrf dgtDS5
     clrf dgtDS4
     clrf dgtDS3
     clrf dgtDS2
     clrf dgtDS1
     clrf dgtDS0
    tstBtn
     btfsc BTN  ; BTN pushed
     goto majDisp  ; no
    IncDgts
     INC1 dgtDS0, .10, majDisp
     INC1 dgtDS1, .10, majDisp 
     INC1 dgtDS2, .10, majDisp
     INC1 dgtDS3, .10, majDisp 
     INC1 dgtDS4, .10, majDisp
     INC1 dgtDS5, .10, majDisp 
     INC1 dgtDS6, .10, majDisp
     INC1 dgtDS7, .10, majDisp
    majDisp
     CALL    Display
     GOTO tstBtn
    ;------------------------------------------------------------------------
     END
    post edited by peterpan73 - 2011/10/13 21:07:02
    #4
    DarioG
    Scheisse Menschen
    • Total Posts : 52256
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: hi there
    • Status: offline
    Re:Frequency Counter 2011/10/13 19:45:57 (permalink)
    0
    Try again with another Browser..

    Dario Greggio
    --
    Wouldn't it be wonderful, if you lost one son for every promise you don't keep?
    #5
    peterpan73
    New Member
    • Total Posts : 9
    • Reward points : 0
    • Joined: 2011/10/13 18:23:14
    • Location: 0
    • Status: offline
    Re:Frequency Counter 2011/10/13 21:11:57 (permalink)
    0
    message edited. Does uncommenting mean adding a semicolon to a line ?? If so then
     
    ;#define useCAdisplay  ; if using Common Anode 7-segment display
    #define useCCdisplay  ; if using Common Cathode 7-segment display
     
    means I have chosen common anode right??? 
    #6
    DarioG
    Scheisse Menschen
    • Total Posts : 52256
    • Reward points : 0
    • Joined: 2006/02/25 08:58:22
    • Location: hi there
    • Status: offline
    Re:Frequency Counter 2011/10/14 02:06:18 (permalink)
    0
    Yep, though I don't know this code.

    Dario Greggio
    --
    Wouldn't it be wonderful, if you lost one son for every promise you don't keep?
    #7
    peterpan73
    New Member
    • Total Posts : 9
    • Reward points : 0
    • Joined: 2011/10/13 18:23:14
    • Location: 0
    • Status: offline
    Re:Frequency Counter 2011/10/14 09:53:22 (permalink)
    0
    I tried to rename the above file 8DGTCACC.INC. When I tried to build from MPLAB with the Hitech Compiler it gives me a " "Error [939] ; . no file arguments"
    post edited by peterpan73 - 2011/10/14 09:54:39
    #8
    dan1138
    Super Member
    • Total Posts : 2497
    • Reward points : 0
    • Status: offline
    Re:Frequency Counter 2011/10/14 16:41:56 (permalink)
    0
    peterpan73I tried to rename the above file 8DGTCACC.INC. When I tried to build from MPLAB with the Hitech Compiler it gives me a " "Error [939] ; . no file arguments"

    You seem to be struggling with some basic ideas about how to build the source code.
     
    Attached is the source code and project file.
     
    The code is not exactly the same as what you are working with but it is as close as I could find for something that builds with no errors.
     
    #9
    peterpan73
    New Member
    • Total Posts : 9
    • Reward points : 0
    • Joined: 2011/10/13 18:23:14
    • Location: 0
    • Status: offline
    Re:Frequency Counter 2011/10/15 05:24:53 (permalink)
    0
     Thanks a ton Dan. I'll settle for 7 digit. Yes, like I mentioned I'm a total noob in this. I'm in two minds about this project. If I don;t get through to make a workable hex at the end I might just buy a ICM7216/7226 from an online chinese shop or make this <a href="http://www.elektor.com/magazines/2004/march/multifunction-frequency-meter.56830.lynkx" target="_blank" rel="nofollow">http://www.elektor.com/ma....56830.lynkx</a> .   I started this project with an old dual 7217 based 8 digit LED freq counter Elektor kit that I shelved way back in the 90s. One of the 7217s burnt out while testing the kit. They are now obsolete and the schematics along with kit have a complicated divider network of 8 pieces of 4 way DIP switches to go along. I have already constructed the front panel to go along with it and before I call it quits have decided to give this one more shot with either a PIC, or the above two options or with a discrete 74XX /4XXX based circuitry for the sake of bringing this project to closure.
    Is the file atachment for common cathode or common anode?? I need the CA
    post edited by peterpan73 - 2011/10/15 06:14:09
    #10
    dan1138
    Super Member
    • Total Posts : 2497
    • Reward points : 0
    • Status: offline
    Re:Frequency Counter 2011/10/15 19:26:36 (permalink)
    0
    The code as posted builds for a common anode type LED display.
     
    As a first PIC project this may require too much PIC specific knowledge and will likely be frustrating.
     
    If your short term goal is to build a functioning frequency counter from a kit of parts then by all means avoid this project and buy what you want from the links you posted.
     
    On the other hand should you wish to lean some tricky things about programming for embedded controllers with limited resources then this is just the kind of project for you.
     
    There are other Microchip parts that would be better suited than the PIC16F84 to make a frequency counter with an LED display.
     
    After look at the code this particular method of using a PIC for a frequency counter is kind of tricky.
     
    Some of the things that will be a problem for you are:
     
    * - The correct setting for the PIC16F84 configuration word is not mentioned.
    A configuration word select the type of oscillator the PIC will be using, if the watch dog timer is used, if the code is protected from being read after programming and if a wait after power on is needed.
     
    * - The oscillator frequency for the default build is not specified.
    This looks like it could be 9 MHz but other parts of the code hint that it may be 4 MHz. This is something you will need to determine on your own.
     
    * - The source code style is hard for me to follow.
    After only a quick look the comments in some parts are clear while other parts are so terse that I cannot easily see the meaning.
     
    * - The frequency counter gate interval is set by the code executing a specific number of instruction cycles.
    This is the kind of thing done in a lot of embedded project. It's not a good thing or a bad thing but is does lead to creating code that can only be used for one very specific project. After you get more experience you will learn that your single most valuable resource is your time. If you can write correct code that can be used in many application you can get maximum value for your time.
    #11
    atferrari
    Super Member
    • Total Posts : 1379
    • Reward points : 0
    • Joined: 2004/07/08 13:09:24
    • Location: Buenos Aires - Argentina
    • Status: offline
    Re:Frequency Counter 2011/10/16 03:54:49 (permalink)
    0
    fdan00
    if you want, I can share with you my frequency meter code.

     
    Hola fdan00,
     
    Is it possible that you show the whole design (circuit and code)?. Any link to a page? I will appreciate that.
    sad I am affraid I just know Assembler.
     
     

    Agustín Tomás

    In theory, there is no difference between theory and practice. In practice, however, there is.

    http://cablemodem.fibertel.com.ar/atferrari/
    #12
    peterpan73
    New Member
    • Total Posts : 9
    • Reward points : 0
    • Joined: 2011/10/13 18:23:14
    • Location: 0
    • Status: offline
    Re:Frequency Counter 2011/10/16 06:55:09 (permalink)
    0
    @ dan1138 Thanks again Dan. Now that you have clarified as hex code working for a 7 digit common anode display with the 16F84A, I will begin to burn it in and solder things together. On another note, I would like to know whether a hex burned into a 16F628A with code originally meant for the 16F84A, will work, like for this LED freq counter for instance? I am also searching the net for LMX2322 based freq counters and prescalers using common PICs such as the 16F628A. If you are interested in coding for a LMX2322 application please let me know, so I can send you some free LMX2322 to work on. Thanks a ton again.
    #13
    rmteo
    Super Member
    • Total Posts : 1006
    • Reward points : 0
    • Joined: 2007/05/02 20:33:25
    • Location: Colorado, USA
    • Status: offline
    Re:Frequency Counter 2011/10/16 13:43:59 (permalink)
    0
    I did this 2 Channel, 50Mhz Frequency Counter, PIC24FJ in those distant days when I was using BASIC and PICs.
          program FREQCNT2
    include "DSPIC_aditional_string_library"

    dim F_out1, F_out2 as dWord
        data_available as boolean
        lcd_txt as string[16]

    sub procedure Timer1Int org $1A ' interrupt at 1s
      IFS0 = IFS0 and $FFF7     ' Clear TMR1IF
      T2CON.15 = 0              ' Stop Timer2/3
      W10 = TMR2                ' Save Timer2/3
      W11 = TMR3HLD
      TMR3HLD = 0               ' Clear Timer2/3
      TMR2 = 0
      T2CON.15 = 1              ' Start Timer2/3
      F_out1 = (W11 << 16) or W10
      F_out1 = F_out1 << 5
      T4CON.15 = 0              ' Stop Timer4/5
      W10 = TMR4                ' Save Timer4/5
      W11 = TMR5HLD
      TMR5HLD = 0               ' Clear Timer4/5
      TMR4 = 0
      T4CON.15 = 1              ' Start Timer4/5
      F_out2 = (W11 << 16) or W10
      F_out2 = F_out2 << 5
      data_available = True
    end sub

    main:
      AD1PCFG = 0xFFFF
      RPINR3 = 8            ' Channel 1 input on RP8
      RPINR4 = 9            ' Channel 2 input on RP9
      data_available = False
      T2CON = $000A ' 32 bit Timer2/3 , External clock from pin T2CK (on the rising edge) , prescaler 1as1
      TMR3 = 0
      TMR2 = 0
      T4CON = $000A ' 32 bit Timer4/5 , External clock from pin T4CK (on the rising edge) , prescaler 1as1
      TMR4 = 0
      TMR5 = 0
      T1CON = $0010           ' Timer1 ON, internal clock FCY, prescaler 1 as 64
      TMR1 = 0
      PR1 = 62500             ' interrupt at 0.25sec
      IPC0  = IPC0 or  $1000  ' Interrupt priority level = 1
      IFS0  = IFS0 and $FFF7  ' Clear TMR1IF
      IEC0  = IEC0 or  $0008  ' Enable Timer1 interrupts
      T1CON.15 = 1            ' Start Timer1
      T2CON.15 = 1            ' Start Timer2
      T4CON.15 = 1            ' Start Timer4

      Lcd_Init(PORTB, 7,6,5,4, PORTB, 2,1,3)
      Lcd_Cmd(LCD_CURSOR_OFF)
      Lcd_Cmd(LCD_CLEAR)
      while true
        if data_available then
          data_available = False
          LongWord2StrWithZeros(F_out1,lcd_txt)
          lcd_txt[0] = "1"
          lcd_txt[1] = ":"
          Str_Cat(lcd_txt," Hz")
          Lcd_Out(1,1,lcd_txt)  ' Display Channel 1
          LongWord2StrWithZeros(F_out2,lcd_txt)
          lcd_txt[0] = "2"
          lcd_txt[1] = ":"
          Str_Cat(lcd_txt," Hz")
          Lcd_Out(2,1,lcd_txt)  ' Display Channel 2
        end if
      wend
    end.

    Attached Image(s)


    Why pay for overpriced toys when you can have
    professional grade tools for FREE!!! mr greenmr green
    #14
    rmteo
    Super Member
    • Total Posts : 1006
    • Reward points : 0
    • Joined: 2007/05/02 20:33:25
    • Location: Colorado, USA
    • Status: offline
    Re:Frequency Counter 2011/10/16 15:58:54 (permalink)
    0
    This will make it easier to read.
          #include <htc.h> 
    //#include <regx51.h>
    //#include <iccioavr.h>
    //#include <avr/io.h>
    //#include <macros.h>
    //#include <stdio.h> //we use printf
    #include <string.h> //we use strcpy()
    //#include <math.h> //we use math functions for the inductance meter
    #include "gpio.h"
    #include "delay.h"
    //#include "spi_sw.h"
    #include "lcd_4bit.h" //we use lcd_4bit
    #include "misc.h" //we use ultoa

    //default configuration bits for 16F886
    __CONFIG(BORDIS & MCLRDIS & PWRTDIS & WDTDIS & HS & LVPDIS);
    __CONFIG(IESODIS & FCMDIS & DEBUGDIS & BORV21);

    //default configuration bits for 16F684
    //__CONFIG(MCLRDIS & BORDIS & WDTDIS & PWRTEN & INTIO);

    //hardware configuration
    #define PULSE_PORT PORTC //PULSE on pc0
    #define PULSE_DDR TRISC
    #define PULSE (1<<0)
    #define FREQ_HIGH 1000000ul //high frequency above which switch to a prescaler (good for at least 20Mhz)
    #define T1PS_LOW T1PS_1x //use t1ps_1x prescaler if frequencies < freq_high
    #define T1PS_HIGH T1PS_8x //use 1:8x prescaler for frequencies > FREQ_HIGH

    //#define LCD_DISPLAY_DLY 500 //lcd display delay, in ms

    //#define OUT_PORT PORTB //out_port on portb
    //#define OUT_DDR TRISB
    //#define OUT_PINs 0xff //out_pin on P2
    //#define OUT(val) OUT_PORT = (val) //output val on OUT_PORT
    #define MSB(word_t) ((word_t) >> 8) //msb of a word
    #define LSB(word_t) ((word_t) & 0x00ff) //lsb of a word
    //end hardware configuration

    #define TMR0IE T0IE //for compatibility
    #define TMR0IF T0IF

    //#define TMR_CS_EXT 1 //tmr source to be external pins
    //#define TMR_CS_INT 0 //tmr source to be internal (=Fcpu=Fosc/4)

    #define T1PS_1x 0x00 //tmr1 prescaler, 0b00
    #define T1PS_2x 0x01 //tmr1 prescaler, 0b01
    #define T1PS_4x 0x02 //tmr1 prescaler, 0b10
    #define T1PS_8x 0x03 //tmr1 prescaler, 0b11

    const unsigned char str0[]="16F886 FreqMeter"; //sign-on
    const unsigned char str1[]="----  v2.0  ----"; //prompt
    //const unsigned char str2[]="ps=            x"; //for prescaler
    const unsigned char str2[]="f=            Hz";
    //const unsigned char str_F[]="F =           Hz";
    //const unsigned char str_l[]="l =           uh"; //for inductance meter
    //const unsigned char str_L[]="L =           uh";

    bank1 unsigned char vRAM[17]; //display buffer
    //unsigned long freq_prev=0;
    volatile unsigned long freq; //frequency counter, 32-bit
    //tmr0 related variables
    //volatile unsigned char tmr0_flag; //1 -> tmr0_ticks_max has not elapsed. 0 = otherwise
    volatile unsigned long timebase_ticks; //how many times has timer0 elapsed
    //unsigned char sTMR1H, sTMR1L;


    //for inductance meter - not used
    #define L_CALIB 330 //inductance used for calibration, in uh
    #define F_CALIB 824500 //frequency generated by the calibration inductor, in hz
    //#define pi() 3.1415926 //pi
    //#define L_CALIB_C (pow(1.0/(2.0*pi()*L_CALIB_F), 2) / L_CALIB_L * 1e18) //estimated c1//c2, in pf
    #define F2L_00uh(freq) (pow(1.0*F_CALIB / freq, 2) * L_CALIB) //estimated L, in 0.01uh

    #define TIMEBASE 1000000ul //how many ticks before time is up. 1tick=1us
    #define TIMEBASE_PR 250 //how many offsets for tmr0 -> 200us per tmr0_isr
    #define TMR0_ERROR 0 //to account for the ticks elapsed when tmr0 is being updated for its offset
    //#define F_ERROR 168 //frequency errors due to various latencies
    //#define F_ERROR_AT_FREQ 8000000ul //frequency at which the error took place

    void interrupt isr(void) {
    if (TMR2IE && TMR2IF) { //tmr2 isr has taken place
    //sTMR1L = TMR1L, sTMR1H = TMR1H; //save tmr1h/l
    TMR2IF=0; //clear tmr0 interrupt flag
    //TMR0+=-TMR0_OFFSET+TMR0_ERROR; //load up the offset
    timebase_ticks+=TIMEBASE_PR+TMR0_ERROR; //update tmr0_ticks;
    if (timebase_ticks >= TIMEBASE * (F_CPU / 1000000ul)) {
    TMR1ON=0; //turn off tmr1
    TMR2ON = 0; //stop tmr2
    //TMR0ON=0; //turn off tmr0
    //tmr0_flag=0; //clear tmr0_flag
    //tmr0_flag=(tmr0_ticks < TMR0_TICKS_MAX);
    //IO_FLP(OUT_PORT, (1<<0)); //indicator for debugging purposes
    }
    return;
    }

    if (TMR1IE && TMR1IF) { //tmr1 isr has taken place
    TMR1IF=0; //clear tmr1 interrupt flag
    freq+=0x10000ul; //update freq, 16-bit overflow
    return;
    }
    }


    //initialize the time base
    void tmr2_init(void) { //tmr0 as the timer
    //tmr0_flag=1; //reset tmr0_flag
    timebase_ticks=0; //reset tmr0_ticks;

    //set up tmr2
    TMR2ON = 0; //turn off tmr2
    //T0CS=0; //tmr0 source: fcpu=fosc/4 -> 1Mhz
    //PSA=1; //prescaler assignment: to wdt
    //PS2=0, PS1=0, PS0=0; //prescaler: 1:1
    TMR2=0x00; //reset tmr2

    //set up the auto reloader
    PR2 = TIMEBASE_PR-1; //auto reload

    //set up the interrupt
    TMR2IF = 0; //clear tmr2if
    TMR2IE=1; //enable tmr1 interrupt
    //TMR0 = -TMR0_OFFSET; //set tmr0 offset
    }

    //initialize the pulse counter
    void tmr1_init(unsigned char t1ps) { //tmr1 as the pulse counter
    IO_IN(PULSE_DDR, PULSE); //t0cki as input

    //set the counter
    freq=0; //reset frequency

    //set up tmr1
    TMR1ON=0; //keep tmr1 off
    TMR1H=0, TMR1L=0; //reset tmr1 counters
    TMR1GE=0; //tmr1 not gated
    T1SYNC=1; //counter asyncronoous
    //T1CKPS1=t1ps >> 1; //tmr1 prescaler: 0b00 -> 1:1
    //T1CKPS0=t1ps & 0x01;
    switch (t1ps) {
    case T1PS_1x: T1CKPS1=0, T1CKPS0=0; break; //1x
    case T1PS_2x: T1CKPS1=0, T1CKPS0=1; break; //2x
    case T1PS_4x: T1CKPS1=1, T1CKPS0=0; break; //4x
    case T1PS_8x: T1CKPS1=1, T1CKPS0=1; break; //8x
    };
    TMR1CS=1; //tmr1 source: PULSE

    //set up the interrupt
    TMR1IF=0; //clear tmr1if
    TMR1IE=1; //tmr1 interrupt enabled
    PEIE=1; //peripheral interrupt enabled
    }

    unsigned long freq_meter(unsigned char t1ps) {
    //unsigned char tmp_h, tmp_l;

    tmr1_init(t1ps); //reset tmr1 to be a counter on external pulse train
    tmr2_init(); //reset tmr0 to be a timer on internal clock
    ei(); //enable interrupt
    TMR2ON=1, TMR1ON=1; //turn on tmr1
    while (TMR1ON) continue; //wait for the desired time to elapse
    //TMR1ON=0; //turn off tmr1 - done in the isr
    di(); //disable interrupt
    //freq |= ((unsigned short) TMR1H << 8) | TMR1L;
    //freq += (sTMR1H << 8) | sTMR1L;
    freq |= ((unsigned short) TMR1H << 8) | TMR1L;
    switch (t1ps) {
    case T1PS_1x: freq = freq << 0; break; //1x
    case T1PS_2x: freq = freq << 1; break; //2x
    case T1PS_4x: freq = freq << 2; break; //4x
    case T1PS_8x: freq = freq << 3; break; //8x
    };
    //correct timing error:
    //timing error is proportional to current frequency and latency (inverse of cpu frequency)
    //freq -= F_ERROR * freq / F_ERROR_AT_FREQ * (F_ERROR_AT_FREQ / 4) / F_CPU;
    return freq;
    }

    void mcu_init(void) {
    ANSEL = 0x00; //porta are digital io
    ANSELH = 0x00; //all portB is digital io
    //IRCF2=1, IRCF1=1, IRCF0=1; //0b111=running at 8Mhz

    //IO_CLR(OUT_PORT, OUT_PINs); //clear out_pins
    //IO_OUT(OUT_DDR, OUT_PINs); //out_pins as output
    }

    unsigned long tmp=0;

    int main(void) {
    //double c12=L_CALIB_C;


    mcu_init(); //reset the mcu
    //spi_init(); //initiate the spi module
    lcd_init(); //initiate the lcd module

    //check to see if clock has failed
    //strcpy(vRAM, "HS clk failed");
    while (OSFIF) { //external clock has failed
    strcpy(vRAM, "HS clk failed");
    lcd_display(LCD_Line0, vRAM);
    break;//while (1); //wait forever
    }

    di(); //disable interrupt
    //sprintf(vRAM, "%s", str0); //form vRAM
    strcpy(vRAM, str0);
    lcd_display(LCD_Line0, vRAM); //display vRAM

    //strcpy(vRAM, str1);
    //lcd_display(LCD_Line1, vRAM); //display the 2nd string

    while(1) {
    //frequency meter
    //show the prescaler - for information purposes
    //strcpy(vRAM, str_f); ultoa(&vRAM[1], 1<<t1ps, 1);

    //sprintf(vRAM, "f=%12uHz", freq); //form vRAM
    strcpy(vRAM, str2); 
    ultoa_s(&vRAM[2], tmp, 12); //form vRAM
    lcd_display(LCD_Line1, vRAM); //display vRAM
    //end frequency meter

    //inductance meter
    //strcpy(vRAM, str_L); ultoa(&vRAM[0], 1<<t1ps, 1);
    //ultoa_2(&vRAM[3], (unsigned long) (F2L_00uh(tmp)*100.0), 10); //form vRAM
    //display vRAM
    //lcd_display(LCD_Line1, vRAM); //display vRAM

    tmp=freq_meter(T1PS_HIGH); //use 8x prescaler most of the time
    if (tmp <= FREQ_HIGH) tmp=freq_meter(T1PS_LOW); //if frequency is too low, switch to low prescaler


    }
    return 0;
    }


    Why pay for overpriced toys when you can have
    professional grade tools for FREE!!! mr greenmr green
    #15
    peterpan73
    New Member
    • Total Posts : 9
    • Reward points : 0
    • Joined: 2011/10/13 18:23:14
    • Location: 0
    • Status: offline
    Re:Frequency Counter 2011/10/16 17:22:49 (permalink)
    0
    @ fdan and rmteo. Good work there. 2 channel is cool. What PIC is this?
    #16
    rmteo
    Super Member
    • Total Posts : 1006
    • Reward points : 0
    • Joined: 2007/05/02 20:33:25
    • Location: Colorado, USA
    • Status: offline
    Re:Frequency Counter 2011/10/16 17:34:50 (permalink)
    0
    I used a PIC24FJ32GA002 for the 2-channel one.
     

    Why pay for overpriced toys when you can have
    professional grade tools for FREE!!! mr greenmr green
    #17
    rmteo
    Super Member
    • Total Posts : 1006
    • Reward points : 0
    • Joined: 2007/05/02 20:33:25
    • Location: Colorado, USA
    • Status: offline
    Re:Frequency Counter 2011/10/16 18:32:46 (permalink)
    0
    fdan00
    ...the 24F chip has two (asynchronous) counters and that's a big advantage over the 16f886.

    The timers on the 8-bit PICs are a mess with some being 8-bit and some 16-bit with separate IC/OC/PWM and things like 10-bit duty cycle and 8-bit period registers.  The PIC24/dsPIC33 (and PIC32) are better but still have IC/OC/PWM as separate modules. 
     
    Having a general purpose 16-bit timer with these features would make life so much easier (especially the bolded features):
    ● 16-bit up, down, up/down auto-reload counter.
    ● 16-bit programmable prescaler used to divide the counter clock frequency by any factor between 1 and 65535.
    4 independent channels that can be used for:
    – Input capture
    – Output compare
    – PWM generation (Edge- and Center-aligned modes)
    – One-pulse mode output
    ● Synchronization circuit to control the timer with external signals and to interconnect several timers.
    ● Interrupt and/or DMA generation on the following events:
    – Update: counter overflow/underflow, counter initialization (by software or internal/external trigger)
    – Trigger event (counter start, stop, initialization or count by internal/external trigger)
    – Input capture
    – Output compare
    post edited by rmteo - 2011/10/16 18:36:04

    Attached Image(s)


    Why pay for overpriced toys when you can have
    professional grade tools for FREE!!! mr greenmr green
    #18
    peterpan73
    New Member
    • Total Posts : 9
    • Reward points : 0
    • Joined: 2011/10/13 18:23:14
    • Location: 0
    • Status: offline
    Re:Frequency Counter 2011/10/16 20:33:14 (permalink)
    0
    @ dan1138 A google search today turned up with this code here http://www.qsl.net/om3cph/counter/led/led8digt.txt Looks like the original author Peter Halicky already had an 8 digit LED counter. I tried to build it as is in MPLAB and got this instead:-
     
    Release build of project `E:\Must do projects PCB negatives and PIC Project hex files for current projects\8 digit LED frequency counter using PIC16F628A\led8digt counter from same author.disposable_mcp' started.
    Language tool versions: MPASMWIN.exe v5.42, mplink.exe v4.40, mplib.exe v4.40
    Mon Oct 17 09:00:36 2011
    ----------------------------------------------------------------------
    Clean: Deleting intermediary and output files.
    Clean: Done.
    Executing: "C:\Program Files\Microchip\MPASM Suite\MPASMWIN.exe" /q /p16F84A "led8digt counter from same author.asm" /l"led8digt counter from same author.lst" /e"led8digt counter from same author.err"
    Error[105]   E:\MUST DO PROJECTS PCB NEGATIVES AND PIC PROJECT HEX FILES FOR CURRENT PROJECTS\8 DIGIT LED FREQUENCY COUNTER USING PIC16F628A\LED8DIGT COUNTER FROM SAME AUTHOR.ASM 93 : Cannot open file (Include File "t1234led.inc" not found)
    Error[113]   E:\MUST DO PROJECTS PCB NEGATIVES AND PIC PROJECT HEX FILES FOR CURRENT PROJECTS\8 DIGIT LED FREQUENCY COUNTER USING PIC16F628A\LED8DIGT COUNTER FROM SAME AUTHOR.ASM 344 : Symbol not previously defined (STATUS)
    Error[113]   E:\MUST DO PROJECTS PCB NEGATIVES AND PIC PROJECT HEX FILES FOR CURRENT PROJECTS\8 DIGIT LED FREQUENCY COUNTER USING PIC16F628A\LED8DIGT COUNTER FROM SAME AUTHOR.ASM 346 : Symbol not previously defined (TRISB)
    Error[113]   E:\MUST DO PROJECTS PCB NEGATIVES AND PIC PROJECT HEX FILES FOR CURRENT PROJECTS\8 DIGIT LED FREQUENCY COUNTER USING PIC16F628A\LED8DIGT COUNTER FROM SAME AUTHOR.ASM 347 : Symbol not previously defined (STATUS)
    Error[113]   E:\MUST DO PROJECTS PCB NEGATIVES AND PIC PROJECT HEX FILES FOR CURRENT PROJECTS\8 DIGIT LED FREQUENCY COUNTER USING PIC16F628A\LED8DIGT COUNTER FROM SAME AUTHOR.ASM 473 : Symbol not previously defined (T1)
    Error[113]   E:\MUST DO PROJECTS PCB NEGATIVES AND PIC PROJECT HEX FILES FOR CURRENT PROJECTS\8 DIGIT LED FREQUENCY COUNTER USING PIC16F628A\LED8DIGT COUNTER FROM SAME AUTHOR.ASM 496 : Symbol not previously defined (T2)
    Error[113]   E:\MUST DO PROJECTS PCB NEGATIVES AND PIC PROJECT HEX FILES FOR CURRENT PROJECTS\8 DIGIT LED FREQUENCY COUNTER USING PIC16F628A\LED8DIGT COUNTER FROM SAME AUTHOR.ASM 516 : Symbol not previously defined (T3)
    Error[105]   E:\MUST DO PROJECTS PCB NEGATIVES AND PIC PROJECT HEX FILES FOR CURRENT PROJECTS\8 DIGIT LED FREQUENCY COUNTER USING PIC16F628A\LED8DIGT COUNTER FROM SAME AUTHOR.ASM 523 : Cannot open file (Include File "z4led.inc" not found)
    Halting build on first failure as requested.
    ----------------------------------------------------------------------
    Release build of project `E:\Must do projects PCB negatives and PIC Project hex files for current projects\8 digit LED frequency counter using PIC16F628A\led8digt counter from same author.disposable_mcp' failed.
    Language tool versions: MPASMWIN.exe v5.42, mplink.exe v4.40, mplib.exe v4.40
    Mon Oct 17 09:00:39 2011
    ----------------------------------------------------------------------
    BUILD FAILED
     
    What I need is 16F84A hex for an 8 digit common anode version. Can you help me please??
     
     
     
     
    post edited by peterpan73 - 2011/10/16 20:43:39
    #19
    peterpan73
    New Member
    • Total Posts : 9
    • Reward points : 0
    • Joined: 2011/10/13 18:23:14
    • Location: 0
    • Status: offline
    Re:Frequency Counter 2011/10/16 21:03:08 (permalink)
    0
    Has anyone here coded for a 2.5Ghz freq.counter/prescaler/DDS function generator project using the LMX2322??
    #20
    Page: 12 > Showing page 1 of 2
    Jump to:
    © 2017 APG vNext Commercial Version 4.5