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

measure square wave frequency with CCP1 and CCP2

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



Joined: 18 Oct 2008
Posts: 3

View user's profile Send private message

measure square wave frequency with CCP1 and CCP2
PostPosted: Sat Oct 18, 2008 12:22 pm     Reply with quote

Hello at all!
I've a problem..Smile

At button pression a square wave and ac continuous signal arrive
respectively to pin RC2 and RC1. The frequency is about 100 Hz.
I used the CCP2 module as a sort of control pin to say "start to count"
two rising edge but I think that I made a mistake. The code give me
strange frequency.

I used PCWH compiler version 3.241 (....yes I know)
Code:

#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

int16 current_ccp;
int16 isr_ccp_delta;
static int16 old_ccp = 0;
int count;
int16 frequency=0;
int16 current_ccp_delta;


#INT_CCP2
void ccp2_isr(void)
{
   disable_interrupts(INT_CCP2);
   count = 0;
   set_timer1(0);
   clear_interrupt(INT_CCP2);
   clear_interrupt(INT_CCP1);
   enable_interrupts(INT_CCP1);

}


#INT_CCP1
void ccp1_isr(void)
{

count++;
current_ccp = CCP_1;
isr_ccp_delta = current_ccp - old_ccp;
old_ccp = current_ccp;

   if(count==2){
      current_ccp_delta = isr_ccp_delta;
      frequency= (50000000L / current_ccp_delta);
      enable_interrupts(INT_CCP2);
   }

clear_interrupt(INT_CCP1);
}





VOID main()
{


SETUP_TIMER_1(T1_INTERNAL | T1_DIV_BY_1);     //timer 1 avanza con clock interno con prescaler 1
setup_ccp1(CCP_CAPTURE_RE);
setup_ccp2(CCP_CAPTURE_RE);
clear_interrupt(INT_CCP2);
clear_interrupt(INT_CCP1);
enable_interrupts(INT_CCP2);
enable_interrupts(GLOBAL);


   while(TRUE){
      printf("%lu Hz  \n\r", frequency);
   }
}

thank you very much

regards from Italy
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Sat Oct 18, 2008 6:50 pm     Reply with quote

1. Why are you doing this ? What is the purpose ?

2. Which pin has the button connected to it ?

3. Does a signal go through the button ?

4. Which pin has the sine wave input, and which pin has the square wave ?

5. What is the amplitude of the sine wave ? The CCP pins really expect
to get a square wave (or rectangular wave). They don't expect to get
an analog waveform as the input.

6. What is the amplitude of the square wave ?

7. Why are you doing the math inside the interrupt routine ?

8. Why does the design of this project have to be so complicated ?
I suspect that it can be done in a more simple way, if you explain
completely what the project is about.
gabbo141



Joined: 18 Oct 2008
Posts: 3

View user's profile Send private message

re
PostPosted: Sun Oct 19, 2008 3:11 am     Reply with quote

dear PCM programmer

thanks for your interest,

I try to answer

1. I have a ir receiver that generate a different (in frequency) square wave depending on which button is pressed on the ir transmitter. the square wave generated from the ir sensor is then cleaned from noise and goes to pin RC2 (CCP1) of the pic.
at the same time a circuit makes the output ir sensor square wave continuous and this signal is send to pin RC1 (CCP2).
so, both the square wave and the continuous signal arrive to pins at the same.
then , discriminating two frequency, i should to move a stepper motor (but this is another problem Smile ).

2. the button is in the ir transmitter station and at its pression will be generated two signals in the receiver station: a square wave and a continuous signal (derived from the S.W.).

3 ...

4. RC1 continuous signal RC2 square wave

5. The continuous signal is +5 V

6. The square wave is +5-0V

7. To do a smaller number of instructions inside the WHILE(TRUE)

8. I make this design because i would two count only the first two rising edge and I need to reset my system when the button is released.


I hope that everything is clear


thank you a lot
Gabriele


Last edited by gabbo141 on Sun Oct 19, 2008 6:53 am; edited 1 time in total
Ttelmah
Guest







PostPosted: Sun Oct 19, 2008 5:00 am     Reply with quote

You description is not very clear.

As I understand it, you have a receiver, that produces a 'tone' output, in the form of a TTL (nominally 5v) digital pulse train, with two different possible frequencies, connected to CCP1.
The same receiver, then also produces a 'level', which goes high, when a legitimate tone is present. This you have connected to CCP2.
Change the design.
Connect the ''level', to one of the standard input not the CCP input. Say RB0.
Then, stop trying to measure a frequency. All you need to do, is test if the time interval between subsequent signal edges, is greater or less than a constant you define. Converting to a frequency, will probably take longer than you have available. If you must convert to a frequency, do this outside the ISR in the main code.

So, something like:
Code:

#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7,ERRORS)

int1 button1=0, button2=0;

#define MID_TONE (1000)
//You need to define this based on the time interval expected
//For a tone half way between the two frequencies.

#INT_CCP1
void ccp1_isr(void) {
   int16 isr_ccp_delta;
   static int16 old_ccp;
   int16 current_ccp;

   current_ccp = CCP_1;
   if (current_ccp < old_ccp)
      isr_ccp_delta = old_ccp - current_ccp;
   else
      isr_ccp_delta = current_ccp - old_ccp;
   //Because of the way the 16bit arithmetic will wrap, this handles
   //the overflow when the timer has wrapped.

   old_ccp = current_ccp;
   if (input(PIN_RB0)) {
      //Here the external signal is high, saying we have a 'tone'
      //Only set the 'button' indicators if this is so.
      if (isr_ccp_delta < MID_TONE) button1=true;
      else button2=true;
   }
}

VOID main(void) {
    SETUP_TIMER_1(T1_INTERNAL | T1_DIV_BY_1);
    //timer 1 avanza   con clock interno con prescaler 1
    setup_ccp1(CCP_CAPTURE_RE);
    clear_interrupt(INT_CCP1);
    enable_interrupts(INT_CCP1);
    enable_interrupts(GLOBAL);


    while(TRUE){
       if (button1) {
          printf("High tone seen\n\r");
          button1=false;
      }
      if (button2) {
          printf("Low tone seen\n\r");
          button2=false;
      }
   }
}

As shown, this will keep triggering so long as a tone is seen, and the input (B0) is high.

Best Wishes
gabbo141



Joined: 18 Oct 2008
Posts: 3

View user's profile Send private message

PostPosted: Sun Oct 19, 2008 9:27 am     Reply with quote

dear ttl
yes...You've got it!....although my bad english
but I didn't understand


Code:

#define MID_TONE (1000)
//You need to define this based on the time interval expected
//For a tone half way between the two frequencies.

can you explain me?
and is this code efficient to discriminate 4 frequencies?
thanks
Ttelmah
Guest







PostPosted: Sun Oct 19, 2008 12:52 pm     Reply with quote

You would have to extend the test a bit for four tones.
If (for instance), the tones were, 1KHz, 1200Hz, 1450Hz, and 1700Hz, then the times between the edges would be 1msec, 833uSec, 689uSec, and 588uSec.
Then, with your clock, you could calculate the expected count for each tone, as:
time(in uSec)*5
So: 5000, 4165, 3445, and 2940 counts.

Then for a four tone detector, you would test for the counts being above (say) 4550 for the lowest tone, between 4549, and 3800 counts for the second, between 3799, and 3192 counts for the third, and if below 3191, then the fourth.

Best Wishes
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