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.

problem in frequency counter using pic 16f877a

Status
Not open for further replies.

sayf alawneh

Junior Member level 3
Junior Member level 3
Joined
Aug 15, 2014
Messages
27
Helped
0
Reputation
0
Reaction score
0
Trophy points
1
Visit site
Activity points
256
guys i really need help my project is to make a frequency counter (frequency meter) can cout frequency up to 5Mhz using TMR1 or TMR0 i am lookig since 2 weeks in every where but still cant understand cause every body explain it different way than the other ,,,, i just need to know the maximum frequency i can count using both timers and whatt is the relation between the max frequency i can count and the crystal oscillator ?
also lot of guys told me to use TMR1 but why TMR1 and not TMR0 ??? i know TMR1 is 16 bit and TMR0 is 8 bits
for my project i used TMR1 and i really dont know why :(
as a test i used PWM from pic16f877a and sent the pWM pulse to T1CkI in another 16f877a
but the accuracy wasnt good !! for example a pwm of 15 k HZ was read 15252 HZ an error of 252 HZ ???
also i couldnt read more than 30Khz i couldnt get the needed range from 1 hz to 5Mhz !! also i need good accuracy is the problem in the code??? here is the counter code guys


Code dot - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D7 at RB0_bit;
sbit LCD_D6 at RB1_bit;
sbit LCD_D5 at RB2_bit;
sbit LCD_D4 at RB3_bit;sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D7_Direction at TRISB0_bit;
sbit LCD_D6_Direction at TRISB1_bit;
sbit LCD_D5_Direction at TRISB2_bit;
sbit LCD_D4_Direction at TRISB3_bit;
void main() {
int c=0,i=0,n=0;
char txt[5],txt1[5],*res;;
lcd_init();
lcd_cmd(_LCD_CLEAR);
lcd_cmd(_LCD_CURSOR_OFF);
TRISC=1;
TRISB=0;
TRISD=0;
PORTD= 0;
TMR1L=0;
TMR1H=0;
LCD_OUT(1,1,"WORKING..");
delay_ms(500);
lcd_out(1,1," WORKING.");
delay_ms(500);
lcd_out(1,1," WORKING ");
T1CON= 0B00000011;delay_ms(1000);
T1CON= 0B00000010;
c= TMR1L;
i= TMR1H * 256;
n= c+i;
IntToStr(n,txt);
lcd_cmd(_LCD_CLEAR);
delay_ms(100);
lcd_out(1,1," FREQUENCY IS");
delay_ms(100);lcd_out(2,0,txt);
lcd_out(2,7," Hz ");
}



and the PWm code is simple just to generate a pulse with 15Khz
guys am really a newbie please i need help i really need it please explain to me as a newbie
i only have 5 days to finish this project :(
 
Last edited by a moderator:

hi,
Look at this image, it suggests a external asynchronous 1imer clock period of 60nanosec, ~16MHz.

Use timer0 in conjunction with a timer0 interrupt clocked software counter to give a precise 1 second period for reading the Timer1 count.
Also use timer1 interrupt to clock a software counter, this will give a 24 bit value [ 8bit in software, 16 in timer1]

At the end of the 1 second period stop timer1, read timer1 and the timer1 interrupt counter.

Reset the timer 0 and timer1 counts to zero at the beginning each 1 second timer period.

E
 

Attachments

  • AAesp01.gif
    AAesp01.gif
    55 KB · Views: 147
hello,

You can count over 30MHz with timers ..

What is your FOSC Quartz = ?

What accuracy has your delay of 1seconde (delay_ms(1000); ?

you said PWM is 15Khz ? are you sure it is ?

To cover a large range of frequency , You must handle overlap of timer ( TMR0IF or TMR1IF) ,
count number of overlaping and add NbOverlap*65536 to the last reading.
If you use a prescaler , you also must add pulses to count residual pulse in prescaler...
 
Counter accuracy is limited by accuracy of time interval of reference clock scaled down from OSC, measured in PPM. 1 ppm external TCXO crystal clocks are cheap these days. Max frequency only limited by HW counters of chip.
 
frequency meter code problem

this code is for frequency meter project
crystal oscillator is 12 Mhz
the external pulse is a square one with 300 Khz frequency
the code is designed to measure 524 Khz with prescalar value 1:8
but it only measure up to 63Khz only do u know the reason guys ?
am really lost in timers since 2 weeks :(
her is the code

Code C - [expand]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
// LCD module connections
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;
sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;// End LCD module connections
char i;
unsigned short cnt;
unsigned int freq_result;
// Define Messages
 
char message1[ ] = "Freq Hz";
 
char *freq = "00000";
 
void Display_Freq(unsigned int freq2write) {
 
freq[0] = (freq2write/10000)%10 + 48; // extrct hundred thousnads digit
freq[1] = (freq2write/1000)%10 + 48; //extract thousands digit
freq[2] = (freq2write/100)%10 + 48; //extract hundreds digit
freq[3] = (freq2write/10)%10 + 48; // Extract tens digit
freq[4] = freq2write%10 + 48; // Extract ones digit
Lcd_Out(1, 6, freq); // Display Frequency on LCD
 
}
void main()
{
TRISB = 0;
PORTB = 0xFF;
TMR1H = 0x00; // Initialize Timer1 register
TMR1L = 0x00; // Initialize Timer1 register
T1CON = 0B00110011; // Timer1 on, external input RC0 and 1:8 scalling
TMR1IF_bit = 0; // clear TMR1IF
 
TRISC = 0xff; // all input
//////////////////////#LCD INITIALIZATION#////////////////////
Lcd_Init(); // Initialize LCD
Lcd_Cmd(_LCD_CLEAR); // Clear display
Lcd_Cmd(_LCD_CURSOR_OFF); // Cursor off
/////////////////////////////////////////////////////////////
Lcd_Out(1,1,message1); // Write message1 in 1st row
do {
 
TMR1H = 0; // reset high byte of timer 1 (takes effect when low byte written)
TMR1L = 0; // reset low byte of timer 1 (also loads in high byte now)
 
Delay_ms(1000); // Delay 0.1 Sec
 
freq_result = TMR1L; // get low byte of timer 1 count (and read high byte to buffer)
freq_result += TMR1H*256; // add in the high byte from buffer
freq_result*=8;
Display_Freq(freq_result); // show the result on LCD
 
} while(1); // Infinite loop

 
Last edited by a moderator:

Re: frequency meter code problem

hello,

524KHz=> 524000 pulses per seconde !
divide by 8 => 65500 pulses per seconde
so 65,5KHz

it seems not multiply by 8.. did you activate Math library ?
try to display Freq_result before multiply by 8.
and try also with

Code:
T1SYNC: Timer1 External Clock Input Synchronization Control bit
When TMR1CS = 1:
1 = Do not synchronize external clock input
 
hello,

I tested your programme on my Microchip IRDAboard 16F877
with Q=20Mhz
if i enter a TTL signal on RC0 25Khz
i get Freq= 25000 .. OK

tested OK , with output on LCD and UART.

Does your programme work correctly at this frequency ?
Is your signal correct (TTL level compliant at over 300Khz!)?
18:41:48.984> Freq= 24992
18:41:49.984> Freq= 24992
18:41:50.984> Freq= 24992
18:41:52.046> Freq= 25000
18:41:53.046> Freq= 24992
18:41:54.046> Freq= 25000
18:41:55.046> Freq= 24992
18:41:56.109> Freq= 24992
18:41:57.109> Freq= 25000
18:41:58.109> Freq= 24992
18:41:59.171> Freq= 25000

my 25KHz is comming from a Quartz 400KHz oscillator + CD4040 divider..

when i measure with
400Khz on RC0 ..i get a value of 6776 .
400000-5*65536=6784
like we get 5 overcount of timer1 ?

200Khz ...............................03384
200000-3*65536=3392
like 3 overtimer1 occured..



i printout the result before freqresult * by 8 ..measure it is correct!
i get 50000 for 400KHz

Probleme is on the size of Freq_result.. int 16bit ..up to 65535
need to use a long value to get over..

so 400Khz gives 400000 Hz

Code:
unsigned long LFreq;
...
Lfreq=(unsigned long) Freq_Result*8;
 
hello,

I tested your programme on my Microchip IRDAboard 16F877
with Q=20Mhz
if i enter a TTL signal on RC0 25Khz
i get Freq= 25000 .. OK

tested OK , with output on LCD and UART.

Does your programme work correctly at this frequency ?
Is your signal correct (TTL level compliant at over 300Khz!)?


my 25KHz is comming from a Quartz 400KHz oscillator + CD4040 divider..

when i measure with
400Khz on RC0 ..i get a value of 6776 .
400000-5*65536=6784
like we get 5 overcount of timer1 ?

200Khz ...............................03384
200000-3*65536=3392
like 3 overtimer1 occured..



i printout the result before freqresult * by 8 ..measure it is correct!
i get 50000 for 400KHz

Probleme is on the size of Freq_result.. int 16bit ..up to 65535
need to use a long value to get over..

so 400Khz gives 400000 Hz

Code:
unsigned long LFreq;
...
Lfreq=(unsigned long) Freq_Result*8;

ill try it and notify u with the result :)
 

Re: frequency meter code problem

hello,

524KHz=> 524000 pulses per seconde !
divide by 8 => 65500 pulses per seconde
so 65,5KHz

it seems not multiply by 8.. did you activate Math library ?
try to display Freq_result before multiply by 8.
and try also with

Code:
T1SYNC: Timer1 External Clock Input Synchronization Control bit
When TMR1CS = 1:
1 = Do not synchronize external clock input
man you are the best every thing worked perfect :D
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top