Skip to main content

DC Motor Speed Control With PIC16F628A

DC motor speed control with PIC16F628A microcontroller simulation.
DC Motor Speed Control Simulation

In this project, we will control the speed and direction of a DC motor using the PIC16F628A microcontroller. We will write the software in MPLAB IDE with the XC8 language that will send a PWM signal to L293D to control the motor. Finally, we will simulate it through the Proteus software.

You can get more information about the PWM signal from the link above. Now let’s examine the L293D motor driver.

L293D Motor Driver

L293D motor driver pinout diagram.
L293D Pinout

With this motor drive, we can supply 600mA (max. 1.2A) and a voltage between 4.5V-36V. We will give 12V voltage to the input, assuming that we will run 12V motors in this project. The control is as in the table below.

As shown in the table, the control of the L293D motor driver is similar to that of the L298N.

If we want to drive 2 DC motors, one L293D is enough. However, if you will use 4 DC motors in your project, you will need 2 L293D.

Note: You must connect the GND of the L293D circuit and all other grounds to each other. Otherwise, the circuit will not work.

In this project, we describe 1 DC motor control because of microcontroller has 1 PWM module. We have set the required control frequency for the motor to 490Hz. This frequency is close to the ideal frequency for the DC motor. You can see the motor speed control code in the XC8 language and PWM calculation with explanations below.

Let’s do the calculations before going to code;

PWM calculation for PIC16F628A microcontroller.
PWM Calculation

As we cannot produce a 490 Hz PWM signal, we produced a 488 Hz signal. We used a 4 MHz internal oscillator to generate a 488 Hz and a 9-bit resolution PWM signal.

DC Motor Speed Control XC8 Code

 * File:   main.c
 * Author: Trionium
 * Created on 13.01.2020, 21:21

// PIC16F628A Configuration Bit Settings

#pragma config FOSC = INTOSCCLK // Oscillator Selection bits (INTOSC oscillator: CLKOUT function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON       // RA5/MCLR/VPP Pin Function Select bit (RA5/MCLR/VPP pin function is MCLR)
#pragma config BOREN = OFF      // Brown-out Detect Enable bit (BOD disabled)
#pragma config LVP = OFF        // Low-Voltage Programming Enable bit (RB4/PGM pin has digital I/O function, HV on MCLR must be used for programming)
#pragma config CPD = OFF        // Data EE Memory Code Protection bit (Data memory code protection off)
#pragma config CP = OFF         // Flash Program Memory Code Protection bit (Code protection off)

#include <xc.h>
#include <stdint.h>
#define _XTAL_FREQ 4000000

void main(void) {
    PR2 = 0x7F; // Set PWM frequency to 488Hz
    CCP1CONbits.CCP1M = 0b1100; // Set PWM Mode
    T2CONbits.T2CKPS = 0b11; // Set Timer2 prescale to 1:16
    T2CONbits.TMR2ON = 1; // TMR2 On
    TRISBbits.TRISB3 = 0; // RB3 Output
    TRISAbits.TRISA0 = 1; // RA0 Input
    TRISAbits.TRISA1 = 1; // RA1 Input
    CMCONbits.CM = 0b111; // Digital input
    int16_t speed = 0;
    // For direction input
    TRISAbits.TRISA2 = 1;
    // For direction control output
    TRISAbits.TRISA3 = 0;
    TRISAbits.TRISA4 = 0;
    while(1) {
        // Speed up
        if(PORTAbits.RA0) {
        // Speed down
        if(PORTAbits.RA1) {
        // Turn left
        if(PORTAbits.RA2) {
            PORTAbits.RA3 = 1;
            PORTAbits.RA4 = 0;
        // Turn right
        else {
            PORTAbits.RA3 = 0;
            PORTAbits.RA4 = 1;
        // PWM resolution is 9bit, therfore
        // Speed must be between 0 and 511
        if(speed > 511)
            speed = 511;
        else if(speed < 0)
            speed = 0;
        // Set Duty Cycle
        CCPR1L = speed >> 2;
        CCP1CONbits.CCP1X = (speed & 2) >> 1;
        CCP1CONbits.CCP1Y = speed & 1;

When the SPEED UP button is pressed, the speed of the motor will increase up to 100% and when the SPEED DOWN button is pressed, the speed of the motor will decrease by 0%. The direction of rotation of the motor can be controlled with the Direction Control switch.

Thus, we made a simple DC motor control circuit with a PIC microcontroller. We hope it has been useful, stay healthy.


Popular posts from this blog

How to Make Blink LED with PIC16F628A

How to Make Blink LED With PIC16F628A In this project tutorial, we are going to make blink-led projects with a pic microcontroller. After you read this tutorial you can build a PIC microcontroller project with XC8 on MPLAB IDE. We are going to make 3 different blinking projects. These projects are basic. Just learn how to make a basic project with a PIC microcontroller. You can see below which projects we are going to make; Blinking LED with 1s delay, LED with button, Blinking LED with a button.

Ultrasonic Sensor HC-SR04 With PIC Microcontroller

How Ultrasonic Sensor Works An ultrasonic sensor is a very useful sensor that measures distances with sounds. We used the PIC16F628A microcontroller for this project. This microcontroller has TMR1 which we are going to use. We need 2 I/O pins for TRIG and ECHO pins. For showing distance, we used an LCD. For more information about the LCD library and usage click the button below. LCD Interfacing with PIC Using XC8