1.3.3 CCP
Modules | Limit High | Resolution |
---|---|---|
CCP1 | 16.38 ms | 250 ns |
Timer3 |
The Capture/Compare/PWM (CCP) module provides an accurate hardware and software method to measure the width of a pulse. The presented method requires the waveform to be periodic since a period measurement is taken.
OVERVIEW
The CCP can be set up to capture both a rising and falling edge of a waveform. A timer count value is captured when the CCP receives an event condition. An event is defined as one of the following:
- Every falling edge
- Every rising edge
- Every 4th rising edge
- Every 16th rising edge
An event on every 4th or 16th rising edge is typically used to calculate the period of a signal, as seen in Figure 1.
Timer1 is used on the PIC16 devices with Timer3 being another option on the PIC18 devices.
When a capture is made, the timer value will be latched to the CCPRxL:H
registers. As seen in Figure 1, a pulse width is defined as the time between a rising and falling edge.
Since a pulse measurement requires both a rising and falling edge, the CCP module needs
software intervention to capture both events.
Ideally, the pulse being measured is many times wider than the setup time required by the CCP module to switch between capturing the rising and falling edges. Often times, the pulse is much less than the required instruction clocks it takes to make the switch. Due to this limitation, a wiser method is to also take a period measurement. If the pulse measurement is greater than the period measurement, then subtract the period measurement from the pulse measurement until the result is less than the period.
The pulse measurement requires a period measurement as well, as seen in Figure 2.
The period can be measured by setting the CCP to capture on every 16th rising edge provided that 16 periods are less than 65536 Timer1 clock periods. If that is the case then select one event or four events as the Capture mode. Make two captures and calculate the difference by subtracting the first value from the second value. Divide the result by 16 (four right shifts without extending the sign) to determine the period. It does not matter if the second capture value is less than the first when calculating the difference.
Code Snippet for Calculating A single Pulse Width in ‘Extracting the Pulse from Period Plus Pulse Capture’ figure above
// The pulse width may have been measured over the length // of more than one period, so subtract the period // out until the pulse width is less than the period. while(MeasuredPulse > Period) MeasuredPulse -= Period;
SETUP
Steps to measure the period:
- Configure CCPXCON<3:0> to capture every 16th rising edge
- Configure Timer1 prescaler for the lowest setting without overflowing on the 16th rising edge
- Enable the CCP module and timer
- Wait until the 16th rising edge
- Disable CCP module and save CCPRX in a
temporary variable (
value1
) - Enable the CCP module
- Wait for 16 edges
- Disable CCP module and timer
- The period is now
Period_16 = CCPR1 - value1 Period = Period_16 >> 4
CCP Period Operation Code
Operation Code CCP1CON<3:0> = 0b0111; // or '0b0110' for every 4th rising edge (Step 1) // Configure Timer1 prescaler - (Step 2) CCP1CONbits.EN = 1; // (Step 3) T1CONbits.TMR1ON = 1; // (Step 3) while(!PIR2bits.CCP1IF); // (Step 4) CCP1CONbits.EN = 0; // (Step 5) value1 = CCP1_CaptureRead(); // same as "(CCPR1H << 8) + CCPR1L)" (Step 5) PIR2bits.CCP1IF = 0; // Clear Flag, (Step 5) CCP1CONbits.EN = 1; // (Step 6) while(!PIR2bits.CCP1IF); // (Step 7) CCP1CONbits.EN = 0; // (Step 8) T1CONbits.TMR1ON = 0; // (Step 8)
Steps to measure the pulse:
- Configure CCPXCON<3:0> to capture every rising edge
- Configure Timer1 prescaler for the lowest setting without overflowing before period
- Enable the CCP module and timer
- Wait for a rising edge
- Disable CCP module and save CCPRX in a
temporary variable (
value2
) - Configure CCPXCON<3:0> to capture every falling edge
- Enable CCP module
- Wait for a falling edge
- Disable CCP module and timer
- The pulse width is
now:
MeasuredPulse = CCPRX - value2 while(MeasuredPulse > Period) MeasuredPulse -= Period;
CCP Pulse Operation Code
CCP1CON<3:0> = 0b0101; // (Step 1) // Configure Timer1 Prescaler - (Step 2) CCP1CONbits.EN = 1; // (Step 3) T1CONbits.TMR1ON = 1; // (Step 3) while(!PIR2bits.CCP1IF); // (Step 4) CCP1CONbits.EN = 0; // (Step 5) value2 = CCP1_CaptureRead(); // same as "(CCPR1H << 8) + CCPR1L)" (Step 5) PIR2bits.CCP1IF = 0; // Clear Flag, (Step 5) CCP1CON<3:0> = 0b0100; // (Step 6) CCP1CONbits.EN = 1; // (Step 7) while(!PIR2bits.CCP1IF); // (Step 7) CCP1CONbits.EN = 0; // (Step 8) T1CONbits.TMR1ON = 0; // (Step 8)
LIMITATIONS
The resolution of this measurement is a function of the PIC MCU instruction clock. The period of the waveform of interest must be at least two times the width of the instruction clock period. This is because the CCP module detection is synchronized to the clock and must register each rising and falling edge.