View previous topic :: View next topic |
Author |
Message |
irmanao
Joined: 08 Apr 2015 Posts: 77
|
CCP (capture) issue with 16f1827 |
Posted: Sat Aug 19, 2017 8:31 am |
|
|
Hey,
I want to capture a square wave and measure its frequency and do certain things if that frequency falls into a small spectrum. I use a signal generator for the square wave that i feed into the PIC and this code from here https://www.ccsinfo.com/forum/viewtopic.php?t=29963
Code: |
#include <16F1827.h>
#fuses NOWDT, NOPROTECT, BROWNOUT, PUT, NOLVP
#use delay(internal = 4000000)
int16 isr_ccp_delta;
#int_ccp4
void ccp1_isr(void)
{
int16 current_ccp;
static int16 old_ccp = 0;
// Read the 16-bit hardware CCP1 register
current_ccp = CCP_4;
// 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()
{
int16 current_ccp_delta;
int16 frequency;
set_timer1(0);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
setup_ccp4(CCP_CAPTURE_RE);
clear_interrupt(INT_CCP4);
enable_interrupts(INT_CCP4);
enable_interrupts(GLOBAL);
while(1)
{
disable_interrupts(GLOBAL);
current_ccp_delta = isr_ccp_delta;
enable_interrupts(GLOBAL);
frequency = (int16)(1000000L / current_ccp_delta);
if (frequency>20000 && frequency<22000)
output_high(PIN_A0);
else output_low(PIN_A0);
delay_ms(100);
}
} |
The problem is that even though my generator outputs a smooth signal the LED that is connected to PIN_A0 goes from high to low at random intervals when the right frequency is detected (20kHz-22kHz).
ccs v.5.008
Any ideas why it's not staying ON continuously?
thanks
Last edited by irmanao on Mon Aug 21, 2017 9:46 am; edited 3 times in total |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Aug 19, 2017 10:47 am |
|
|
Before even looking at your code too much, can you answer these
questions:
1. What is the Vdd voltage of your PIC ?
2. What are the high and low voltages of your incoming square wave
signal ? If you have an oscilloscope, look at the voltages.
Also, one more thing:
Your while(1) loop doesn't have any delay in it. I would add a delay of
100 ms to the end of the loop. Then I think you would get a better
impression of the on/off timing of the LED. Add this line:
|
|
|
irmanao
Joined: 08 Apr 2015 Posts: 77
|
|
Posted: Sat Aug 19, 2017 11:11 am |
|
|
Yeap, added the delay and it now works great. Thanks for the valuable tip and time. |
|
|
irmanao
Joined: 08 Apr 2015 Posts: 77
|
|
Posted: Sat Aug 19, 2017 1:42 pm |
|
|
I now came across a different problem... If i feed the CCP with a short pulse of the correct frequency, the LED does go ON but it never goes off. Any ideas?
thanks |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Aug 19, 2017 2:46 pm |
|
|
A short pulse ?
Do you mean one individual, single, lone, pulse that is of some
unspecified short time duration ? If so, post the duration of the
single pulse.
Or do you mean a short burst of 20-22 KHz squarewave ?
If so, post the length of the burst in time, or in the number of full cycles
of the squarewave.
Also, post the amount of time before and after the single pulse, or burst. |
|
|
irmanao
Joined: 08 Apr 2015 Posts: 77
|
|
Posted: Sat Aug 19, 2017 4:41 pm |
|
|
I mean a short burst (two full cycles) of the squarewave. I use a push button connected to a different PIC to send it whenever i press it. If i disconnect the wire that feeds that burst, the LED does go low again... but it doesn't after the burst is over.
thanks |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Sat Aug 19, 2017 5:42 pm |
|
|
The basic problem is, you've had a CCP interrupt, then there's no more
signal, so you don't get anymore interrupts. Therefore, 'isr_ccp_delta'
retains the last value that it was set to. The calculated frequency
doesn't change, and the LED stays on.
There are a couple ways to handle this.
1st method:
You could, after copying isr_ccp_delta into current_ccp_delta, just set
isr_ccp_delta to 1000000L or something. That number, when used in
the frequency calculation, will give you a freq of 1. Your LED will go off.
I haven't tested this, but it sounds like it would work.
2nd method:
This post explains how to do it:
http://www.ccsinfo.com/forum/viewtopic.php?t=29963&start=9
The post below gives a code example that implements that method.
You can see that a global 'gc_capture_flag' variable was added to the
program. Then it's set inside the isr to indicate a CCP interrupt occurred.
http://www.ccsinfo.com/forum/viewtopic.php?t=33153&&start=67
If the first method works, then go with it. |
|
|
irmanao
Joined: 08 Apr 2015 Posts: 77
|
|
Posted: Sun Aug 20, 2017 4:47 am |
|
|
Yep, the first method worked. Thanks a lot for the original code also. |
|
|
|