![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
gabbo141
Joined: 18 Oct 2008 Posts: 3
|
measure square wave frequency with CCP1 and CCP2 |
Posted: Sat Oct 18, 2008 12:22 pm |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Oct 18, 2008 6:50 pm |
|
|
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. |
|
![](templates/subSilver/images/spacer.gif) |
gabbo141
Joined: 18 Oct 2008 Posts: 3
|
re |
Posted: Sun Oct 19, 2008 3:11 am |
|
|
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 ).
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 |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah Guest
|
|
Posted: Sun Oct 19, 2008 5:00 am |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
gabbo141
Joined: 18 Oct 2008 Posts: 3
|
|
Posted: Sun Oct 19, 2008 9:27 am |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah Guest
|
|
Posted: Sun Oct 19, 2008 12:52 pm |
|
|
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 |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|