|
|
View previous topic :: View next topic |
Author |
Message |
chary_pr23
Joined: 19 Nov 2008 Posts: 4
|
Problem with Input capture |
Posted: Tue Dec 02, 2008 3:46 am |
|
|
Hi,
I am using PIC24FJ128GA010 on the Explorer 16 Development board. I use CCS compiler V 4.078
I am feeding a square wave to the input capture pin. But the difference in subsequent capture values deviate from the correct value on every 8th capture event.
The init and ISR for the input capture module are as follows
Code: | /**********************************************************************************************************
Input capture module
**********************************************************************************************************/
#define CAP_VALS_LEN 400
static uint16_t cap_val[CAP_VALS_LEN];
static int i;
/**********************************************************************************************************
I N I T I A L I S A T I O N
**********************************************************************************************************/
void init_ic1(void)
{
RCFGCAL = 0x0000; // Disable the RTCC module which multiplexes the IC1 pin
TRISD |= 0x0100; // Configure IC1 pin (PIN_D8) as input
IPC0 |= 0x0010;
IEC0 |= 0x0002; // Enable interrupts.
IFS0 &= 0xFFFD; // Clear the Ic1 interrupt status flag.
IC1CON = CAPTURE_OFF; // Turn off input capture module.
IC1CON = CAPTURE_TIMER2 | // On capture event Timer 2 is captured
INTERRUPT_EVERY_CAPTURE | // Interrupt on every capture event
CAPTURE_EE | // Capture Every Edge
CAPTURE_CONTINUE_IDLE; // Capture module continues during idle mode
}
/**********************************************************************************************************
I S R
**********************************************************************************************************/
#INT_IC1 NOCLEAR
void ic1_isr(void)
{
uint16_t capture = 0;
uint16_t diff = 0;
static uint16_t prev_cap;
IFS0 &= 0xFFFD; // Clear the interrupt flag.
capture = IC1BUF;
diff = capture - prev_cap;
prev_cap = capture;
cap_val[i] = diff;
if(i == (CAP_VALS_LEN -1)) {
i = 0;
} else {
i++;
}
} |
The clock which drives timer2 is 16Mhz (Fosc = 32Mhz)
When the input waveform is a square wave of pulse width 70us, the difference between subsequent capture values must be 1120. the values in the buffer cap_val is
{
1024, 1121, 1121, 1120, 1121, 1121, 1120, 1121,
1024, 1121, 1121, 1121, 1121, 1121, 1121, 1121,
1024, 1121, 1121, 1121, 1121, 1121, 1121, 1121,
1024, 1121, 1121, 1121, 1121, 1121, 1121, 1121,
1024, 1121, 1121, 1121, 1121, 1119, 1121, 1121,
1024, 1121, 1121, 1121, 1121, 1121, 1121, 1121,
1024, 1121, 1121, 1121, 1121, 1121, 1121, 1121,
1024, 1121, 1121, 1120, 1121, 1121, 1121, 1121,
1024, 1121, 1121, 1121, 1121, 1121, 1121, 1121,
1024, 1121, 1121, 1121, 1121, 1121, 1121, 1121................}
Increasing or decreasing the period of the input waveform has no effect(except that the capture value changes). Wrong capture value continues to occur on every 8th capture event.
Please help me tackle this problem.
Thanks in advance
Chary
Last edited by chary_pr23 on Thu Dec 04, 2008 6:59 am; edited 3 times in total |
|
|
RLScott
Joined: 10 Jul 2007 Posts: 465
|
Re: Problem with Input capture. |
Posted: Tue Dec 02, 2008 6:55 am |
|
|
What relationship does the "bad" value have to the "good" value as you change the period of the input signal? The example you showed here has 1024 instead of 1120, for a drop of 96. Is the bad value always 96 lower than the good value, or is it always 1024, or what? _________________ Robert Scott
Real-Time Specialties
Embedded Systems Consulting |
|
|
chary_pr23
Joined: 19 Nov 2008 Posts: 4
|
|
Posted: Wed Dec 03, 2008 12:52 am |
|
|
The bad value is such that the least significant byte in the difference(between cap values)becomes zero.
i.e
if the difference is 0x460, then the bad value is 0x400,
if the difference is 0x1033, then the bad value is 0x1000 and so on. |
|
|
RLScott
Joined: 10 Jul 2007 Posts: 465
|
|
Posted: Wed Dec 03, 2008 9:28 pm |
|
|
I don't know what is going on, but I am surprised that the collected data is so perfect. Usually when an external signal is being captured, the relative drift in timing between the external signal and the PIC clock causes a +/- 1 difference at least. Yet you show a whole bunch of 1120 results. Is the signal you are measuring somehow locked to the PIC clock? _________________ Robert Scott
Real-Time Specialties
Embedded Systems Consulting |
|
|
chary_pr23
Joined: 19 Nov 2008 Posts: 4
|
|
Posted: Thu Dec 04, 2008 12:35 am |
|
|
No.
Actually the values are 1121 instead of 1120. Sorry for that. I was sharing the board with other team members so I couldn't get you a copy paste of the readings in watch window. I have manually entered the values and meanwhile forgot about the +/-1 factor. |
|
|
RLScott
Joined: 10 Jul 2007 Posts: 465
|
|
Posted: Thu Dec 04, 2008 5:52 am |
|
|
Well, I see nothing wrong with the init or the isr, so I will guess that the 1/8 behavior has something to do with the rest of the code that is not posted. _________________ Robert Scott
Real-Time Specialties
Embedded Systems Consulting |
|
|
chary_pr23
Joined: 19 Nov 2008 Posts: 4
|
|
Posted: Thu Dec 04, 2008 6:39 am |
|
|
Here is the code for timer2 init and the fuses.
Code: |
#ifndef _FUSES_H_
#define _FUSES_H_
#include <24FJ128GA010.h>
#device ICD=TRUE
#OPT 0 //Optimization level is 0
#FUSES HS //High Speed Oscillator
#FUSES PR //Pimary oscillator enabled
#FUSES NOWDT //No Watch Dog Timer
#FUSES NOJTAG //JTAG disabled
#FUSES NOPROTECT //Code not protected from reading
#FUSES NOWRT //Program memory not write protected
#FUSES DEBUG //Debug mode for use with ICD
#FUSES ICS1 //ICD communication channel 1
#FUSES NOIESO //Internal External Switch Over mode enabled
#FUSES NOCKSFSM //Clock Switching is disabled, fail Safe clock monitor is disabled
#FUSES NOOSCIO //OSC2 is general purpose output
#use delay(clock=32000000)
#endif |
Code: | void timer2_init(void)
{
T2CON = 0x0000; // Stops the Timer2 and reset control reg.
TMR2 = 0x0000; // Clear contents of the timer register
PR2 = 0xFFFF; // Load the Period register with the value 0xFFFF
IPC1 |= 0x1000; // (This example assigns level 1 priority)
IFS0 &= 0xFF7F; // Clear the interrupt status flag
T2CON |= 0x8000; // Start timer2
disable_interrupts(INT_TIMER2);
} |
And the test application
Code: |
int main(void)
{
timer2_init();
init_ic1();
while(1);
return 0;
}
|
|
|
|
|
|
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
|