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

Frequency reading using PIC
Goto page Previous  1, 2, 3
 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Aug 20, 2009 5:33 pm     Reply with quote

What is your compiler version ? I don't think you ever posted it.
nizar445



Joined: 09 Jun 2009
Posts: 23

View user's profile Send private message

PostPosted: Thu Aug 20, 2009 6:04 pm     Reply with quote

Quote:
What is your compiler version ?


MPLAB 8.10
CCS C Compiler V4.013
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Thu Aug 20, 2009 6:13 pm     Reply with quote

Post the program you're actually using to test this.

You referred to some earlier program. I looked earlier in the thread.
The one I found is doing compares and lighting up LEDs. That's useless
to me for a test program. I need one that displays the frequency
on a terminal window. Then I can test your problem.

-------

I can't do anything more on this today. I'll work on it tomorrow.
nizar445



Joined: 09 Jun 2009
Posts: 23

View user's profile Send private message

PostPosted: Thu Aug 20, 2009 7:07 pm     Reply with quote

Here is my full code:

Code:
#include <16F87.H>
#fuses  NOPROTECT, NOLVP, NOPUT, NOMCLR,NOBROWNOUT, NOCPD, NOWRT, NODEBUG, XT, NOWDT

#use delay(clock=4000000)

#use rs232(baud=9600, xmit=PIN_B5)
// This global variable holds the time interval
// between two consecutive rising edges of the
// input signal.
   
float isr_ccp_delta;

// When a rising edge occurs on the input signal,
// the CCP1 will 'capture' the value of Timer1
// at that moment.  Shortly after that, a CCP1
// interrupt is generated and the following isr
// is called.   In the isr, we read the 'captured'
// value of Timer1.  We then subtract from it the
// Timer1 value that we 'captured' in the previous
// interrupt.  The result is the time interval
// between two rising edges of the input signal.
// This time interval is then converted to a frequency
// value by code in main(). 

#int_ccp1
void ccp1_isr(void)
{
float current_ccp;
static float old_ccp = 0;


current_ccp = CCP_1;  // From 16F819.H file

// Calculate the time interval between the
// previous rising edge of the input waveform
// and the current rising edge.  Put the result
// in a global variable, which can be read by
// code in main().

isr_ccp_delta = current_ccp - old_ccp;

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


//=======================
void main()
{
float current_ccp_delta;
float frequency;

// Setup Timer1 and CCP1 for Capture mode so that
// we can measure the input signal's frequency.
// The input signal comes from an external function 
// generator, which is connected to the CCP1 pin 8 with a wire.


set_timer1(0);           
setup_timer_1(T1_INTERNAL | T1_DIV_BY_8); 
setup_ccp1(CCP_CAPTURE_RE);   

// Clear the CCP1 interrupt flag before we enable
// CCP1 interrupts, so that we don't get an unwanted
// immediate interrupt (which might happen).

clear_interrupt(INT_CCP1);
enable_interrupts(INT_CCP1);
enable_interrupts(GLOBAL);


output_high(PIN_B4);
delay_ms(1000);

while(1)
  {
   while(1)
   {
      // Get a local copy of the latest ccp delta from the isr.
      // We have to disable interrupts when we read a global
      // isr variable that is larger than a single byte.
   
      disable_interrupts(GLOBAL);
      current_ccp_delta = isr_ccp_delta;
      enable_interrupts(GLOBAL);
      
   
      // To calculate the frequency of the input signal,
      // we take the number of clocks that occurred
      // between two consecutive edges of the input signal,
      // and divide that value into the number of Timer1
      // clocks per second.   Since we're using a 4 MHz
      // internal clock, the Timer1 clock is 1 MHz (Timer1 runs
      // at the instruction cycle rate, which is 1/4 of the
      // internal clock frequency).  For example, suppose the
      // the input waveform has a frequency of 244 Hz.
      // 244 Hz has a period of about 4098 usec.
      // Timer1 is clocked at 1 MHz, so between two
      // consecutive rising edges of the input signal,
      // it will count up by 4098 clocks.  To find the
      // frequency, we divide 4098 into the number of
      // clocks that occur in 1 second, which is 1000000.
      // This gives 1000000 / 4098 = 244 Hz.
   
      frequency = (float)(125000L / current_ccp_delta);
      // Display the calculated frequency.
         printf("\n\r freq = %f", frequency);
        if (frequency <= 30)   
          {
         printf("low");
         output_low(PIN_B4);
           delay_ms(3000);
           output_high(PIN_B4);
           delay_ms(3000);
   
          }
      else if (frequency > 30 && frequency <= 59)   
          {
          printf("normal");
            output_low(PIN_B4);
            delay_ms(1000);
            output_high(PIN_B4);
            delay_ms(1000);
   
            }     
      else
            {
            printf("high");
               output_low(PIN_B4);
               delay_ms(500);
               output_high(PIN_B4);
               delay_ms(500);
             break;
            }
      }  // end first while 1
          
       while(1)
      {
            disable_interrupts(GLOBAL);
            current_ccp_delta = isr_ccp_delta;
            enable_interrupts(GLOBAL);
         frequency = (float)(125000L / current_ccp_delta); 
            printf("\n\r freq = %f", frequency);
         delay_ms(1000);

         if (frequency > 59)   
              {
              output_low(PIN_B4);  //LED ON (active LOW)
            printf("hiiiiiiiiiigh");
            delay_ms(1000);
             // read analoge input and reduce input code goes here to be develped later!!   
             }
         else if (frequency <= 59)
            {
            printf("good bye");
            delay_ms(1000);
            break;
            }
      }// end second while 1
      
   }   //end while(1)

}  // end main



Thanks a lot mate
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Aug 21, 2009 12:41 pm     Reply with quote

Quote:
float isr_ccp_delta;

#int_ccp1
void ccp1_isr(void)
{
float current_ccp;
static float old_ccp = 0;
.
.
.
}

void main()
{
float current_ccp_delta;
float frequency;

You have edited my code. Did you realize this ? The data types
for the variables shown in bold are supposed to be 'int16'. That's what
they were. If you change them back to int16 then it all starts working.
There is nothing wrong with my code (a little bit of pride at work here).
nizar445



Joined: 09 Jun 2009
Posts: 23

View user's profile Send private message

PostPosted: Fri Aug 21, 2009 3:54 pm     Reply with quote

Yes I did that on purpose, I thought that, by changing all the variables to “float” I will get more accurate readings as all the calculations will include the decimals!!?

If I change these variables back to “int16” will I get the decimals?

Thanks for your reply.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Aug 21, 2009 4:10 pm     Reply with quote

To get a fractional result, with numbers to the right of the decimal point,
do this:

1. Change all the specified data types back to 'int16', as I indicated in
my earlier post. (and no others).

2. Change the equation that calculates the frequency to this:
Code:
 frequency = 125000.0 / current_ccp_delta;

Note how the numerator is now represented as a float value, by
appending a .0 on the end of it. This forces the compiler to do
the equation with floating point math, and to give a floating point
result.
nizar445



Joined: 09 Jun 2009
Posts: 23

View user's profile Send private message

PostPosted: Fri Aug 21, 2009 5:07 pm     Reply with quote

Thanks for your reply, I will try that, by the way, there was “L” letter next to the 125000 in the frequency formula do I need to include it or not?

Code:
frequency = (125000L / current_ccp_delta);


And why did you put it in your program, and what does it do?
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Goto page Previous  1, 2, 3
Page 3 of 3

 
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