CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to support@ccsinfo.com

How Can i get +/- 0.1Hz Frequency Resolution

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
NEWBOY



Joined: 19 Dec 2003
Posts: 9

View user's profile Send private message

How Can i get +/- 0.1Hz Frequency Resolution
PostPosted: Fri Dec 19, 2003 7:42 am     Reply with quote

Hello Pic C gurus,
i want you to help me answer this question and help me with my present project.
i have a project that requi 0.1res me to measure the frequency (square wave) from a sensor to -/+Hz resolution
Would this be possible with the pic16f877 @ 20mhz?
i have just immigrated from PBP and i was able to get upto +/- 0.6Hz resolution using ccp capture
i did this by measuring the period then converting it to frequency but because of floating point numbers i have finally decided to break the bank and move up to using C.
But first of all i need some practise as rome wasn't built in a day so i have decided to convert the program i wrote in pbp to C but i am having real problems with the following

1) set capture for 16th falling edge
2) turn capture on/off

Could someone kindly help with those


jan Razz
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Fri Dec 19, 2003 8:47 am     Reply with quote

Look in the manual under setup_ccp1()

To turn off:
setup_ccp1(CCP_OFF);

For 16th edge and interrupt:
setup_ccp1(CCP_CAPTURE_DIV_16 | CCP_COMPARE_INT);
NEWBOY



Joined: 19 Dec 2003
Posts: 9

View user's profile Send private message

PostPosted: Fri Dec 19, 2003 1:27 pm     Reply with quote

Thank you for the pointer
i just got a bit confused with the manual but its all sinking in now
by the way would it be possible to get my 0.1 Hz resolution ?
if it is , how can this be acheived

jan
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Fri Dec 19, 2003 2:16 pm     Reply with quote

Depends on the frequency that you are measuring. The higher the frequency, the lower the resolution.
Guest








PostPosted: Fri Dec 19, 2003 5:01 pm     Reply with quote

Mark
The frequency would be in the range of 1Khz to 6Khz
i was thinking of using something like a frequency divider say of 10
which would then make the range 100hz to 600hz
Any ideas of a chip that does that of similar?

Jan
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Fri Dec 19, 2003 9:27 pm     Reply with quote

If you extend the CCP's value greater than 16 bits by counting timer1 overflows, you should be able to do what you want. You will have 2 interrupts, one for timer1 and the other for CCP1. In the timer1 int, just increment a global variable. This could be an 8 bit value which will become the high byte of the CCP value. When the CCP int occurs, the 2nd and 3rd bytes will be the CCP value. This will extend the value to 24 bits. You could make the timer1 variable 16bits which would give you a 32 bit CCP value. After you get the CCP value, be sure to reset the timer1 var to 0. Now if you are sure that the frequency will always be 1K-6KHz, you could probably work the divisors out so that you can actually ignore the timer1 var. That is, not even need it. But for now, I would try using the var.
Guest








PostPosted: Sat Dec 20, 2003 12:12 pm     Reply with quote

Mark
i found something similar but this is based on the frequency being sampled at 1 sec intervals
Due to my knowlegde in using C i got lost trying to reduce the sampled time of 1 sec intervals to 15ms as my signal would only be avaliable for
15ms at any time using delay_ms(15) doesn't seem to work is there another way.

jan
/////////////////////////////////////////////////////////////////////////
//// EX_FREQC.C ////
//// Counts the 'zero' crossings of an input signal for 1 second, ////
//// therefore counting the frequency of the signal. The input ////
//// signal's frequency is then displayed over the serial port. ////
//// ////
//// The 1s delay is created by generating a perfect 5,000,000 ////
//// cycles (it takes 0.2us for one cycle at 20Mhz). The trick is ////
//// that conditional statements have different values of cycles ////
//// depending on a TRUE or FALSE jump. ////
//// ////
//// The input signal is to be supplied to PIN C0 ////
//// ////
//// This example will work with the PCB and PCM compilers. The ////
//// following conditional compilation lines are used to include a ////
//// valid device for each compiler. Change the device and clock ////
//// for your hardware if needed. ////
/////////////////////////////////////////////////////////////////////////
//// (C) Copyright 1996,2001 Custom Computer Services ////
//// This source code may only be used by licensed users of the CCS ////
//// C compiler. This source code may only be distributed to other ////
//// licensed users of the CCS C compiler. No other use, ////
//// reproduction or distribution is permitted without written ////
//// permission. Derivative programs created using this software ////
//// in object code form are not restricted in any way. ////
/////////////////////////////////////////////////////////////////////////

#include <16f877.h>
#fuses HS,NOWDT
#use delay(clock=20000000) //one instruction=0.2us
#use rs232(baud=9600, xmit=PIN_c6, rcv=PIN_c7)
#bit t1_overflow=0x0C.0

// #bit t1_overflow=0xF9E.0 (PIC18, Reminder)

void main() {
int cycles8, cycles;
int32 freq;
long freqc_high;
long freqc_low;

while (TRUE) {
cycles8=0;
cycles=0;
freqc_high=0;
t1_overflow=0;
set_timer1(0);
setup_timer_1(T1_EXTERNAL|T1_DIV_BY_1);
/* ___ wait one second ___ */
while (cycles!=0xFF) { //true=3, false=4
cycles8=0; //1 cycle
//start inner loop
while (cycles8!=0xFF) { //true=3, false=4
if (t1_overflow)//true=2,false=3 //----|
{t1_overflow=0;freqc_high++;}//6 cycles // |
else // |-- 8 cycles
{delay_cycles(5);} //----|
delay_cycles(62); //x
cycles8++; //1
///2 cycles to jump to top
//math: end inner loop
//math: total inner loop=((3+8+x+1+2)*255 + 4)*255
//math: if x=62.87781 then inner loops takes 5mil instructions
//math: if x=62 then inner loop takes 4942920, have to fill 57080 cycles
}
delay_cycles(216); //y
cycles++; ///1 cycle
///2 cylces to jump to top
//math: outer=(3+1+y+1+2)*255+4=57080
//math: y=(57080-4)/255)-(3+1+0+0+1+2)
//math: if y=216.827450980392156862745098039216 then outer loop cylces is 57080
//math: if y=216 then outer loop cycles is off by 211 cycles. z=211
}
delay_cycles(211); //z
/* ___ end waiting 1 second ___ */
setup_timer_1(T1_DISABLED); //turn of counter to prevent corruption while grabbing value
if (t1_overflow) //check one last time for overflow
freqc_high++;
freqc_low=get_timer1(); //get timer1 value as the least sign. 16bits of freq counter
freq=make32(freqc_high,freqc_low); //use new make32 function to join lsb and msb
printf("%LU Hz\r\n",freq); //and print frequency

}
}
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Sat Dec 20, 2003 1:47 pm     Reply with quote

Well this doesn't have anything to do with using a CCP to measure the frequency. It actually uses the timer1 as a counter being driven by the frequency that is being measured. It also doesn't allow for anything else to occur while the test is in progress. I wouldn't use this method. I would stick with using the CCP module.
Guest








PostPosted: Sat Dec 20, 2003 2:31 pm     Reply with quote

Glad you made that clear
i would stick to the capture method
Very big thanks

Jan
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group