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 CCS Technical Support

Using CCP1 to measure Frequency

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



Joined: 09 Jul 2004
Posts: 70

View user's profile Send private message

Using CCP1 to measure Frequency
PostPosted: Mon Apr 14, 2008 8:58 pm     Reply with quote

Hello,
I have been looking for a way to use either CCP1 or CCP2 to measure an input frequency. I have read several posts on this forum for doing tachometers and gathered some of the programs that other have posted. I am trying to read a frequency of tenths of Hz up to a few kHz. I have tried to use the code posted by PCM Programmer and others that makes the timer a 24 bit to get the lower frequencies. My program that i have put together, seems to work well at high frequencies (tested at 1Khz to 3 kHz) however at lower frequencies i get 1hz returned quite often and ocasionally the correct value. Below 150 hz it gives all kinds of erronous values. Please review the code below and if anyone see errors let me know. Compiler 4.062 PIC18F8722
Code:

#include <18F8722.H>
#device adc=10
#include <stdio.h>
#include <math.h>
#include <bootloader.h>
//#fuses HSPLL, PLL3, CPUDIV1, NOWDT, PUT, BROWNOUT, NOLVP   // 12 MHz xtal
#fuses HS, WDT, NOPUT, NOBROWNOUT, NOLVP // 20 MHz xtal
#use delay(clock=40000000,RESTART_WDT)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

#priority CCP1, TIMER1

//#define BytePtr(var, offset)   (char *)(&(char *)var + offset)
#define BytePtr(var,offset)(char*)(&var+offset)

#byte PIR1 = 0xF9E
#bit  TMR1IF = PIR1.0


int8  gc_timer1_extension = 0;
int8  gc_capture_flag = FALSE;
int32 g32_ccp_delta;

//------------------------------------------------------
#int_timer1
void timer1_isr(void)
{
gc_timer1_extension++;
}

//------------------------------------------------------

#int_ccp1
void ccp1_isr(void)
{
   char timer_ext_copy;
   int32 current_ccp;
   static int32 old_ccp=0;
   gc_capture_flag=TRUE;
   current_ccp=(int32)CCP_1;
   timer_ext_copy=gc_timer1_extension;
   if(TMR1IF)
   {
      if(*BytePtr(current_ccp,1)<2)
         timer_ext_copy++;
      gc_timer1_extension++;
      TMR1IF=0;
   }
   *BytePtr(current_ccp,2)=timer_ext_copy;
   g32_ccp_delta=(current_ccp>old_ccp)?current_ccp-old_ccp:current_ccp+(0x1000000-old_ccp);
   old_ccp=current_ccp;
}
//=======================
void main()
{
int16 frequency;
int32 current_ccp_delta;

set_timer1(0);           
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
setup_ccp1(CCP_CAPTURE_RE);
clear_interrupt(INT_TIMER1);  // Enable interrupts.
enable_interrupts(INT_TIMER1);
clear_interrupt(INT_CCP1);
enable_interrupts(INT_CCP1);

enable_interrupts(GLOBAL);

gc_capture_flag=FALSE;

while(1)
  {
   disable_interrupts(GLOBAL);
   current_ccp_delta = g32_ccp_delta;;
   enable_interrupts(GLOBAL);
   if(gc_capture_flag == TRUE)
   {
      //setup_timer_1(T1_DISABLED);

      //(int32)current_ccp_delta = second_ccp-first_ccp;
      frequency = (int16)((10000000L + (current_ccp_delta >> 1)) / current_ccp_delta);

      printf("%lu Hz\n\r", frequency);
//      printf("%lu Hz, delta = %lx \n\r", frequency, current_ccp_delta);

      gc_capture_flag = FALSE;
   }
 

  delay_ms(100);
 }

}
nmeyer



Joined: 09 Jul 2004
Posts: 70

View user's profile Send private message

PostPosted: Wed Apr 16, 2008 8:15 pm     Reply with quote

i was able to get this working very well by making a few minor changes. I can read a few hz upto at least 3Khz which is plenty for my needs. However, i am now trying to integrate this in a much larger program and there it falls apart. I am still investigating why. here is the new code.
Code:

#include <18F8722.H>
#device adc=10
#include <stdio.h>
#include <math.h>
#include <bootloader.h>
//#fuses HSPLL, PLL3, CPUDIV1, NOWDT, PUT, BROWNOUT, NOLVP   // 12 MHz xtal
#fuses HS, WDT, NOPUT, NOBROWNOUT, NOLVP // 20 MHz xtal
#use delay(clock=40000000,RESTART_WDT)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, ERRORS)

#priority CCP1, TIMER1

#define BytePtr(var, offset)   (char *)(&(char *)var + offset)

#byte PIR1 = 0xF9E
#bit  TMR1IF = PIR1.0


int8  gc_timer1_extension = 0;
int8  gc_capture_flag = FALSE;
int32 g32_ccp_delta;

//------------------------------------------------------
#int_timer1
void timer1_isr(void)
{
gc_timer1_extension++;
}

//------------------------------------------------------

#int_ccp1
void ccp1_isr(void)
{
   char timer_ext_copy;
   int32 current_ccp;
   static int32 old_ccp=0;
   gc_capture_flag=TRUE;
   current_ccp=(int32)CCP_1;
   timer_ext_copy=gc_timer1_extension;
   if(TMR1IF)
   {
      if(*BytePtr(current_ccp,1)<2)
         timer_ext_copy++;
      gc_timer1_extension++;
      TMR1IF=0;
   }
   *BytePtr(current_ccp,2)=timer_ext_copy;
   g32_ccp_delta=(current_ccp>old_ccp)?current_ccp-old_ccp:current_ccp+(0x1000000-old_ccp);
   old_ccp=current_ccp;
}
//=======================
void main()
{

int16 frequency,x;
int32 current_ccp_delta;

set_timer1(0);           
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
setup_ccp1(CCP_CAPTURE_FE);
clear_interrupt(INT_TIMER1);  // Enable interrupts.
enable_interrupts(INT_TIMER1);
clear_interrupt(INT_CCP1);
enable_interrupts(INT_CCP1);

enable_interrupts(GLOBAL);

gc_capture_flag=FALSE;
x=0;
while(1)
  {
   disable_interrupts(GLOBAL);
   current_ccp_delta = g32_ccp_delta;;
   enable_interrupts(GLOBAL);
   if(gc_capture_flag == TRUE)
   {
      frequency = (int16)((10000000L + (current_ccp_delta >> 1)) / current_ccp_delta);
      gc_capture_flag = FALSE;
      clear_interrupt(INT_CCP1);
   }
   if(x==50000)//50000
   {
      printf("%lu Hz\n\r", frequency);
      x=0;
   }
  x=x+1;
  delay_us(10);
 }

}

 
RLScott



Joined: 10 Jul 2007
Posts: 465

View user's profile Send private message

PostPosted: Thu Apr 17, 2008 5:47 am     Reply with quote

nmeyer wrote:
i was able to get this working very well by making a few minor changes. I can read a few hz upto at least 3Khz which is plenty for my needs. However, i am now trying to integrate this in a much larger program and there it falls apart. I am still investigating why. here is the new code.


Are we supposed to look at that code and guess what "falling apart" means? Tell us exactly what your problem is if you want someone to look for a problem.

Robert Scott
Real-Time Specialties
nmeyer



Joined: 09 Jul 2004
Posts: 70

View user's profile Send private message

PostPosted: Thu Apr 17, 2008 7:52 am     Reply with quote

The code i posted above works as is. I wanted to get that posted so that if anyone else was looking, they would have a "working" example. At the time of my post i had added this code into a much larger program and i am having issues with it not reporting a frequency that is anywhere close to what it should be. I have not posted any code from that program, as i am investigating it to see if i can solve it. If not, i will post new information.
Thanks
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