DC Motor control with PIC microcontroller | mikroC Projects

This post shows how to control DC motor speed and direction of rotation using PIC16F887 microcontroller and L293D motor driver.
The L293D quadruple half-H drivers chip allows us to drive 2 motors in both directions. With one PWM signal from the PIC16F887 and two control signals we can easily control the speed as well as the direction of rotation of one DC motor. PWM: Pulse Width Modulation.

In this project the speed of the DC motor is controlled using a potentiometer connected to the PIC16F887 microcontroller. The speed is related to the variation of the duty cycle of the PWM signal, the DC motor reaches its maximum speed when the duty cycle is equal to 100% (255 for 8-bit resolution).
The direction of rotation is controlled using a pushbutton, if the pushbutton is pressed the motor will change its direction.

DC Motor control with PIC16F887 microcontroller circuit:
The following image shows the circuit schematic diagram of this example.

(All grounded terminals are connected together)

The circuit is supplied with two power sources, one with voltage of 5V which supplies the PIC16F887 microcontroller and the L293D driver IC (VCC1), and the second source with voltage of 12V which supplies the L293D chip (VCC2) (therefore the DC motor). The DC motor nominal voltage is 12V.

The speed of the DC motor (both directions) is controlled with the 10k potentiometer which is connected to AN0 pin of the PIC16F887 (#2) and the direction of rotation is controlled with the push button which is connected to RB1 pin (#34). If the button is pressed the motor will change its direction of rotation directly.

The L293D driver has 2 VCCs: VCC1 is +5V and VCC2 is +12V (same as motor nominal voltage). IN1 and IN2 are the control pins where:

IN1

IN2

Function

L

H

Direction 1

H

L

Direction 2

L

L

Fast motor stop

H

H

Fast motor stop

The PIC16F887 generates a PWM signal on pin RC2 (#17) using CCP1 module (CCP: Capture/Compare/PWM), this pin is connected to EN1,2 pin of the L293D chip. IN1 and IN2 pins are connected to RD0 and RD1 respectively (they can be reversed).

In this project the PIC16F887 microcontroller uses its internal oscillator @ 8 MHz, MCLR pin is configured as an input pin.

DC Motor control with PIC16F887 microcontroller C code:
The following C code is for mikroC PRO for PIC compiler, it was tested with version 7.2.0.

The pushbutton (connected to RB1) and the control lines (connected to RD0 and RD1) are defined in the code as shown below:

C

1

2

3

4

5

// direction button connected to pin RB1

#define Button RB1_bit

// define motor control pins

#define IN1 RD1_bit

#define IN2 RD0_bit

Internal weak pull-up is enabled for pin RB1, the following lines are used for that:

C

1

2

3

// enable RB1 internal pull up

NOT_RBPU_bit=0;// clear RBPU bit (OPTION_REG.7)

WPUB=0x02;// WPUB register = 0b00000010

The resolution of the ADC module is 10-bit which means its output digital value can vary between 0 and 1023. If the analog input voltage is 0 the digital value is also 0, and if the analog voltage is 5V (VDD) the digital value is 1023.

MikroC PRO for PIC compiler has a built-in library for PWM. With this library the resolution of the PWM is 8-bit which means the duty cycle can be between 0 and 255.

In this project I used the ADC digital value to set the PWM signal duty cycle, and to convert a 10-bit number to 8-bit, we’ve shift it (the 10-bit number) to the right by 2 as shown below (motor_speed >> 2):