3.7 CCP Modules
CCP modules can be set to operate in many different modes, which makes them the most complicated peripherals to deal with. Just try to analyze their operation using the tables describing bit functions and you will understand what we are talking about. So, when you use one of the CCP modules, first select the mode you need, analyze the appropriate figure, then change the bits of the registers. Or else...
The CCP module (
Capture/Compare/PWM) is a peripheral which allows the user to time and control different events. As its name suggests, it can be set to operate in three different modes:
Capture Mode provides an access to the current state of a register which constantly changes its value. In this case, it is the timer register TMR1.
Compare Mode constantly compares values of two registers. One of them is the timer register TMR1.
PWM (
Pulse Width Modulation) can generate signals of varying frequency and duty cycle on one or more output pins.
There are two CCP modules integrated into the PIC16F887 microcontroller - CCP1 and CCP2. They are almost identical in operation with difference in enhanced PWM features available on the CCP1 module only. This chapter gives a detailed description of this module. As for the CCP2 module, only the features distinguishing it from CCP1 will be covered.
CCP1 MODULE
The heart of the CCP1 module is a 16-bit register CCPR1 which consists of two registers CCPR1L and CCPR1H. It is used for capturing binary numbers from the timer register TMR1 (TMR1H and TMR1L) or comparing binary numbers stored in registers CCPR1 and TMR1.
If enabled by software, the timer register TMR1 reset may occur on any match in the compare mode. Besides, the CCP1 module is capable of generating PWM signals of varying frequency and duty cycle.
Bits of the CCP1CON register are in control of the CCP1 module.
CCP1 IN CAPTURE MODE
In this mode, the CCP1 register (consisting of the CCPR1H and CCPR1L register pair) captures a 16-bit value from the timer register TMR1 (consisting of the TMR1H and TMR1L register pair) when one of the following events occurs on the RC2/CCP1 pin:
- Every falling edge (1 -> 0);
- Every rising edge (0 -> 1);
- Every 4th rising edge (0 -> 1); and
- Every 16th rising edge (0 -> 1).
Which of these events will cause a 16-bit data to be captured depends on the combination of four bits (CCP1M3, CCP1M2, CCP1M1 and CCP1M0) of the control register. In addition, the following conditions must be met:
- The RC2/CCP1 pin must be configured as an input; and
- The Timer1 module must operate as a timer or a synchronous counter.
The CCP1IF flag bit is set when capture is made. If the CCP1IE bit of the PIE1 register is set when it happens, an interrupt occurs.
When the CCP1 module exits the capture mode, an unwanted capture interrupt may be generated. In order to prevent this, both the bit enabling the CCP1IE interrupt and the CCP1IF flag bit should be cleared prior to making any change in the CCP1CON control register.
An unwanted interrupt may also be generated when switching from one prescaler rate to another. To prevent this, the CCP1 module should be temporarily switched off prior to changing the prescaler rate. It is advisable to use the following program sequence written in assembly language:
BANKESEL CCP1CON
CLRF CCP1CON 'CONTROL REGISTER IS CLEARED
'CCP1 MODULE IS OFF
MOVLW XX 'NEW PRESCALER MODE IS SELECTED
MOVWF CCP1CON 'NEW VALUE IS LOADED INTO THE CONTROL REGISTER
'CCP1 MODULE IS SIMULTANEOUSLY SWITCHED ON
Let's do it in mikroBasic...
...
asm
BANKESEL CCP1CON
CLRF CCP1CON ' CONTROL REGISTER IS CLEARED
' CCP1 MODULE IS OFF
MOVLW XX ' NEW PRESCALER MODE IS SELECTED
MOVWF CCP1CON ' NEW VALUE IS LOADED INTO THE CONTROL REGISTER
' CCP1 MODULE IS SIMULTANEOUSLY SWITCHED ON
end asm
...
CCP1 IN COMPARE MODE
In this mode, the value stored in the CCP1 register is constantly compared to the value stored in the TMR1 timer register. When a match occurs, the logic state of the RC2/CCP1 output pin may be changed, which depends on the state of bits in the control register (CCP1M3 - CCP1M0). The CCP1IF flag bit will be simultaneously set.
To set the CCP1 module to operate in the compare mode, two conditions must be met:
- The RC2/CCP1 pin must be configured as an output; and
- Timer1 must be synchronized with internal clock.
CCP1 IN PWM MODE
Pulse sequences with varying pulse frequency and duty cycle have a wide range of application in automation. A typical example is a power control unit. Refer to figure below. If a logic zero (0) indicates a switch-off state and a logic one (1) indicates a switchon state, electrical power to feed a consumer with will be directly proportional to the pulse duration. This ratio is called
Duty Cycle.
Another example, also common in practice, is the use of PWM signals in signal generating units to produce signals of arbitrary waveforms such as sinusoidal waveform. See figure below:
Devices which operate using PWM signals are commonly used in practice as adjustable frequency drivers controlling the operation of electric motors (speed, acceleration, deceleration etc.).
Figure above shows a block diagram of the CCP1 module set to PWM mode. In order to generate a pulse of arbitrary duty cycle on its output pin, it is necessary to set pulse period (frequency) and pulse duration first.
PWM PERIOD
The PWM output pulse period (T) depends on the value stored in the PR2 register of the Timer2. It is calculated by means of the following equation:
PWM Period = (PR2 +1) * 4Tosc * TMR2 Prescale Value
If the PWM period (T) is known, it is easy to calculate signal frequency (F) because these two values are related by equation F=1/T.
PWM PULSE WIDTH
The PWM pulse width is determined by means of 10 bits in total: all bits (eight in total) of the CCPR1L register as MSbs and two bits of the CCP1CON register as LSbs (DC1B1 and DC1B0). The result is a 10-bit number contained in the formula:
Pulse Width = (CCPR1L,DC1B1,DC1B0) * Tosc * TMR2 Prescale Value
The following table shows how to generate PWM signals of varying frequency if the microcontroller uses a 20 MHz quartz-crystal (Tosc=50nS).
FREQUENCY [KHZ] |
1.22 |
4.88 |
19.53 |
78.12 |
156.3 |
208.3 |
TMR2 Prescaler |
16 |
4 |
1 |
1 |
1 |
1 |
PR2 Register |
FFh |
FFh |
FFh |
3Fh |
1Fh |
17h |
Just two more things:
- The output pin will be constantly set if the pulse width is by negligence set to be larger than PWM period.
- In this case, the Timer2 postscaler cannot be used for generating long PWM periods.
PWM SIGNAL RESOLUTION
A PWM signal is nothing more than a pulse sequence with varying duty cycle. For one specific frequency (number of pulses per second), there is a limited number of duty cycle combinations. Resolution is a maximum number of duty cycle combinations measured in bits. For example, a 10-bit resolution will result in 1024 discrete duty cycles, whereas an 8-bit resolution will result in 256 discrete duty cycles etc. As for this microcontroller, the resolution depends on the contents of the PR2 register. The maximum resolution is obtained by writing number FFh to this register.
PWM signals' frequences and resolutions (Fosc = 20MHz):
PWM FREQUENCY |
1.22KHZ |
4.88KHZ |
19.53KHZ |
78.12KHZ |
156.3KHZ |
208.3KHZ |
Timer Prescale |
16 |
4 |
1 |
1 |
1 |
1 |
PR2 Value |
FFh |
FFh |
FFh |
3Fh |
1Fh |
17h |
Maximum Resolution |
10 |
10 |
10 |
8 |
7 |
6 |
PWM signals' frequences and resolutions (Fosc = 8MHz):
PWM FREQUENCY |
1.22KHZ |
4.90KHZ |
19.61KHZ |
76.92KHZ |
153.85KHZ |
200.0KHZ |
Timer Prescale |
16 |
4 |
1 |
1 |
1 |
1 |
PR2 Value |
65h |
65h |
65h |
19h |
0Ch |
09h |
Maximum Resolution |
8 |
8 |
8 |
6 |
5 |
5 |
Let's do it in mikroBasic...
' In this example, PWM module is initialized and set to give a pulse train of 50% duty-
' cycle. Functions PWM1_Init(), PWM1_Start() and PWM1_Set_Duty() are used for this
' purpose. All of them are already contained in the mikroBasic PRO for PIC PWM library
' and just need to be copied to the program.
dim duty_c as byte ' Define variable duty_c
...
sub procedure InitMain()
ANSEL,ANSELH = 0 ' All I/O pins are configured as digital
PORTC,TRISC = 0 ' Initial state of port C output pins
PWM1_Init(5000) ' PWM module initialization (5KHz)
end sub
main:
InitMain()
duty_c = 127 ' Initial value of duty-cycle
PWM1_Start ' Start PWM1 module
PWM1_Set_Duty(duty_c) ' Set PWM duty-cycle to 50%
...
...
CCP1CON Register
P1M1, P1M0 - PWM Output Configuration bits - The P1A pin is always configured as an input in the capture/compare mode. Pins P1B, P1C and P1D act as port PORTD input/output pins.
P1M1 |
P1M0 |
MODE |
0 |
0 |
PWM with single output |
Pin P1A outputs modulated signal.
Pins P1B, P1C and P1D are port D input/output |
0 |
1 |
Full Bridge - Forward configuration |
Pin P1D outputs modulated signal
Pin P1A is active
Pins P1B and P1C are inactive |
1 |
0 |
Half Bridge configuration |
Pins P1A and P1B output modulated signal
PinsP1C and P1D are port D inputs/outputs |
1 |
1 |
Full Bridge - Reverse configuration |
Pin P1B outputs modulated signal
Pin P1C is active
Pins P1A and P1D are inactive |
DC1B1, DC1B0 - PWM Duty Cycle Least Significant bits - are only used in the PWM mode in which they represent two least significant bits of a 10-bit number. This number is used to determine duty cycle of a PWM signal. The rest of bits (8 in total) are stored in the CCPR1L register.
CCP1M3 - CCP1M0 bits - are used for selecting the operating mode of the CCP1 modul.
CCP1M3 |
CCP1M2 |
CCP1M1 |
CCP1M0 |
MODE |
0 |
0 |
0 |
0 |
Module is disabled (reset) |
0 |
0 |
0 |
1 |
Unused |
0 |
0 |
1 |
0 |
Compare mode |
CCP1IF bit is set on match |
0 |
0 |
1 |
1 |
Unused |
0 |
1 |
0 |
0 |
Capture mode |
Every falling edge on the CCP1 pin |
0 |
1 |
0 |
1 |
Capture mode |
Every rising edge on the CCP1 pin |
0 |
1 |
1 |
0 |
Capture mode |
Every 4th rising edge on the CCP1 pin |
0 |
1 |
1 |
1 |
Capture mode |
Every 16th rising edge on the CCP1 pin |
1 |
0 |
0 |
0 |
Compare mode |
Output and CCP1IF bit are set on match |
1 |
0 |
0 |
1 |
Compare mode |
Output is cleared and CCP1IF bit is set on match |
1 |
0 |
1 |
0 |
Compare mode |
Interrupt request arrives and bit CCP1IF is set on match |
1 |
0 |
1 |
1 |
Compare mode |
Bit CCP1IF is set and timers 1 or 2 registers are cleared |
1 |
1 |
0 |
0 |
PWM mode |
Pins P1A and P1C are active-high
Pins P1B and P1D are active-high |
1 |
1 |
0 |
1 |
PWM mode |
Pins P1A and P1C are active-high
Pins P1B and P1D are active-low |
1 |
1 |
1 |
0 |
PWM mode |
Pins P1A and P1C are active-low
Pins P1B and P1D are active-high |
1 |
1 |
1 |
1 |
PWM mode |
Pins P1A and P1C are active-low
Pins P1B and P1D are active-low |
CCP2 MODULE
Regardless of different names of registers and bits in modules CCP1 and CCP2, the CCP2 module represents a true copy of the CCP1 module set to operate in normal mode (capture and compare). There is only one thing that makes the CCP2 different when it operates in the compare mode.
It is the Timer1 reset signal. Namely, if the A/D converter is enabled, at the moment the values of registers TMR1 and CCPR2 match, the Timer1 reset signal will automatically start the process of A/D conversion.
The CCP2 module is also under control of the control register bits. This time, it is the CCP2CON register.
CCP2CON Register
DC2B1, DC2B0 - PWM Duty Cycle Least Significant bits - are only used in the PWM mode in which they represent two least significant bits of a 10-bit number. This number is used to determine duty cycle of a PWM signal. The rest of bits (8 in total) are stored in the CCPR2L register.
CCP2M3 - CCP2M0 bits - are used for selecting the operating mode of the CCP2 module.
CCP2M3 |
CCP2M2 |
CCP2M1 |
CCP2M0 |
MODE |
0 |
0 |
0 |
0 |
Module is disabled (reset) |
0 |
0 |
0 |
1 |
Unused |
0 |
0 |
1 |
0 |
Unused |
0 |
0 |
1 |
1 |
Unused |
0 |
1 |
0 |
0 |
Capture mode |
Every falling edge on the CCP2 pin |
0 |
1 |
0 |
1 |
Capture mode |
Every raising edge on the CCP2 pin |
0 |
1 |
1 |
0 |
Capture mode |
Every 4th rising edge on the CCP2 pin |
0 |
1 |
1 |
1 |
Capture mode |
Every 16th rising edge on the CCP2 pin |
1 |
0 |
0 |
0 |
Compare mode |
Output and CCP2IF bit are set on match |
1 |
0 |
0 |
1 |
Compare mode |
Output is cleared and CCP2IF bit is set on match |
1 |
0 |
1 |
0 |
Compare mode |
Interrupt is generated, CCP2IF bit is set and CCP2 pin is unaffected on match |
1 |
0 |
1 |
1 |
Compare mode |
On mach, CCP2IF bit is set, Timer 1 registers are cleared and A/D conversion starts if A/D converter is enabled. |
1 |
1 |
x |
x |
PWM mode |
In Short
Setting CCP1 module to PWM mode
In order to set the CCP1 module to operate in the PWM mode, the following steps should be taken:
- Disable the CCP1 output pin (configure it as an input).
- Set the PWM period by writing a value to the PR2 register.
- Set the CCP1 module to operate in the PWM mode by combining bits of the CCP1CON register.
- Set duty cycle of the PWM signal by writing a value to the CCPR1L register and using bits DC1B1 and DC1B0 of the CCP1CON register.
- Configure and start Timer2:
- Clear the TMR2IF interrupt flag of the PIR1 register.
- Set the Timer2 prescale value using bits T2CKPS1 and T2CKPS0 of the T2CON register.
- Run the Timer2 by setting the TMR2ON bit of the T2CON register.
- Enable PWM output pins after one PWM cycle has been completed:
- Wait for the Timer2 overflow (the TMR2IF bit of the PIR1register is set).
- Configure the appropriate pin as an output by clearing a bit of the TRIS register.
CCP1 IN ENHANCED MODE
The enhanced mode is available on the CCP1 module only. The CCP1 set to operate in the enhanced mode basically doesn’t differ from the CCP1 in normal mode. The enhancement actually refers to the transmission of PWM signals to the output pins. It is an important detail because microcontrollers are increasingly used in electric motor control systems. These devices are not described herein, but if you ever have had a chance to work with similar devices, you will recognize some units which, until quite recently, were used as independent additional modules. Today they are integrated into microcontrollers and can operate in several different modes.
SINGLE OUTPUT PWM MODE
A single output PWM mode is enabled only when bits P1M1 and P1M0 of the CCP1CON register are cleared. In this case, one PWM signal can be available on up to four different output pins at the same time. Besides, the PWM signal may appear either in basic or inverted waveform. Signal distribution depends on bits of the PSTRCON register, while its polarity depends on the CCP1M1 and CCP1M0 bits of the CCP1CON register.
If an inverted output is used, pins are low-active, and pulses with the same waveform are always generated in pairs: on the P1A and P1C pins and P1B and P1D pins, respectively.
HALF-BRIDGE MODE
In the half-bridge mode, the P1A pin is fed with a PWM signal, while the P1B pin is at the same time fed with the complementary PWM signal. These pulses drive MOSFET transistors in the Half-Bridge configuration, which enable/disable current to pass through the load.
Do not switch on both MOSFET transistors simultaneously as the short circuit that may be caused thereby will be fatal. In order to avoid this, it is necessary to wait a while between switching drivers on and off. Such a time delay, marked as ‘td’ in figure below, is provided by means of bits PDC0-PDC6 of the PWM1CON register.
As can be seen in figure below, the half-bridge mode can also be used to drive MOSFET transistors in the Full Bridge configuration:
FULL-BRIDGE MODE
All four pins are configured as outputs in the full-bridge mode. In practice, this operating mode is commonly used for running motors as it provides a simple and full control of speed and rotation direction. There are two configurations of this mode: Full Bridge- Forward and Full Bridge-Reverse.
FULL BRIDGE - FORWARD CONFIGURATION
In the Full-Bridge Forward configuration the following occurs:
- A logic one (1) appears on the P1A pin (pin is active-high);
- Pulse sequence appears on the P1D pin; and
- A logic zero (0) appears on the P1B and P1C pins (pins are active-low).
Figure below shows the state of the P1A-P1D pins during one full PWM cycle.
FULL BRIDGE - REVERSE CONFIGURATION
The Full-Bridge Reverse configuration is similar to the above-mentioned configuration, only that pins have different functions:
- A logic one (1) appears on the P1C pin (pin is active-high);
- Pulse sequence appears on the P1B pin; and
- A logic zero (0) appears on the P1A and P1D pins (pins are active-low).
PWM1CON Register
PRSEN PWM Restart Enable bit
- 1 - Upon auto-shutdown, the PWM module automatically restarts, while the ECCPASE bit of the ECCPAS register is cleared.
- 0 - In order to restart PWM module upon auto-shutdown, the ECCPASE bit must be cleared from within the software.
PDC6 - PDC0 PWM Delay Count bits - A 7-digit binary number determines the number of instruction cycles (4*Tosc) used as a time delay during the activation of PWM output pins.
PSTRCON Register
STRSYNC - Steering Sync bit sets the time of PWM pulse redirecting:
- 1 - Redirecting occurs after modifying the PSTRCON register, but not until the PWM waveform is complete.
- 0 - Redirecting occurs after modifying the PSTRCON register. The PWM signal on the output pin is immediately changed with no regard to whether the previous cycle is complete or not. Such redirecting is used when a PWM signal has to be immediatley removed from the pin.
STRD - Steering Enable bit D determines the P1D pin function.
- 1 - The P1D pin is fed with a PWM signal the polarity of which is controlled by the CCP1M0 and CCP1M1 bits.
- 0 - Pin is configured as a general port PORTD input/output.
STRC Steering Enable bit C determines the P1C pin function.
- 1 - The P1C pin is fed with a PWM signal the polarity of which is controlled by the CCP1M0 and CCP1M1 bits.
- 0 - Pin is configured as a general port PORTD input/output.
STRB - Steering Enable bit B determines the P1B pin function.
- 1 - The P1B pin is fed with the PWM signal the polarity of which is controlled by the CCP1M0 and CCP1M1 bits.
- 0 - Pin is configured as a general port PORTD input/output.
STRA - Steering Enable bit A determines the P1A pin function.
- 1 - The P1A pin is fed with the PWM signal the polarity of which is controlled by the CCP1M0 and CCP1M1 bits.
- 0 - Pin is configured as a general port PORTC input/output.
ECCPAS Register
ECCPASE - ECCP Auto-Shutdown Event Status bit indicates whether the shutdown state of the CCP module has occurred:
- 1 - CCP module is in the Shutdown state.
- 0 - CCP module operates normally.
ECCPAS2 - ECCPAS0 - ECCP Auto-Shutdown Source Select bits are used to select the auto shut-down state source:
ECCPAS2 |
ECCPAS1 |
ECCPAS0 |
SHUTHOWN STATE SOURCE |
0 |
0 |
0 |
Shutdown state disabled |
0 |
0 |
1 |
Comparator C1 output change |
0 |
1 |
0 |
Comparator C2 output change |
0 |
1 |
1 |
Comparator C1 or C2 output change |
1 |
0 |
0 |
Logic zero (0) on INT pin |
1 |
0 |
1 |
Logic zero (0) on INT pin or comparator C1 output change |
1 |
1 |
0 |
Logic zero (0) on INT pin or comparator C2 output change |
1 |
1 |
1 |
Logic zero (0) on INT pin or comparator C1 or C2 output change |
PSSAC1, PSSAC0 - Pins P1A, P1C Shutdown State Control bits define the logic state of output pins P1A and P1C when the CCP module is in the shut-down state.
PSSAC1 |
PSSAC0 |
PINS LOGIC STATE |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
X |
High impedance (Tri-state) |
PSSBD1, PSSBD0 - Pins P1B, P1D Shutdown State Control bits define the logic state of output pins P1B and P1D when the CCP module is in the shut-down state.
PSSBD1 |
PSSBD0 |
PINS LOGIC STATE |
0 |
0 |
0 |
0 |
1 |
1 |
1 |
X |
High impedance (Tri-state) |