DC Motor Control using PWM mode of CCP

PWM Concept

PWM signal is a digital square wave, where the  frequency is constant, but that fraction of the time the signal is on (the duty cycle) can be varied between 0 and 100.Pulse Width Modulation
, or PWM, is a technique for getting analog results with digital means. Digital control is used to create a square wave, a signal switched between on and off. This on-off pattern can simulate voltages in between full on (5 Volts) and off (0 Volts) by changing the portion of the time the signal spends on versus the time that the signal spends off.
The duration of "on time" is called the pulse width. To get varying analog values, you change/ modulate, that pulse width.
If you repeat this on-off pattern fast enough with an LED for example, the result is as if the signal is a steady voltage between 0 and 5v controlling the brightness of the LED.

PWM duty-cycle
Duty Cycle

In the image, the green lines represent a regular time period. This duration or period is the inverse of the PWM frequency.

pwm duty cycle

Pulse Width Modulation

DC motor interface using PWM

DC Motor Driver is a L293D based motor driver interface board. The main aim of interfacing DC motor with any microcontroller is to control the direction and speed of a DC motor. But due to high voltage and current requirement of DC motors, it cannot be interfaced directly with microcontrollers. For to interface DC motor with any microcontroller, we need a motor driver.
Motor driver is basically a current amplifier which takes a low-current signal from the microcontroller and gives out a proportionally higher current signal which can control and drive a motor.
L293D is a dual H-Bridge motor driver IC. With one L293D IC we can interface two DC motors which can be controlled in both clockwise and counter clockwise direction.

L293D pinout diagram

In the interfacing diagram below, we will learn How to interface a L293D based DC Motor Driver in PWM mode with PIC18 microcontroller.
The PWM mode is used to control the speed of DC motors. Higher the duty cycle of the PWM signal higher is the speed of DC motor. The PIC18 microcontroller will generate PWM signals of different duty cycle using its PWM mode of CCP module and will give the PWM signal to the two enable pins of the L293D.
Here, we will use the DC Motor Driver to control the speed of two DC motor. In this way, the microcontroller will run the DC motor in forward direction with different speeds.

DC motor interfacing with PIC18

DC motor interfacing using L293D


DC Motor interface with PIC18 Microcontroller

Note:-  Pin RC2 Provide PWM output

  1. START
  2. Configure RC0, RC2 pins as output pins
  3. Select PWM mode of operation by writing into CCP1CON
  4. Load initial value into PR2 register
  5. Configure T2CON register for Prescaler
  6. Write value into CCPR1L (Duty cycle register) to generate 25% duty cycle waveform on pin RC2
  7. Provide some delay
  8. Write value into CCPR1L (Duty cycle register) to generate 50% duty cycle waveform on pin RC2
  9. Provide some delay
  10. Write value into CCPR1L (Duty cycle register) to generate 75% duty cycle waveform on pin RC2
  11. Provide some delay
  12. Write value into CCPR1L (Duty cycle register) to generate 100% duty cycle waveform on pin RC2
  13. END

The following Program will generate PWM waveform with 25%, 50%, 75%, 100% duty cycle on Pin RC2 using CCP Module

#pragma config OSC=HS
#pragma config PWRT=OFF
#pragma config WDT=OFF
#pragma config DEBUG=OFF, LVP=OFF
void DELAY();
#define IN1 PORTCbits.RC0
#define IN2 PORTCbits.RC2
void main()
TRISC=0x00;   ///RC0,RC2 pin as PWM output pin
CCP1CON=0X0C;///PWM mode
PR2=100;      ////PR2=(Fosc/4xNxFpwm)
T2CON=0X05;  ///Prescaler=4
while(1)      ///forever loop
IN1=1;// CLOCKWISE Direction
CCPR1L=25;     //25% Duty cycle
CCPR1L=50;     //50% Duty cycle
CCPR1L=75;     //75% Duty cycle
CCPR1L=100;     //100% Duty cycle
TMR2=0x00;               //load TMR2=00H
PIR1bits.TMR2IF=0;        //Clear interrupt flag
T2CONbits.TMR2ON=1;        //start timer 2
while(PIR1bits.TMR2IF==0);  ///monitor TMR2 interrupt flag

void DELAY()
unsigned int i,j;


  • Notes by Prof. Sujit Wagh
  • www.arduino.cc/en/Tutorial/SecretsOfArduinoPWM

Last modified: Monday, 16 September 2019, 4:53 PM