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

Low frequency counting problem

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








Low frequency counting problem
PostPosted: Mon Feb 22, 2010 2:32 pm     Reply with quote

I'm a new user of CCSC. My compiler version is 4.068. I found a code for counting very low pulses. (Frequency will be 0.5Hz-3Hz) But this code doesn't work under 10Hz. Where is my mistake? How can I fix it?
Code:

#include <16F877.H>
#fuses XT, NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, bits=8)   

int16 isr_ccp_delta;

#int_ccp1
void ccp1_isr(void)
{
int16 current_ccp;
static int16 old_ccp = 0;
current_ccp = CCP_1;  // From 16F877.H file
isr_ccp_delta = current_ccp - old_ccp;
old_ccp = current_ccp;
}

//=======================
void main()
{

int16 current_ccp_delta;
int16 frequency;

set_timer1(0);           
setup_timer_1(T1_INTERNAL | T1_DIV_BY_8);
setup_ccp1(CCP_CAPTURE_RE);   
clear_interrupt(INT_CCP1);
enable_interrupts(INT_CCP1);
enable_interrupts(GLOBAL);


while(1)
  {
   disable_interrupts(GLOBAL);
   current_ccp_delta = isr_ccp_delta;
   enable_interrupts(GLOBAL);
   frequency = (625000L + (int32)(current_ccp_delta >>1)) / current_ccp_delta;

   // Display the calculated frequency.
   printf("\n\r%lu Hz\n\r", frequency);

   delay_ms(500);
  }

}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Feb 22, 2010 2:44 pm     Reply with quote

Use the code posted by Macas in this thread, and then make the
modifications that I explain later in the thread:
http://www.ccsinfo.com/forum/viewtopic.php?t=33153&start=45
Guest








PostPosted: Mon Feb 22, 2010 2:58 pm     Reply with quote

Ok I found a code. But I couldn't understand some points:
Code:

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

and

g32_ccp_delta = (current_ccp > old_ccp) ? current_ccp - old_ccp : current_ccp + (0x1000000 - old_ccp);


Could you explain these code?
Thanks....
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Mon Feb 22, 2010 3:27 pm     Reply with quote

The first one allows you to write to a specified byte in a 16 or 32 bit
variable that is an "lvalue" (i.e., the variable is on the left side of an
assignment).

The 2nd one is a fix for a sign-extension problem when doing 24-bit
math in 32-bit variables.
Guest








PostPosted: Thu Feb 25, 2010 11:41 am     Reply with quote

I have found a code for frequency counting. But this code doesn't work in real hardware. Could you show my mistake?
Code:

#include <18F452.H>
#fuses HS,NOWDT, PUT, BROWNOUT, NOLVP // 20 MHz xtal
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#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;   

// Get local copy of the timer ext.
timer_ext_copy = gc_timer1_extension;


if(TMR1IF)
  {
   if(*BytePtr(current_ccp, 1) < 2)  // Was CCP captured after Timer1 wrapped?
      timer_ext_copy++;  // If so, inc the copy of the timer ext.

   // Since we know a timer interrupt is pending, let's just
   // handle it here and now.  That saves a little load off
   // the processor.
   gc_timer1_extension++;  // Increment the real timer extension
   TMR1IF = 0;     // Then clear the Timer1 interrupt
  }

// Insert the timer extension into the proper place in the 32-bit
// CCP value.
// ie.,  Insert it into location "EE" as follows: 0x00EEnnnn
// (nnnn = the CCP).
*BytePtr(current_ccp, 2) = timer_ext_copy;

g32_ccp_delta = (current_ccp > old_ccp) ? current_ccp - old_ccp : current_ccp + (0x1000000 - old_ccp);

// Save the current ccp value for next time.
old_ccp = current_ccp;

}

//=======================
void main()
{
set_timer1(0);           
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);   
setup_ccp1(CCP_CAPTURE_RE);     
clear_interrupt(INT_TIMER1);
enable_interrupts(INT_TIMER1);
clear_interrupt(INT_CCP1);
enable_interrupts(INT_CCP1);
enable_interrupts(GLOBAL);

while(true)
  {
      float frequency;
      int32 current_ccp_delta;
      if(gc_capture_flag == TRUE)
     {
      disable_interrupts(GLOBAL);
      current_ccp_delta = g32_ccp_delta;;
      enable_interrupts(GLOBAL);
      frequency =  (5000000L / (float)current_ccp_delta);
      printf("%4.2f\n\r", frequency);
      gc_capture_flag = FALSE;
  }
  }
}
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Feb 25, 2010 11:45 am     Reply with quote

What device is providing the input signal to the CCP1 pin ?

What is the frequency of the input signal ?

What are the voltage levels of the signal ?

What is the duty cycle of the signal ?

Is the signal a rectangular waveform, or sinusoidal ?

Is the signal a clean, continuous, frequency signal ?
Guest








PostPosted: Thu Feb 25, 2010 2:10 pm     Reply with quote

1-Heart beat signal (From analog circuit)
2-Frequency will be 0.5Hz - 4Hz
3-The voltage level will be 0 to 4-4.5 V
4-Approximately %50
5-It likes rectangular signal
6-The Signal has some noise but not too much.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Feb 25, 2010 3:30 pm     Reply with quote

It works for me. I connected a B&K Function Generator (model 4011)
to pin C2 of my PicDem2-Plus board. This is the CCP1 input pin. I also
connected the ground lead from the B&K to the ground on the PicDem2-
Plus board. I set the B&K to output a square wave signal at 1 Hz, with
CMOS (0 to 5v) logic levels.

Then I slowly turned the Coarse adjustment frequency knob on the B&K
so it increased the frequency of the signal going to the PIC. Here is
what I see on the TeraTerm window on my PC:
Quote:

0.99
1.00
1.00
1.00
1.00
0.99
0.99
0.99
0.99
1.00
1.03
1.40
1.55
1.70
1.88
2.02
2.15
2.22
2.32
2.47
2.48
2.71
3.07
3.35
3.62
3.79
3.96
4.22
4.54
4.96
5.46
5.77
5.80
5.80
5.79
5.79

That's correct. The frequency goes up. Also, my oscilloscope has a
built-in frequency counter. It verifies that the signal is about 5.78 Hz.
So, it's all working. I tested this with the PCH compiler, vs. 4.104.
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