Pulse Width Modulation (PWM) with PIC Microcontroller – XC8

PWM on Oscilloscope

Pulse Width Modulation (PWM) with PIC Microcontroller – XC8

Watch the Video Tutorial

The CCP/ECCP is a multipurpose peripheral module inside most PIC Microcontroller devices. CCP which stands for Capture, Compare and Pulse width modulation while ECCP stands for Enhanced Capture, Compare and Pulse width modulation. The module includes four unique but related peripherals:

  • Capture mode: The peripheral allows timing of duration of an event.
  • Compare mode: The peripheral constantly monitors a timer counter value and compare it to a value set in the application. When they match, it will trigger an event.
  • Pulse Width Modulation (PWM): The peripheral will produce a variable pulse width signal based on a pulse width and period value set in the applications code.
  • The Enhanced Pulse Width Modulation (EPWM): The peripheral will produce a variable pulse width signal based on a pulse width and period value set in the applications code along with Auto-shutdown, Auto-restart, Dead-band Delay and PWM Steering modes. In addition the EPWM can drive various PWM arrangements: Single PWM, Half-Bridge PWM, Full-Bridge PWM, Forward Mode, Full-Bridge PWM, Reverse Mode, Single PWM with PWM Steering Mode

In this article we will discuss the PWM. Pulse width modulation (PWM) is a technique of controlling the amount of power delivered to an electronic load by switching ON and OFF a digital signal. This is the simplest technique that can be used to produce analog voltages from a digital one.
The fraction of the period for which the signal is ON to the total period is known as the duty cycle. The average DC value of the signal can be varied by varying the duty cycle. The duty cycle can be anywhere between 0 (signal is always off) to 1 (signal is constantly on). Suppose, if the signal has +5 V while it is ON and 0 V during OFF condition, then by changing the duty cycle of the signal, the amount of energy transferred to device can be varied. This method is commonly used for controlling speeds of DC motors, brightness of lamps, Sine wave inverters, Digital to Analog Converter (DAC) etc. As you can see in this figure 1 below, when On time is small and Off time long, the Bulb hardly gets any time to turn ON, As the ON time is increased and OFF time decreased it gets brighter.

Controlling brightness of lamps with PWM signalFigure 1: Controlling brightness of lamps with PWM signal

PIC18F26K20 has two CCP modules, named as CCP1 on Pin RC2 (Enhanced Capture, Compare and Pulse width modulation) and CCP2 on Pin RC1 (Standard Capture, Compare and Pulse width modulation).

PIC18F26K20 CCP modulesFigure 2: PIC18F26K20 CCP modules

The Capture/Compare/PWM (CCP2 in PIC18F26K20) module is very versatile. The Capture and Compare features integrate closely with the 16-bit TMR1 and the PWM feature uses the third timer, the 8-bit TMR2. The CCP2 module has two 8-bit registers, called CCPR2L and CCPR2H. Together they form a 16-bit register that can be used for capture, compare or to form the duty cycle of a PWM stream. The CCP2 module is controlled by the CCP2CON register.

PIC18F26K20 - CCP2CON Satyandard Capture/Compare/PWM Control RegisterFigure 3: PIC18F26K20 – CCP2CON Satyandard Capture/Compare/PWM Control Register

In PWM mode, the CCP module produces up to a 10-bit resolution PWM output on the CCPx pin. To operate in PWM mode, the CCPx pin must be configured for output. Figure 4 below shows a simplified block diagram of PWM operation.

PWM Simplified Block Diagram – PIC18F26K20Figure 4: PWM Simplified Block Diagram – PIC18F26K20

We are going to use MPLAB Code Configurator to confugure the PWM peripheral. The steps include setting up the system clock, Timer 2 and the PWM module. The MCC will automatically generate the code to load the proper registers and initialize the proper values to produce the desired PWM signal.
In this demonstration, we are going to create a simple example. An LED will be connected to PIC18F26K20 Capture/Compare/PWM peripheral output. The module will be configured to create a PWM signal at: 1KHz, different duty cycles will be used 100%, 80%, 50%, 30% and 10% using a 8Mhz system clock and 1:16 prescaler.

System Setup
The System is where the oscillator speed is selected and any changes to the configuration settings you may need. The 8 MHz internal oscillator is selected as shown in the picture below, the MCLR pin is also gonna be disabled.

System SetupFigure 5: System Setup

Timer 2 Setup
In the “Device Resources” window, which should be located in the lower left of MCC, add the PWM peripheral under CCP to your project by double clicking. This will automatically add the Timer 2 (TMR2) peripheral to your project as well because PWM uses Timer 2.
Timer 2 uses the oscillator selected in the System section to adjust the Timer 2 period. The time of 1.0 milliseconds is entered for the period to yield a 1KHz frequency. The prescaler is selected as 1:16 from the drop-down menu.

Timer 2 SetupFigure 6: Timer 2 Setup

CCP2: PWM Setup
By selecting the CCP2: PWM the MCC automatically selects the I/O pin RC1 in the I/O selection window. The RC1 pin actually shows up with the label CCP2 in green to show that the CCP2 peripheral now controls the I/O pin. The CCP2:PWM setup screen is where the Duty Cycle is selected and in this demonstration 10 is entered for 10%.

CCP2: PWM SetupFigure 7: CCP2: PWM Setup

Generate Code
When all the setup screens are complete the MCC Generate Code button is clicked and the MCC produces the software files for the project. The MCC will produce a main.c file that contains a System Initialize function as it’s only component. The MCC will generate the mcc, pin_manager, pwm2 and tmr2 C and H files.
The System_Initialize function is placed in a file named MCC.C. System_Initialize calls four functions:
The OSCILLATOR_Initialize function takes the Oscillator Settings selected and sets up the proper registers for the 8 MHz internal oscillator and other fuses you might have selected.
The PIN_MANAGER_Initialize function sets the registers for the I/O pins.
The TMR2_Initialize function sets the registers for the Timer 2 settings selected including the prescaler and PR2 value.
The PWM2_Initialize function selects the settings for the 100% duty cycle value. Notice the CCP2RL register is loaded with the proper value to create the proper high time of the 100% duty cycle.

The pwm2.h files has two functions that we can use to control the PWM module:

  • PWM2_Initialize(void): This routine initializes the PWM2_Initialize. This routine initializes the PWM2_Initialize. This routine must be called before any other CCP2 routine is called.
  • PWM2_LoadDutyValue(uint16_t dutyValue); This routine loads the 16 bit duty cycle value. PWM2_Initialize() function should have been called
    before calling this function.

Example: uint16_t dutycycle;

Below is the the main.c code, loading different duty cycle after a delay of 3 seconds. The project circuit is shown here below on figure 8.

LED connected to PWM pinFigure 8: an LED connected to PWM pin

Below is 80% duty cycle as displayed on the oscilloscope

Oscilloscope 80% duty cycle

Figure 9: 80% duty cycle

You can download the full project files (MPLAB XC8 source code and Proteus Schematic design) below here.  All the files are zipped, you will need to unzip them (Download a free version of the Winzip utility to unzip files).  

Download Mplab Project with Code Configurator: PWM MPLB X Code

Download Proteus Schematic: PWM Proteus

Share this post

Select your currency