Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

Help to develop software for freq. counter

Status
Not open for further replies.

blinkstar88

New Member
Dear All,

i got this freq counter from internet and i want to developed my own software. The schematic is attach and the url is https://hem.passagen.se/communication/fcntlcd.html

This f counter used pll ic from national (lmx2346) and capable to measure freq up to 2.5 Ghz. This ic used to divided freq input by 64 and programmed by spi interface by microcontroller. The freq input will change the charge pump, its ttl leveler. This charge pump (Cpo) will directly connected to microcontroller and measured the freq by microcontroller.

I got no problem to interface lcd, and programmed pll ic with this microcontroller.

The problem is i don't know how to start to measure the freq was converted to charge and connected to RC0 of microcontroller.

Any idea will aprreciated.

Thanks
 

Attachments

  • fcntrs232.gif
    fcntrs232.gif
    19 KB · Views: 1,408
Your post is confusing. The webpage and your GIF image indicate a LMX2322 is being used. If this is the case, then:

First you need to get the datasheet of the LMX2322 here:
**broken link removed**

Look carefully at the wording on page 9 section 2.2.2 of the datasheet, which I quoted below:

If test mode is ACTIVATED (R[14]=1), the outputs of the N and R counters are directed to the CPo output to
allow for testing. The PD_POL bit selects which counter output according to Table 2.2.3.

The charge pump output(CPo) of the LMX2322 is thus not used in the usual analogue way but the designer places the LMX2322 into test mode, so that the output of the N counter is available at this pin instead. By measuring frequency at this pin, one can obtaine the divided down input frequency.

*** If however, the LMX2346 chip is what you have on hand, then you can program the LMX2346 internal register control word so that the LD pin can be used to output the divided-down frequency signal of either the N or R counter.

Hope this helps.

Edited: added info on LMX2346
 
Last edited:
yes you right i want to develop using lmx2346 cause that's only i have on hand.
By the way thank you for the info, you've give me a light :) so i know where to start.

Here's my list that i want to do with the software:

1. Initialize lcd
2. Set the pll through microwire
- Program N Divider to 64
- Set LD Output Select (Register R 14:13) so N Divider will output to LD Pin
4. Measure freq on pin LD
5. Display freq on LCD with real Freq = freq x 64
6. Loop to routine 4 every 1 second
7. End

Is it right?
 
yes you right i want to develop using lmx2346 cause that's only i have on hand.
By the way thank you for the info, you've give me a light :) so i know where to start.

Here's my list that i want to do with the software:

1. Initialize lcd
2. Set the pll through microwire
- Program N Divider to 64
- Set LD Output Select (Register R 14:13) so N Divider will output to LD Pin
4. Measure freq on pin LD
5. Display freq on LCD with real Freq = freq x 64
6. Loop to routine 4 every 1 second
7. End

Is it right?
 
That sounds about right.

Don't forget to initialize the PIC timers too. You'll need them to provide a fixed time interval for frequency measurement.
 
eblc1388 said:
..................

First you need to get the datasheet of the LMX2322 here:
**broken link removed**

Look carefully at the wording on page 9 section 2.2.2 of the datasheet, which I quoted below:



The charge pump output(CPo) of the LMX2322 is thus not used in the usual analogue way but the designer places the LMX2322 into test mode, so that the output of the N counter is available at this pin instead. By measuring frequency at this pin, one can obtaine the divided down input frequency.

*** If however, the LMX2346 chip is what you have on hand, then you can program the LMX2346 internal register control word so that the LD pin can be used to output the divided-down frequency signal of either the N or R counter.

Hope this helps.

Edited: added info on LMX2346
Hi Eblc 1388,
Thanks for this rare datasheet- i have been searching for a lon time-- and then settled for LMX2306, thanks to National Semi for the samples they obliged.
 
eblc1388 said:
That sounds about right.

Don't forget to initialize the PIC timers too. You'll need them to provide a fixed time interval for frequency measurement.

Yeah you right, i will use TMR 1 to measure it, its the first thing i want to do. Trying to Search how to use it.

Thanks
 
Last edited:
There are lot's of existing PIC frequency counters out there, including a VERY old MicroChip application note (using an OTP PIC) - you might find it useful to check how those usually work?.
 
blinkstar88 said:
Dear All,

i got this freq counter from internet and i want to developed my own software. The schematic is attach and the url is https://hem.passagen.se/communication/fcntlcd.html

This f counter used pll ic from national (lmx2346) and capable to measure freq up to 2.5 Ghz. This ic used to divided freq input by 64 and programmed by spi interface by microcontroller. The freq input will change the charge pump, its ttl leveler. This charge pump (Cpo) will directly connected to microcontroller and measured the freq by microcontroller.

I got no problem to interface lcd, and programmed pll ic with this microcontroller.

The problem is i don't know how to start to measure the freq was converted to charge and connected to RC0 of microcontroller.

Any idea will aprreciated.

Thanks

The same site gives a software for LED version and it is only a mod to drive LCD instead of Muxed LEDs. Hope this helps
https://hem.passagen.se/communication/software.html

You may otherwise request the original desiner who can offer a preprogrammed chip
 
I want make same freq. meter. But i never work with PLL and microcontrollers before.

I have a question about lmx2322:

In datasheet we have:
Preset modulus of dual modulus prescaler (P=32)
The B value (NB_CNTR) must be > 3
N = (P x B) + A
N = (32 x 3)+0 = 96 -> i think it's a minimum value for N Divider.
Could you please explain how to "Program N Divider to 64"?

Thank you.
 
Last edited:
Hi!
I am also interested in this project, and therefore made some investigations.
After disassembling the HEX file, (not the exclusive version) here is what I have found out.
For the 18bit word 3 bytes are used: mem_56, mem_55, mem_54 (MSB-LSB)
Sub_100 makes the actual sending of the data.
mem_57 is the counter used for rotating the 3 bytes. As You can see, first the MSB (mem_56) is processed (the counter is loaded with 2), by checking bit 1, rotating to left and so on. Next the middle byte (counter=8) and the finally the lower byte.

Code:
sub_100
;
; called from: 0138
; called from: 013F
; called from: 0147
; called from: 01D8
; called from: 01DF
        bcf             PORTC, 1    ; 0100: 1087
        bcf             PORTC, 3    ; 0101: 1187
        movlw           0x02        ; 0102: 3002
        movwf           mem_57      ; 0103: 00D7

loop_104
; jump here from: 010F
        bcf             PORTC, 1    ; 0104: 1087
        btfss           mem_56, 1   ; 0105: 1CD6
        goto            label_109   ; 0106: 2909

        bsf             PORTC, 2    ; 0107: 1507
        goto            label_10a   ; 0108: 290A

label_109
; jump here from: 0106
        bcf             PORTC, 2    ; 0109: 1107

label_10a
; jump here from: 0108
        call            sub_12f     ; 010A: 212F

        rlf             mem_56, f   ; 010B: 0DD6
        bsf             PORTC, 1    ; 010C: 1487
        call            sub_12f     ; 010D: 212F

        decfsz          mem_57, f   ; 010E: 0BD7
        goto            loop_104    ; 010F: 2904

        movlw           0x08        ; 0110: 3008
        movwf           mem_57      ; 0111: 00D7

loop_112
; jump here from: 011D
        bcf             PORTC, 1    ; 0112: 1087
        btfss           mem_55, 7   ; 0113: 1FD5
        goto            label_117   ; 0114: 2917

        bsf             PORTC, 2    ; 0115: 1507
        goto            label_118   ; 0116: 2918

label_117
; jump here from: 0114
        bcf             PORTC, 2    ; 0117: 1107

label_118
; jump here from: 0116
        call            sub_12f     ; 0118: 212F

        rlf             mem_55, f   ; 0119: 0DD5
        bsf             PORTC, 1    ; 011A: 1487
        call            sub_12f     ; 011B: 212F

        decfsz          mem_57, f   ; 011C: 0BD7
        goto            loop_112    ; 011D: 2912

        movlw           0x08        ; 011E: 3008
        movwf           mem_57      ; 011F: 00D7

loop_120
; jump here from: 012B
        bcf             PORTC, 1    ; 0120: 1087
        btfss           mem_54, 7   ; 0121: 1FD4
        goto            label_125   ; 0122: 2925

        bsf             PORTC, 2    ; 0123: 1507
        goto            label_126   ; 0124: 2926

label_125
; jump here from: 0122
        bcf             PORTC, 2    ; 0125: 1107

label_126
; jump here from: 0124
        call            sub_12f     ; 0126: 212F

        rlf             mem_54, f   ; 0127: 0DD4
        bsf             PORTC, 1    ; 0128: 1487
        call            sub_12f     ; 0129: 212F

        decfsz          mem_57, f   ; 012A: 0BD7
        goto            loop_120    ; 012B: 2920

        bsf             PORTC, 3    ; 012C: 1587
        call            sub_12f     ; 012D: 212F

        return                      ; 012E: 0008
;

And here you find the register contents: (00, 58, 05 and 00, 02, 00)

Code:
        movlw           0x00        ; 01D2: 3000
        movwf           mem_56      ; 01D3: 00D6
        movlw           0x58        ; 01D4: 3058
        movwf           mem_55      ; 01D5: 00D5
        movlw           0x05        ; 01D6: 3005
        movwf           mem_54      ; 01D7: 00D4
        call            sub_100     ; 01D8: 2100

        movlw           0x00        ; 01D9: 3000
        movwf           mem_56      ; 01DA: 00D6
        movlw           0x02        ; 01DB: 3002
        movwf           mem_55      ; 01DC: 00D5
        movlw           0x00        ; 01DD: 3000
        movwf           mem_54      ; 01DE: 00D4
        call            sub_100     ; 01DF: 2100

First it puts the chip in TEST mode with N divider as output, then sets the B counter to 2, and A counter to 0.
Altough the datasheet stetes several times, that the minimum value for B is 3, it seems to work.
NOTES: Divide ratio: 3 to 1,023(Divide ratios less than 3 are prohibited)

I also find 3 more writes to the chip with really strange values,(0,0,A2; 0,0E,B8; 0,A3,09) and as far as i can tell, there is no way for the program to even jump there??? (maybe dummy stuff, or disassembler error? however tried with 2 different disassemblers)
(look after "return ; 0131: 0008")

Code:
sub_12f
;
; called from: 010A
; called from: 010D
; called from: 0118
; called from: 011B
; called from: 0126
; called from: 0129
; called from: 012D
        movlw           0x80        ; 012F: 3080
        call            sub_023     ; 0130: 2023

        return                      ; 0131: 0008
;
; end of sub_12f
;------------------------------------------------------------

        movlw           0xa2        ; 0132: 30A2
        movwf           mem_54      ; 0133: 00D4
        movlw           0x00        ; 0134: 3000
        movwf           mem_55      ; 0135: 00D5
        movlw           0x00        ; 0136: 3000
        movwf           mem_56      ; 0137: 00D6
        call            sub_100     ; 0138: 2100

        movlw           0xb8        ; 0139: 30B8
        movwf           mem_54      ; 013A: 00D4
        movlw           0x0e        ; 013B: 300E
        movwf           mem_55      ; 013C: 00D5
        movlw           0x00        ; 013D: 3000
        movwf           mem_56      ; 013E: 00D6
        call            sub_100     ; 013F: 2100

        call            sub_34e     ; 0140: 234E

        movlw           0x09        ; 0141: 3009
        movwf           mem_54      ; 0142: 00D4
        movlw           0xa3        ; 0143: 30A3
        movwf           mem_55      ; 0144: 00D5
        movlw           0x00        ; 0145: 3000
        movwf           mem_56      ; 0146: 00D6
        call            sub_100     ; 0147: 2100

        return                      ; 0148: 0008
;
; end of sub_12f
 

Attachments

  • led_counter.zip
    9.3 KB · Views: 324
Last edited:
szabi i have extract config bits from two hex files(not exclusive hexes for lmx2322) :

UNF
000101100000000101
000001010000000000
to999
000101100000000101
000000001000000000
 
Hi!
The first divides by 640, the second is the same as I've found.
(Yesterday I made some sample requestst from National, LMX2346, these are free samples! Today I got a mail, that too many ppl are requesting this chip, and they need a shipping tax. :(
 
Last edited:
I have made some calculations on the Exclusive 2.5GHz frequency counter.
https://hem.passagen.se/communication/fcntlcd.html
From the author's explanations there are 2 different measuring resolutions, 1KHz with 512ms gate, and 100Hz with 1280ms gate times.
If my calculations are correct, using a 10MHz oscillator, the maximum measurable frequencys are 1,28GHz with 1KHz res (512ms gate), and 320MHz with 100Hz res (1280ms gate). only!
512prescaler/0.512s=1000Hz and 512prescaler*(10MHz/4)=1.28GHz
128prescaler/1.28s=100Hz and 128prescaler*(10MHz/4)=320MHz
 
Perfect calculations!
I have write some code on C(ccs compiler) but i have some problem with precision in simulator (proteus). In simulator i don't use pll. I'm try to calculate freq from 30Mhz oscillator.

The sample of code:
#use delay(clock=20000000)
int k;
int l;
int u_cnt;
int1 i;
long long result;
#INT_RTCC
void TIMER_INTERRUPT ( void )
{
set_timer0 (0);
l++;
}


void main()
{

SET_TRIS_A(0x18);
disable_interrupts ( GLOBAL );
setup_timer_0(RTCC_EXT_L_TO_H | RTCC_DIV_256);
enable_interrupts ( GLOBAL );
enable_interrupts (INT_RTCC);
set_timer0 (0);
delay_ms(100);
k = get_timer0();
output_low(PIN_A3);
k = get_timer0();
u_cnt = 0;
i = 0;
while (i == 0)
{
output_high(PIN_A3);
output_low(PIN_A3);
if (get_timer0() > k)
i = 1;
else
u_cnt++;
}
u_cnt = 0x100 - u_cnt;
u_cnt = ~ u_cnt;
u_cnt++;
result = (l*0x10000+k*0x100+u_cnt)*0xA;
result= result; //the result = +-8kHz :(
}
 
Last edited:
OK, the calculations are right, but I did not took into consideration that the TIMER1 in asynchronous counter mode (without prescaler) can handle signals up to ~16,6MHz (60ns period)
You should also use TIMER1 instead of TIMER0!
 
I'm using Timer0 on pic16F876 for freq counting (PIN_A4). I have config Timer0 to External clock mode (RTCC_EXT_L_TO_H) and enable iternal prescaler (/256). After 256*256 = 65536 clocks i have INTERRUPT...
Also i directly connect PIN_A3 to PIN_A4. After delay i sent level 0 to pin A3 for stop timer0.
This scheme work fine and can count freq up to 50Mhz, i will try use you calculation with 10Mhz oscilator. Also i will try use timer 1 in asynchronous counter mode.
Thank you for advise.
 
The author in his 2.5GHz counter doesn't use the Timer1 interrupt for measurement. He creates a 64ms delay loop, within he checks the TMR1IF flag, and increments a 1 byte counter. At the end, he copies the timer1 into 2 more registers, giving a 24bit (3byte) result.
The only interrupt used is the timer0 for display update, if I'm right.
Here: https://www.sprut.de/electronic/pic/projekte/frequenz/freq_uni_628.htm
you find another good frequency counter 2Hz-1GHz with source code. It has a nice autoranging feature, so it self adjusts the prescaler ratio (and thus the precision) with incoming frequency. I have found a U813BS 1.1GHz prescaler from an old TV's tuner. You could use the LMX2322 instead, and change to a higher pin-count processor to be able to program it.
By setting a too high prescaler (ex 256), the problem is, that you will get a minimum of 256Hz resolution. (1s gate time)
 
Last edited:
szabi, thank you again.
For precision count (resolution <256 Hz) I'm using a count up procedure.
After stoping of timer0 i send level 1 on PIN_A3 in cycle, while timer0 will increment.
The resolution in Hz = ~((256 - count of click on PIN_A3)+1).
For example - after stop we have 129 in timer 0
129*256 = 33024 Hz.
Then we use count up procedure... The value of timer0 will increment to 130 after 31 clicks.
256-31 = 225
~225 = 30
30+1 = 31 Hz.
Finally we have 33024+31 = 33055Hz

PS:
Sorry for my poor english.
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top