Tuesday, July 19, 2016

BLDC Motor control using PIC16F877A and L293D

Brushless DC motor control with PIC16F877A microcontroller and L293D driver
In this project:
Sensored brushless DC (BLDC) motor control with PIC16F877A microcontroller
I made a sensored BLDC motor speed controller using PIC16F877A and 3 phase bridge circuit.
In this project we are going to see how to build a BLDC motor controller using the same microcontroller and L293D motor driver chip instead of the 3 phase bridge circuit.
The 3 phase bridge is more complicated and expansive and while the L293D motor driver chip is a small, cheap and saves time.
In this project we need two L293D chips because the BLDC motor is a three phase motor, and at any time two windings energized while the third one floating.
The L293D has 4 inputs and 4 outputs with 2 enable pins, each enable pin controls 2 outputs as shown below:
L293D Half H-Bridge motor driver pinout
Complete circuit schematic is shown below:
Interfacing CD-ROM BLDC motor with PIC16F877A and L293D circuit CCS PIC C
In the circuit there are 3 buttons connected to RB0, RB1 and RB2. The buttons connected to RB1 and RB2 are used to start the BLDC motor and the other button is a stop button.
The BLDC motor speed is controlled using a potentiometer connected to AN0 channel.
There are 3 AND gates (HEF4081BP) in the circuit, these gates are used to get a 3 PWM signals from the original one which comes from RC2 pin using CCP1 module.
HEF4081BP has 4 independent 2-input AND gates, three of them are used. This IC needs a supply voltage of +5V between pins 7 (GND) and 14 (VCC).
The CD-ROM BLDC motor pin configurations is shown in the following image:
CD-ROM DVD-ROM Brushless DC motor pin configuration PIC16F877A L293D
Each sensor outputs a digital high for 180 electrical degrees and outputs a digital low for the other 180 electrical degrees. The following figure shows the relationship between the sensors outputs and the required motor drive voltages for phases A, B and C.
Brushless DC motor timing PIC16F877A L293D
The 3 hall effect sensors needs 3 pins and for that RB4, RB5 and RB6 are used.
Two lookup tables are used for motor driver commutation according to the following two tables where table1 for direction 1 and table 2 for direction 2:
BLDC motor direction control table PIC16F877A L293D 
IN1, EN1, IN2 and EN2 are the 1st L293D pins which are respectively IN1, EN1, IN3, EN2.
IN3 and EN3 are the 2nd L293D IN1 and EN1.
BLDC Motor control using PIC16F877A and L293D CCS PIC C code:
// Sensored brushless DC motor control with PIC16F877A and L293D CCS C code
// http://ccspicc.blogspot.com/
// electronnote@gmail.com

#include <16F877A.h>
#device ADC = 10
#use delay(clock = 8000000)
#use fast_io(B)
#use fast_io(D)

int8 hall, Direction = 0;
int8 MoveTable1[8] = {0, 50, 11, 56, 44, 14, 35, 0};
int8 MoveTable2[8] = {0, 35, 14, 44, 56, 11, 50, 0};
#INT_RB                                       // RB port interrupt on change
void rb_isr(void){
  hall = (input_b() >> 4) & 7;
  if(Direction == 1)
void main(){
  output_b(0);                                // PORTB initial state
  port_b_pullups(TRUE);                       // Enable PORTB internal pull-ups
  setup_adc(ADC_CLOCK_DIV_16);                // Set ADC conversion time to 16Tosc
  setup_adc_ports(AN0);                       // Configure AN0 as analog  
  set_adc_channel(0);                         // Select channel 0 input
  setup_timer_2(T2_DIV_BY_1, 199, 1);         // Set PWM frequency to 10KHz
  setup_ccp1(CCP_OFF);                        // CCP1 OFF
    if(!input(PIN_B1)){                       // If RB1 button pressed
      if(Direction == 0){
        Direction = 1;
        setup_ccp1(CCP_PWM);                  // Configure CCP1 as a PWM
        clear_interrupt(INT_RB);              // Clear RB IOC flag bit
        enable_interrupts(INT_RB);            // Enable PORTB IOC
        hall = (input_b() >> 4) & 7;
    if(!input(PIN_B2)){                       // If RB1 button pressed
      if(Direction == 0){
        Direction = 2;
        setup_ccp1(CCP_PWM);                  // Configure CCP1 as a PWM
        clear_interrupt(INT_RB);              // Clear RB IOC flag bit
        enable_interrupts(INT_RB);            // Enable PORTB IOC
        hall = (input_b() >> 4) & 7;
    while(Direction != 0){
       disable_interrupts(INT_RB);             // Disable PORTB IOC
       setup_ccp1(CCP_OFF);                    // CCP1 OFF
       Direction = 0;

CD-ROM BLDC Motor control using PIC16F877A and L293D:
The following video shows project hardware circuit.

Microchip: Sensored BLDC Motor Control Using dsPIC30F2010 (AN957).
Microchip: Brushless DC Motor Control Made Easy (AN857).
L293D Datasheet.