r/electronics•
uscEE

PIC32 CCP Module

I'm currently working on a project and I would like to use the Capture module to measure the speed from a tachometer. I'm using the microchip C32 compiler and the PIC32MX460F512L.

I would like to use capture pin 5 and Timer2 in 16bit mode. My understand after reading the documentation is that by setting the Capture mode to rising edge, it will throw an interrupt on each rising edge of the pin. Simultaneously it will copy the Timer2 register to the IC5BUF.

I used the following settings

OpenTimer2(T2_ON | T2_SOURCE_INT | T2_PS_1_256, 0x0000);

	IC5CONbits.ON = 0;			//Module off, will turn on at end
IC5CONbits.FEDGE = 1; 		//Capture on rising edge
IC5CONbits.C32 = 0;		//16 bit mode
IC5CONbits.ICTMR = 1;		//Use timer 2 
IC5CONbits.ICI = 0b00;		//Int on every capture event
IC5CONbits.ICM = 0b011;	//Simple Capture Event mode every rising edge
IC5CONbits.ON = 1;

 void __ISR(_INPUT_CAPTURE_5_VECTOR, ipl7) Capture(void)
 {
    	temp_int = IC5BUF;
        mIC5ClearIntFlag();         // clear this interrupt .
 } 

I then toggle a pin that is roughly 100ms long, and do a check to see if temp_int is in the right range, but it doesn't seem to be. As you can see i'm simply reading the 32bit register, is that somehow causing problems? Any help would be appreciated. Thanks.

Posted Jul 17, 2012, 5:23 PM UTC

65
Coach_Mercure•

I first want to say that I can be wrong, I never used that PIC in particular,

but from my understanding of the datasheet and your code I don't think you will obtain the results you are looking for. If you are looking for a value corresponding to 100ms, you won't get it. The value you will get at the rising edge of the signal is the value of the Timer 2 at that exact moment. The timer resets every time it gets to its maximum value so the value you will read during an interrupt will correspond to the "almost value" the timer 2 will be at.

You will need to either use a counter to sum all the resets of the timer 2 or you will need to control a bit more the timer 2 and say, try to determine the delay between 2 events.

2
uscEEOP•

From my understanding of the datasheet , this is exactly what the CCP module does. It handles the set and reset of the timer so that you get an accurate count of the signal pulse width. I could manually set a timer on a pin change, but that wouldn't seem necessary if I could get the CCP module to operate properly. Thanks for the info.

1
thepainteddoor•

When a rising edge is detected on your capture pin, the value of timer2 will be copied (let's say to a variable called CAPTURE_current). This is fine, unless the time between events is longer than the period of timer2. So, to be safe, every time Timer2 overflows, increment a counter.

Then, when you calculate your period you do it like this:

delta = (CAPTURE_current * (timer2_overflows * 65535)) - CAPTURE_last

period = delta * seconds_per_tick

CAPTURE_last = CAPTURE_current

Also, be careful when updating 16-bit variables that are changed by an interrupt. It is good procedure to disable interrupts while copying to prevent errors. Of course, I don't know about other PICs, I am talking about ones with 8-bit registers.

2
uscEEOP•

Ok I think that's what Coach_Mercure was saying. So it is actually more like a free running clock that it samples on the interrupt? That and the timing issues would make sense. I'll give the changes a try tonight and report back.

1
thepainteddoor•

Yup! You got it. Also, I forgot to mention you have to reset the overflow counter at the end of the Capture Interrupt Service Routine.

2