View previous topic :: View next topic |
Author |
Message |
Madri
Joined: 09 Mar 2008 Posts: 3
|
Using CCP in capture mode!?? |
Posted: Sun Nov 22, 2009 4:12 am |
|
|
Dear forum,
I've looked at numerous examples given on this forum on this exact same topic and still I am battling - tunnel vision? I don't know. This is my first time using the CCP in capture mode.
I use timer0 to generate a 50Hz signal on pin B0. This signal is fed to the CCP2 input that is configured in capture mode. I want to measure the frequency.
I display 49Hz instead of 50Hz. Where o where am I missing the bus?
Here is my code (as minimal as I could make it).
Is the problem in my calculation, or is it in the test signal I'm trying to generate. I unfortunately do not have access to a function generator. .
Any advice??
Regards,
Madri
Code: |
#include <18F4620.h>
#device HIGH_INTS=true
#fuses HS,NOPROTECT,NOWDT,BROWNOUT,PUT,NOLVP
#use delay(clock=20000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
/* Public interface */
//....
/* Constants */
//...
/* Global variables */
int timer1RolloverCount = 0;
int16 frequency;
int32 isrCCPdelta;
int1 captureFlag = FALSE;
void init(void)
{
init_pins();
set_timer0(40536); //set up timer 0 to interrupt every 10ms
setup_counters(RTCC_INTERNAL,RTCC_DIV_2);
set_timer0(0);
setup_ccp2(CCP_CAPTURE_RE);
setup_timer_1(T1_INTERNAL|T1_DIV_BY_4); //period of timer 1 = 800ns per tick
set_timer1(0);
clear_interrupt(INT_TIMER1); //ensure interrupt flag is cleared
clear_interrupt(INT_CCP2); //ensure interrupt falg is cleared
enable_interrupts(INT_TIMER0); //servo and contact sensor time base
enable_interrupts(INT_CCP2);
enable_interrupts(INT_TIMER1); //used to provide time base for speed related calculations
enable_interrupts(GLOBAL);
} /* init */
/*****************************************************************************
* TIMER 0 interrupt. Provides the 20ms period for the test signal on pin B0.
****************************************************************************/
#int_TIMER0
void TIMER0_isr()
{
set_timer0(40536); //create 10ms timebase thus creating a signal with freq 50Hz
output_toggle(PIN_B0); //to test frequency reading...
}/* TIMER0_isr */
/*****************************************************************************
* TIMER 1 interrupt. Keeps track of number of roll over events. TIMER 1 is also the timer associated with the
* CAPTURE mode ****************************************************************************/
#int_TIMER1
void TIMER1_isr()
{
++timer1RolloverCount; //increment count when a timer rollover event occurs
}
/*****************************************************************************
* Capture interrupt. Occurs when encoder sensor goes high. Calculates pulse length.
* This is then used to calculate the distance and speed.
****************************************************************************/
#INT_CCP2
void CCP2_isr()
{
int32 endTime;
static int32 startTime = 0;
endTime = CCP_2;
isrCCPdelta = (int32)0x10000 * timer1RolloverCount - (int32)startTime + (int32)endTime;
startTime = endTime; //end of one pulse is start of next;
timer1RolloverCount = 0; //restart rollover count
captureFlag = TRUE;
}
/*****************************************************************************
* Main routine.
****************************************************************************/
void main(void)
{
int16 externCCPdelta;
init();
while (TRUE)
{
if(captureFlag==TRUE) //tesing rpm only...
{
disable_interrupts(GLOBAL);
externCCPdelta = isrCCPdelta;
enable_interrupts(GLOBAL);
frequency = (int16)(1250000L / externCCPdelta);
printf("Freq = %Lu\r\n",frequency);
captureFlag = FALSE;
}
else
{
printf("No signal...\r\n");
}
delay_ms(200);
}//end while(true)
}/* main */
|
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
Madri
Joined: 09 Mar 2008 Posts: 3
|
thanks! |
Posted: Sun Nov 22, 2009 11:37 am |
|
|
Many thanks! Now it's working 100%.
Madri |
|
|
Madri
Joined: 09 Mar 2008 Posts: 3
|
o' no!??? |
Posted: Sun Nov 22, 2009 12:47 pm |
|
|
When I change the code in timer0 to generate a 5Hz signal (closer to my real-world signal), the frequency displays 23. I am very confused!?
Why is this happening? How can I fix it?
Madri
I changed frequency calculation to:
Code: | frequency = (int16)((1250000L + (int32)(externCCPdelta>>1))/ (float)externCCPdelta); |
|
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
|