CCP Modules (Capture/Compare/PWM)

 

Previous Tutorial Previous Tutorial Tutorial 14 Next Tutorial Next Tutorial
CCP Modules | Capture/Compare/PWM
Introductory Level ★☆☆☆☆

 

In this tutorial, you’ll get to know what are the CCP modules in PIC Microcontrollers. Their modes of operation (Capture-Compare-PWM), what are the mechanics of operation for each mode, And how to develop the necessary firmware in order to drive the CCP module operation for each mode (Capture-Compare). We’ll postpone the PWM mode to the next tutorial. And Now, let’s get started!

[toc]


   Components Needed For This Tutorial   

 

Quantity Component Name
1 PIC16F877A
1 Breadboard
1 Jumper Wires Pack
4 330Ω Resistors
4 LED
2 Push Button
2 10kΩ Resistors
1 4MHz Crystal OSCillator
1 LM7805 Voltage Regulator
1 9v Battery or any Power Supply Source
1 PICkit3 (PIC Programmer)


   Introducing The CCP Module   

 

This is a multi-purpose module that we can switch between 3 different modes of operation. At each mode of operation, this module can perform a specific task that could be useful for many applications. The Microchip PIC16F877A Chip that we’re using has a couple of identical CCP modules CCP1 & CCP2. They’re actually identical in structure and operation. That’s why we’ll only discuss the CCP1 module and you can replicate everything to drive the CCP2 module if you wish.

 Features Of CCP Modules 

Each of the Capture/Compare/PWM (CCP) Modules contains a 16-bit register which can operate as a:

  • 16-Bit Capture Register
  • 16-Bit Compare Register
  • PWM Duty Cycle Register

The 16-Bit Data register For CCP modules is actually a couple of 8-Bit SFRs (CCPRxL-CCPRxH) where x maybe 0 or 1 for CCP1 & CCP2 modules.

 Modes Of Operation 

As we’ve mentioned earlier that each CCP module can operate in one of 3 possible modes. And here is a brief description for each of these modes

Capture: In Capture mode, the CCP module captures the 16-Bit value of Timer1 module in the CCPRx register upon a specific user-defined event. While the Timer1 module is running in either timer-mode or synchronized counter-mode.

Compare: In Compare mode, the 16-Bit value of the CCPRx register is constantly compared against the TMR1 register’s value until a match occurs. Then, the CCPx pin is driven high, low or not-changed as defined by the programmer (you and me).

PWM: In PWM mode, the Timer2 module is being used to produce a PWM output signal on the CCPx pins (RC2, RC3 respectively). We (as programmers) are in charge of setting the output frequency for the PWM signal as well as its duty cycle. The PWM signal is being used for motor speed control, LED dimming, solar chargers and much more as we’ll see in future tutorials.

 CCP Modules Timer Resources Required 

Both the CCP1 & CCP2 module require a hardware timer as a resource for their operation. The hardware timer module being used for both of CCP modules is determined based on the mode of operation. The table below indicates which timer module is being used for each mode.

 CCP Mode   Timer Resource 
Capture Timer1
Compare Timer1
PWM Timer2
Note

You must pay attention while using CCP modules that there is at least one timer module is running in timer/counter mode and it’s reserved by the CCP module. Any change to hardware timers will directly affect the operation of the respective CCP module, so please be careful!

 CCPxCON Register 

The operation of both CCP1 & CCP2 modules is controlled via the CCPxCON Registers which are a couple of 8-Bit SFRs (CCP1CON & CCP2CON) respectively. As we’re going to experiment with the CCP1 module, so we’ll have a look at the register which controls the operation of this module namely CCP1CON. (Datasheet page64)

CCP Module CCP1CON Register

From my own perspective, I can see that the PWM is the most important mode among these 3-modes for CCP modules. There are dozens of applications which are mainly dependent on PWM signals. That’s why we’ll briefly discuss the first two modes (Capture/Compare) in this tutorial. And we’ll only have a single practical LAB for each of them. In order to have much spare time to discuss the PWM mode in more depth. So now let’s get started with the first mode!

 


   Capture Mode   

 

In Capture Mode, the 16-Bit CCPR1 (CCPR1H:CCPR1L) register captures the 16-Bit value of the TMR1 register when an event occurs on the CCP1 pin (RC2). The event that fires a capture signal can be one of the following 4-options:

  • Every rising edge
  • Every falling edge
  • Every 4th rising edge
  • Every 16th rising edge

We (the programmers) choose which event is going to fire the capture signal. The type of event that fires the capture signal is configured by the 4-control bits (CCP1M3:CCP1M0) as shown in the CCP1CON register in the datasheet.

 Capture Mode Diagram 

Here is the logic (Block) diagram for the capture mode as found in the datasheet (8.1 page65)

CCP Module - Capture Mode Block Diagram

And here is another yet simpler way of representing the same diagram.

CCP Module Capture Mode Diagram

 CCP Operation In Capture Mode 

As you might have noticed in the above diagram, the operation of the CCP module in capture mode goes as follows. First, the timer module is set to operate in timer or counter mode and its register’s value (TMR1) starts incrementing. Second, the CCP module should be configured to operate in capture mode with a selectable trigger event. There are obviously 4-options that fire capture signal (e.g. every rising edge), let’s say every rising edge is selected via the CCP1CON register.

Now, upon each rising edge on the CCP1 pin (RC2). The 16-Bit value of the TMR1 will be copied to the 16-Bit CCPR1 register. This action fires an interrupt signal that is dedicated to the CCP1 module in general. We can actually use this to instantaneously handle CCP-Capture events.

In the following CaptureMode LAB, we’ll operate the Timer1 in counter mode. Then we’ll feed it with some external pulses then trigger the CCP1 pin (RC2) and PORT the CCPR1 register’s value to an io port in order to practically check the operation of this module.

 Notes For Capture Mode 

I- CCP Pin Configuration:

In Capture mode, the RC2/CCP1 pin should be configured as an input by setting the TRISC2 bit.  If the RC2/CCP1 pin is configured as an output, a write to the port can cause a Capture condition.

II- Timer1 Mode Selection:

Timer1 must be running in Timer mode, or Synchronized Counter mode, for the CCP module to use the capture feature. In Asynchronous Counter mode, the capture operation may not work.

III- Software Interrupt:

When the Capture mode is changed, a false capture interrupt may be generated. The user should keep bit CCP1IE clear to avoid false interrupts and should clear the flag bit, CCP1IF, following any such change in operating mode.

IV- CCP Prescaler Setting:

There are four prescaler settings, specified by bits CCP1M3:CCP1M0. Switching from one capture prescaler to another may generate an interrupt.

 Configuring CCP1 Module For Capture Mode 

  1. Set Timer1 module to operate in timer/counter mode.
  2. Turn ON Timer1 module
  3. Configure the CCP1 module to operate in Capture Mode (using CCP1CON register).
  4. Choose the event on which a capture occurs (using CCP1CON register – CCP1Mx Bits).
  5. Configure the CCP1 interrupt
  6. Write The ISR Handler for CCP-Capture Interrupt

 Implementing CCP1 Capture Mode Driver 

Step1 – Setup Timer1 For Timer or Counter Mode

[ For Timer Mode ]


[ For Counter Mode ]

Step2 – Turn ON Timer1

Step3,4 – Setup CCP1 For Capture Mode & Choose Event

Replace x’s with the proper bit-pattern for the capture mode with the event you wish to select.

Step5 – Configure The CCP1 Interrupt

Step6 – Write The ISR Handler For CCP-Capture Interrupt

 


   Compare Mode   

 

In Compare Mode, the 16-Bit CCPR1 (CCPR1H:CCPR1L) register is constantly compared against the TMR1 register. When a match occurs, The CCP1 pin (RC2) is:

  • Driven Low
  • Driven High
  • Remains Unchanged

We (the programmers) choose which event is going to happen on the CCP1/RC2 pin. The action on the CCP1/RC2 pin is controlled by the 4-control bits (CCP1M3:CCP1M0) as shown in the CCP1CON register in the datasheet.

 Compare Mode Diagram 

Here is the logic (Block) diagram for the compare mode as found in the datasheet (8.2 page66)

CCP Module - Compare Mode Block Diagram

And here is another yet simpler way of the same diagram.

CCP Module Compare Mode Diagram

 CCP Operation In Compare Mode 

As you might have noticed in the above diagram, the operation of the CCP module in compare mode goes as follows. First, the CCPR1 register is loaded by a value at which we want the Timer1 to stop counting. Second, the Timer1 module is set to operate in timer or counter mode and its register’s value (TMR1) starts incrementing. Third, the CCP module should be configured to operate in compare mode with a selectable RC2/CCP1 pin event. There are obviously 3-options for the RC2/CCP1 pin event, let’s say Driven-High is the selected event and it’s easily done via the CCP1CON register.

Now, the Timer1 module is running either in timer/counter mode. When a match occurs, the RC2/CCP1 pin is Driven-High, the timer module is cleared to be zero once again. Moreover, this action also fires an interrupt signal that is dedicated to the CCP1 module. We can actually use this interrupt signal to instantaneously handle CCP-Capture events.

In the following CompareMode LAB, we’ll operate the Timer1 in timer mode. Then we’ll pre-load a specific value to the CCPR1 register to generate a 0.5s time delay for an LED toggle effect.

 Notes For Compare Mode 

I- CCP Pin Configuration:

The user must configure the RC2/CCP1 pin as an output by clearing the TRISC2 bit.  Clearing the CCP1CON register will force the RC2/CCP1 compare output latch to the default low level. This is not the PORTC I/O data latch.

II- Timer1 mode selection:

Timer1 must be running in Timer mode, or Synchronized Counter mode, if the CCP module is using the compare feature. In Asynchronous Counter mode, the compare operation may not work.

III- Software Interrupt Mode:

When Generate Software Interrupt mode is chosen, the CCP1 pin is not affected. The CCPIF bit is set, causing a CCP interrupt (if enabled).

IV- Special Event Trigger:

In this mode, an internal hardware trigger is generated which may be used to initiate an action. The special event trigger output of CCP1 resets the TMR1 register pair. This allows the CCPR1 register to effectively be a 16-bit programmable period register for Timer1. The special event trigger output of CCP2 resets the TMR1 register pair and starts an A/D conversion (if the A/D module is enabled).

 Configuring CCP1 Module For Compare Mode 

  1. Set Timer1 module to operate in timer or counter mode.
  2. Turn ON Timer1 module
  3. Preload The CCPR1 Register with the desired value (from calculations)
  4. Configure the CCP1 module to operate in Compare Mode (using CCP1CON register).
  5. Choose the event on the RC2 pin when a match occurs (using CCP1CON register – CCP1Mx Bits).
  6. Configure the CCP1 interrupt
  7. Write The ISR Handler for CCP-Capture Interrupt

 Implementing CCP1 Compare Mode Driver 

Step1 – Setup Timer1 For Timer or Counter Mode

[ For Timer Mode ]


[ For Counter Mode ]

Step2 – Turn ON Timer1

Step3 – Preload The CCPR1 Register

Where N is the value that we get from the calculations which will be discussed hereafter in the CompareMode LAB in this tutorial.

Step4,5 – Setup CCP1 For Compare Mode & Choose Event

Replace x‘s with the proper bit-pattern for the compare mode with the event you wish to select.

Step6 – Configure The CCP1 Interrupt

Step7 – Write The ISR Handler For CCP-Compare Interrupt

 


   CCP1 In Capture Mode – LAB   

 

Lab Name CCP CaptureMode
Lab Number 11
Lab Level Introductory
Lab Objectives Learn how to use the CCP module in CaptureMode. Run the Timer1 module in synchronized counter mode and increment its value with an external push button input pulses. When the RC2/CCP1 pin is driven-high (Rising edge), the TMR1 counts should be PORTed out to an IO port hooked to some LEDs.

 

       1. Coding       

 

Open the MPLAB IDE and create a new project name it “CCP-CaptureMode”. If you have some issues doing so, you can always refer to the previous tutorial using the link below.

timer-preloading

Set the configuration bits to match the generic setting which we’ve stated earlier. And if you also find troubles creating this file, you can always refer to the previous tutorial using the link below.

timer-preloading

Now, open the main.c file and let’s start developing the firmware for our project.

Our objective is to set the Timer1 to operate in the synchronized counter mode so as to get incremented externally via a push button. The CCP1 module should be configured to operate in CaptureMode with rising edge triggered event. When the RC2/CCP1 pin is driven high, the ISR handler should PORT-Out the CCPR1L register to an IO port such as PORTB.

The typical steps for configuring the CCP1 module to operate in CaptureMode have been already discussed earlier in this tutorial. And here is the full code listing for this LAB

And that’s it. Hit the compile button! and let’s do some testing!

 

       2. Simulation       

 

To simulate this project, you should create a schematic diagram like the one shown below in your simulation environment.

CCP Capture Mode Schematic

Here are the simulation results in case you’re curious about it. As there is no prototyping on real-board kind of video.

Play Video On YouTube
will be added soon…

 


   CCP1 In Compare Mode – LAB   

 

Lab Name CCP-CompareMode
Lab Number 12
Lab Level Intermediate
Lab Objectives Learn how to use the CCP module in compare mode in order to generate accurate time intervals utilizing the Timer1 hardware as a resource. We’ll generate a 0.5s time interval to blink an LED in this LAB.

 

       1. Coding       

 

Open the MPLAB IDE and create a new project name it “CCP-CompareMode”. If you have some issues doing so, you can always refer to the previous tutorial using the link below.

timer-preloading

Set the configuration bits to match the generic setting which we’ve stated earlier. And if you also find troubles creating this file, you can always refer to the previous tutorial using the link below.

timer-preloading

Now, open the main.c file and let’s start developing the firmware for our project.

Our first task is to compute the number of Timer1 ticks that are required to complete a 0.5s timer interval. We’ll use the following formula.

CCP Modules - CompareMode

Substituting for Fosc = 4MHz, Prescaler = 1:1, Tout = 0.5sec, and solving for Number of Ticks. The result will be as follows

Ticks = 500000

What?! We all know that TMR1 is capped at 65535 ticks, it’s the maximum value for a 16-Bit timer module. That’s why we’ll be in need to generate multiple match events in order to reach the 0.5s time period we wish. Consequently, we’ll plug-in an additional parameter to our equation to be more general as shown below

CCP Compare Mode

Now, let (X=10) you’ll get (Ticks = 50000) which is reasonable indeed. And that is the value which we’ll load into the CCPR1 register. And at which we’ll be triggering the compare event interrupt to flip (Toggle) the LED. The full code listing for this LAB is shown below.

And that’s it. Cross Your Fingers! Hit the compile button! and let’s do some testing!

 

       2. Simulation       

 

To simulate this project, you should create a schematic diagram like the one shown below in your simulation environment.

CCP Compare Mode Schematic

Here are the simulation results in case you’re curious about it. As there is no prototyping on real-board kind of video for this LAB.

CCP Compare Simulation

 


   Concluding Remarks   

 

  1  

With compare mode, we can now fire a Timer1 interrupt signal at any instance. Meaning that we no more need to wait for 65535 ticks until the timer overflows to generate an interrupt. We can now preload any value we want to the CCPR1 register and run the Timer1 module counting from 0 up-to CCPR1 value at which a match event occurs firing a CCP-Interrupt signal. Moreover, it also clears the TMR1 register-pair. The general equation we use for this process is shown below

CCP Compare Mode

Where X is the number of matching interrupts. As you know, for large time intervals (Tout) it’ll require an insanely large amount of Ticks. Which must never exceed 65535 in your calculations, that’s why you should seek for another value for X in these situations.

  2  

You can set Timer1 to operate in timer mode and utilize the CCP module in capture mode in order to calculate an input wave pulse-width. By starting and stopping the timer on the edges. You must be very careful with this as you might need to flip the CCP mode in the ISR which is a little bit tricky business.

You can set Timer1 to operate in the counter mode and utilize the CCP module in compare mode in order to accept a specific number of external input pulses. You can easily set the threshold by writing to the CCPRx register-pair.

There are many ways in which you can use both capture and compare mode of CCP Modules. Try out the LABs shown above in this tutorial, and then play around to get more familiar with the stuff discussed earlier.

 

 

In the next tutorial, we’ll be discussing the PWM Mode. How it works and how to generate PWM signals to control the Brightness of an LED or the speed of a DC Motor or whatever. So let’s move forward!

 

Previous Tutorial Previous Tutorial Tutorial 14 Next Tutorial Next Tutorial
Share This Page With Your Network!
Join Our +25,000 Newsletter Subscribers!

Stay Updated With All New Content Releases. You Also Get Occasional FREE Coupon Codes For Courses & Other Stuff!

Photo of author
Author
Khaled Magdy
Embedded systems engineer with several years of experience in embedded software and hardware design. I work as an embedded SW engineer in the Automotive & e-Mobility industry. However, I still do Hardware design and SW development for DSP, Control Systems, Robotics, AI/ML, and other fields I'm passionate about.
I love reading, writing, creating projects, and teaching. A reader by day and a writer by night, it's my lifestyle. I believe that the combination of brilliant minds, bold ideas, and a complete disregard for what is possible, can and will change the world! I will be there when it happens, will you?

4 thoughts on “CCP Modules (Capture/Compare/PWM)”

  1. Hello Khaled Magdy,
    Would you be able to do the same tutorial making use of the MCC generated macros for the CCP peripheral? I would love to see how they correlate and possibly make things easier. I am using a PIC16F18446 nano development board and I am trying to see how everything works in a simple manner.

    Reply
    • Greetings Carl,
      And thanks for the suggestion. I’ll consider creating a couple of tutorials specifically for using the MCC.

      Reply
  2. hi in CCB- CaptureMode pgrm: I’m using PIC16F877A MC 20MHZ oscillator. I have chosen the X=50, as per calculations to achive 0.5 sec to toggle RC4 pin. I have checked with Oscilloscope ti’s toggling every 0.1 sec instead of 0.5 sec.

    I don’t understand really why it’s happening.

    Reply
  3. Hey Khaled,
    1. I tried your code written in the example of compare mode in PIC18F87J10 but unable to create the waveform as you generated it. Even the register I selected is same as yours.
    2. Actually, I am trying to generate a waveform of 150Hz and 200uS Pulse width using ISR, but unable to do so. So, can you please guide me on this problem.

    Reply

Leave a Comment