PIC18F4550 Timer Capture (CCP) mode


Input Capture is widely used in many applications such as:

  • Capturing the arrival time of an event
  • Measuring pulse width
  • Measuring period

An event can be represented by the rising and falling edges of a pulse.


Signal Event


The time of an event occurrence can be recorded by latching the count when an edge is detected (rising or falling). This can be done using input capture mode in the microcontrollers.

PIC18F4550 has an in-built CCP (Capture / Compare / PWM) module which has input capture mode. The input capture of the signal has applications like finding frequency, calculating the duty cycle of the input signal, etc. 

Let us see the capture mode in PIC microcontroller 18F4550.

PIC18F4550 has two CCP modules -  

  1. CCP1
  2. CCP2

Here, we will be discussing the CCP1 module.

In capture mode, the input pulse should be connected to CCP1 which is multiplexed with PORTC.2 (RC2) as shown below, and configure it as the input pin.


PIC18F4550 Capture Pins

PIC18F4550 Capture mode Pins
PIC18F4550 Capture mode Pins


CCP1 module is able to use only the following two timers

  1. Timer1
  2. Timer3


Working of Capture Mode

Now, how the capture mode works?

Capture Mode Block Diagram
Diagram of PIC Compare Mode
  • Timer1 or Timer3 are initialized to count the value in the capture operation.
  • T3CON register is used for selecting the Timer1 / Timer3 for input capture shown above.
  • When the rising or falling edge is detected at the CCP1 pin, the interrupt flag CCP1IF bit is set. It is cleared through software.
  • When an interrupt occurs, the value of the timer is copied into CCP register CCPR1 (CCPR1H and CCPR1L), and by looking at this value we are able to find the arrival time of that event.


Capture Mode (CCP) Registers

In PIC18F4550, different registers are used for capture mode.

1. CCPR1 Register is a 16-bit event capture register in which the event captured by timer1 or timer3 i.e. TMR1 or TMR3 register is copied. This is done by the hardware itself. CCPR1L register and CCPR1H register are the two 8-bit registers that are used for lower and higher byte storage, respectively.

CCPR1 Register
CCPR1 Register


2. CCP1CON Register: CCP Control Register

This is an 8-bit register used to select the capture mode. Let’s see the bit configuration of this register.

CCP1CON Register
CCP1CON Register

CCP1M3 : CCP1M0: CCP1 Mode Select bits

         0100 = Capture mode is selected for every falling edge detected.

         0101 = Capture mode is selected for every rising edge detected.

         0110 = Capture mode is selected for every 4th rising edge detected.

         0111 = Capture mode is selected for every 16th rising edge detected.

And the other combinations of these bits are used for Compare and PWM mode.

DCxB1 and DCxB0 are used for PWM mode only.

CCP1IF Interrupt Flag

  • After a capture event occurs, the interrupt flag is set.
  • This interrupt flag is CCP1IF (CCP interrupt flag) which is located in the PIR1 register. The PIR1 register is shown below.


PIR1 Register: Peripheral Interrupt Register

PIR1 Register
PIR1 Register


      1 = TMR1 or TMR3 register capture occurred (at falling or rising edge of pulse)

      0 = No TMR1 or TMR3 capture occurred.

We need to enable this (CCP1IF) flag by enabling the CCP1IE bit (CCP Interrupt enable bit) in the PIE1 register.


PIE1 Register: Peripheral Interrupt Enable

PIE1 Register
PIE1 Register


T3CON Register: Timer3 Control and Status Register

T3CON register is used for selecting a timer for the capture mode. This is shown below

T3CON Register
T3CON Register

T3CCP2: T3CCP1 (bit 6 and bit 3)

These two bits in combination are used for Timer and Capture mode selection.

      00 = Timer1 is the capture/compare clock source for both the CCP modules.

      01 = Timer3 is the capture / compare clock source for the CCP2,

               Timer1 is the capture / compare clock source for the CCP1

      1x = Timer3 is the capture / compare clock source for both the CCP modules.

RD16 :

This bit is used to specify that the Timer3 register is 16-bit (TMR3) or two 8-bit (TMR3H and TMR3L).

      RD16 = 1, Enable one 16-bit register.

      RD16 = 0, Enable two 8-bit registers.

The setting of this bit is required only when we select Timer3 for the capture mode.

Otherwise, RD16 in T1CON register is used for Timer1.


Steps for Programming Capture (CCP) Mode

Initialization of PIC18F4550 Capture mode

  1. Initialize the CCPCON1 register for capturing the rising or falling edge.
  2. Configure the CCP1 pin as an input pin.
  3. If you are using Timer3, then configure the T3CON register to select Timer3 for input capture; otherwise, Timer1 is a default.
  4. Also, set the value of the T1CON or T3CON register for deciding whether the timer register should be two 8-bit (TMRxL and TMRxH) or 16-bit (TMRx).
  5. Set CCPR1 and TMR3 / TMR1 register to 0.

Note: ’x’ is for 1 or 3.

CCP1CON = 0x05;	/* Capture mode is selected for detecting rising edge */
CCPR1 = 0x00;	/* Clear CCPR1 register for counting*/
T1CON = 0x80;	/* Enable 16-bit TMR1 register, no pre-scale,use internal clock, timer OFF */


Capture Operation

  1. Make timer ON.
  2. Monitor until CCP1IF flag==1, which is set when capture occurs.
  3. Copy the value of the CCPR1 register to any data variable and get a time of event occurrence.


Frequency Measurement using PIC18F4550 Code

Let’s design an application using PIC18F4550 in which we will measure the Frequency of the input signal and display it on 16x2 LCD. The input signal is connected to the CCP1 (RC2) pin for frequency measurement.

   Frequency Measurement using Input Capture Mode in PIC18F4550
#include <stdio.h>
#include <stdlib.h>
#include <p18f4550.h>
#include "osc_config.h"
#include "LCD_8bit_file.h"
#include <string.h>

#define f_timer 2000000

void main()
    unsigned long signal_period,data1,data2;
    unsigned long frequency_Hz[20];
    float Frequency;
    OSCCON=0x72;        /* set internal clock to 8MHz */
    CCP1CON=0x05;       /* Capture mode is selected for detecting Rising edge */
    CCPR1=0x00;         /*CCPR1 is capture count Register which is cleared initially*/
    T1CON=0x80;         /* Enable 16-bit TMR1 Register,No pre-scale,use internal clock,Timer OFF */
	TMR1ON=1; /* Turn-On Timer1 */	
        while(!(PIR1bits.CCP1IF));  /*Wait for Interrupt flag which is generated when edge is detected*/
        data1 = CCPR1;              /*Copy count of 1st edge detected*/        
        while(!(PIR1bits.CCP1IF));  /*Wait for Interrupt flag which is generated when edge is detected*/
        data2 = CCPR1;              /*Copy count of 2nd edge detected*/

        if(data1 < data2)

            /*Calculation for Frequency Measurement*/
            signal_period = data2 - data1;
            Frequency = ((float)f_timer / (float)signal_period); /*Count for 1 cycle*0.5us gives period */
            sprintf(frequency_Hz,"%.3f  ",Frequency); 



Components Used

LCD16x2 Display
LCD16x2 Display


PIC18F4550 Pulse Measurement Proteus Simulation Download
PIC18F4550 Pulse Measurement Project File Download