You are on page 1of 6

EE197 E-H

5 April 2011

BLDC Motor Driver


Ranbill O. Cadayona, Jan Darell L. Hernandez, Jesse Paulo V. Macabasco
Electrical and Electronics Engineering Institute, University of the Philippines
Diliman, Quezon City, Philippines
ranbillcadayona@yahoo.com

jdhernandez_03@yahoo.com
jpmacabasco@gmail.com
Abstract The brushless DC motor is a motor type gaining
popularity because of its advantages over brushed ones. This
document presents a microcontroller-based driver design for a
BLDC motor.

I. INTRODUCTION
rushless Direct Current (BLDC) motors are one of the
motor types rapidly gaining popularity. BLDC motors
are used in industries such as appliances, automotive,
aerospace, consumer, medical, industrial automation
equipment and instrumentation.
As the name implies, BLDC motors do not use brushes
for commutation; instead, they are electronically commutated.
This is accomplished through a driver designed for the
particular operation of a BLDC motor.

III. BLDC MOTOR DRIVER DESIGN


The BLDC motor driver is both a hardware and software
design, since it will be based on a microcontroller (which
needs to be programmed).
A. Hardware
The hardware design of the driver is based on the threephase bridge, shown in Fig.2. Each drive phase consists of one
motor terminal driven high, one motor terminal driven low,
and one motor terminal left floating; corresponding to the
commutation sequence.

II. BLDC MOTOR THEORY OF OPERATION


The BLDC motor is constructed as such: the rotor is made
of the permanent magnet and the stator contains the windings.
For a three-phase BLDC motor, there are three windings; one
energized positively, another one negatively, and one left
unpowered. This is done at each sequence, alternately
changing between windings; this is called the Six-Step
Commutation. At this commutation, the magnetic field
produced by the windings keeps on changing its position,
causing the permanent magnet in the rotor to follow.

Fig. 2 Three-phase bridge

The field effect transistors used for the driver are IRF9640
and IRF640; power MOSFETs complementary to each other
(P-channel and N-channel respectively). These MOSFETS are,
in turn, driven by power transistors (TIP30 and TIP31)
through a common-emitter amplifier cascaded with a power
amplifier.
2k
R4

Q3
TIP31

IRF9640

1K
470
10k
R3
R2

Q2
TIP31

Q10
TIP30

R5

d1n4004
D1
Q4

2k
R7

Q7
TIP31

Fig. 1 Six-step commutation


470
10k
R16
R8

The BLDC motor will run only if the correct sequence is


followed; otherwise, the motor will run for a certain angle and
stop since commutation did not follow.

IRF640

1K
Q1
TIP31

Q5
TIP30

R6

d1n4004
D2
Q8

Fig. 3 Transistor drive with power amplifier (one phase)

Page 1 of 6

EE197 E-H

5 April 2011

Since a common-emitter amplifier is used, output logic will


be inverted and must be accounted in determining the desired
waveforms for the driver output.
40
V3

ARB3
V(N1)*V(N2)

V10

N1

1K

OUT

ctr=1 frolloff=100k
U1

2k
R4

Q3
TIP31

IRF9640

1K

R1

N2
V7

470
10k
R3
R2

Q2
TIP31

Q10
TIP30

R5

The feedback voltage sensors are used to determine the


state of the windings and voltage levels; for commutation
sequence. Fig.8.a is a virtual ground, since the real neutral
node is not accessible. This virtual ground is formed by
paralleling resistors with each winding and formed in wyeconnection. Fig.8.b is a simple divider to sense the voltage of
the floating winding.

d1n4004
D1

u
U

250k

250k

R2

R1

R1
250k

V_STAR

1K
V4

ctr=1 frolloff=100k
U2

2k
R7

Q7
TIP31

Q1
TIP31

Q5
TIP30

470
10k
R16
R8

R6

d1n4004
D2
Q8

R3
250k

R3
250k

v _u

R4
3.3k

IRF640

1K

R9

Q4

R5
250k

v _v

R2
10k

v _w

R4
10k

R6
10k

Fig. 5 Complete Motor driver (one phase)

Fig. 5 shows the complete design for the motor driver.


Waveform generators are used to simulate the microcontroller.
The driver is isolated by 4N25 optocouplers in the input side
to ensure protection for the microcontroller.
The simulated waveforms of the driver are shown in Fig. 6.
PWM signals are used to control the input voltage. By
averaging the voltages from the PWM signals, an effective
input voltage is achieved. For a PWM signal with 10% duty
cycle, 10% of the input voltage is fed to the driver.

Fig. 8.a) Virtual ground and b) feedback voltage sensors

These sensed voltages are then fed into a comparator; used


as a zero-crossing detector. If a zero-crossing is detected, the
transistor will output a logic high (3.3V) which the
microcontroller polls. This will serve as markers, and signal
the microcontroller to make the required adjustments for
correct commutation sequence. This will now correspond to
the closed loop control of the motor.
3.3
V2
7
V1

R2
3.3k
u_u

X1

v_u

250k

v_STAR

R1

Q1
Q2N3904

LF353
3.3
V4
7
V3

R4
3.3k
u_v

X2

v_v

250k

v_STAR

R3

Q2
Q2N3904

LF353
3.3
V6
7
V5

Fig. 6 Simulated driver output waveforms (one phase)

The waveforms are based on the logic shown in Fig. 7.


When A2 (green waveform in Fig. 6) is logic high and A1
(blue waveform) is logic low, the output logic (red waveform)
should be float or open circuit; in the case of the simulation,
20V is the set float voltage since float cannot be really
simulated. When A2 and A1 is both logic high, the output
logic is high; low when both inputs are low. When A2 is low
and A1 is high, it would mean that the voltage supply is
shorted to ground; so this final case should not be encountered
in producing the PWM signals.

Fig. 7 PWM Logic

R6
3.3k
u_w

X3

v_w

250k

v_STAR

R5

Q3
Q2N3904

LF353

Fig. 9 Feedback Voltage Comparators

For current limiting of the driver, a simple metal clip (with


approximately 18m resistance) is used; sensing the voltage
across it and feeding it into the ADC of the microcontroller.
Initially, when there is no load, supply voltage is equal to 40%
of the DC input voltage (48V). After applying a load, the back
emf decreases, making the current high, which is undesirable
for the system. The microcontroller lowers the duty cycle of
the PWM signal if a high current is detected.

Fig. 10 Current sensing

Page 2 of 6

EE197 E-H

5 April 2011

B. Software
The microcontroller used for this motor driver is the
Z8F6421 Flash Microcontroller (packaged in the IRC
slimboard). The language used for programming the
microcontroller is C.
Since the commutation sequence for the BLDC motor is
divided into six, a unique set of codes will correspond to each
stage.Timers are operated in PWM mode to produce the inputs
to the three-phase bridge. Fig. 11 shows the microcontroller
output waveforms for an open loop system (six-step
commutation). This program applies when the system is at its
starting condition. The output coming from the
microcontroller is fed directly to the motor, making it rotate at
low speed.

Fig. 12 b) Microcontroller Waveforms for a Closed Loop System

IV. LIMITATIONS OF THE DESIGN


The configuration for speed control is not working properly;
it should change the speed of the commutation by changing
the reload values in the microcontroller program. In testing it,
the motor would only enter dynamic breaking, and then
proceed back to normal commutation sequence. A problem
with this scheme is that the change is sudden, a more reliable
control configuration (preferably with a potentiometer) is
recommended for the driver.

Fig. 11 Microcontroller Waveforms for an Open Loop System

After some time, the motor will start to rotate faster,


turning the system to a closed loop. At this point, the part of
the program following the scheme shown in Fig.12 will be
applied. For commutation purposes with the back emf signals,
the phase voltage should be determined whether it has crossed
zero with respect to the neutral (zero crossing detector). As
this happens, when one phase is crossing neutral, the other
two phases are at equal and opposite voltages, thus, a zero
crossing of one phase is detected.

V. CONCLUSION
The design presented in this paper is able to drive the
BLDC motor with a rating of 48V; from low starting speed to
a certain high speed. The right commutation sequence is
followed by the driver; hence a smoother running of the
BLDC motor.
The driver also implements both open and closed loop
control; open loop is for starting sequences and then
transitions into the closed loop control for the motor. This is
done through correct voltage feedback sensing and use of
comparators. The driver also includes a current limiting
scheme to protect the design from damage due to high
currents caused by loading.
REFERENCES
[1]

[2]
[3]
[4]

(2011) Permanent Magnet Synchronous Machine on MathWorks


[Online].
Available:
http://www.mathworks.com/help/toolbox/
physmod/powersys/ref/permanentmagnetsynchronousmachine.html
R. Condit, Sensorless BLDC Control With Back-EMF Filtering,
Microchip Technology Inc., c2007.
P. Yedamale, Brushless DC (BLDC) Motor Fundamentals, Microchip
Technology Inc., c2003.
J.R. Mevey, Sensorless Field Oriented Control of Brushless Permanent
Magnet Synchronous Motors, Dept. of Electrical and Computer
Engineering, College of Engineering, Kansas State University,
Manhattan, Kansas, USA, c2009.

Fig. 12 a) Microcontroller Waveforms for a Closed Loop System

Page 3 of 6

EE197 E-H

5 April 2011
APPENDIX

T1RL = (RELOAD & 0xFF);


IRQ0ENH &= ~0x40;
// disable timer1 interrupt T3I
IRQ0ENL &= ~0x40;
IRQ0 &= ~0x40;
// clear timer3 interrupt flag
T1CTL1 |= 0x80;
// Enable timer3

Source Code
#include <sio.h>
#include <stdio.h>
#include <ez8.h>
#define CHANNEL 0x00
#define MODE 0x00
#define VREF 0x00
#define ENABLE 0x80
#define RELOADPWM 144

void delay(void);
void Init_ADC(void);
int Poll_ADC(void);
void InitTimerDelay0(void);
void InitTimerDelay1(void);
void InitTimerDelay2(void);
void InitTimer0(void);
void InitTimer1(void);
void InitTimer2(void);
void stage_1(void);
void stage_2(void);
void stage_3(void);
void stage_4(void);
void stage_5(void);
void stage_6(void);
void sense_current(void);
int RELOAD=24001;
int PWM;
void delay ()
{
char a;
for(a = 0; a < (0x0F); a++);
}
void Init_ADC (void)
{
PBAF = 0x01;
ACTL = (CHANNEL | VREF | MODE);
}
int Poll_ADC (void)
{
ACTL |= ENABLE;
while(ACTL & ENABLE);
return (int)((ADHR<<2)|(ADLR>>6));
}
void InitTimerDelay0(void)
{
T1CTL1 = 0x28; // disable T3,one shot mode, prescaler 32
T1H = 0x00; T1L = 0x01;
// T3 start = 0x0001
T1RH = (RELOAD >> 8);

}
void InitTimer0(void)
{
PAAF |= 0x02;
//T0OUT --> PA1
T0CTL1 = 0x2B;
//PWM mode, prescaler = 32,
low first per period, disable T0
T0H = 0x00;
//T0 start = 0x0001
T0L = 0x01;
T0RH = (RELOADPWM>>8); //T0 reload value
T0RL = (RELOADPWM & 0xFF);
T0PWMH = (PWM>>8);
//T0 PWM value
T0PWML = (PWM & 0xFF);
IRQ0ENH &= ~0x02; //disable timer interrupt T0I
IRQ0ENL &= ~0x02;
IRQ0 &= ~0x02;
//clear timer0 interrupt flag
T0CTL1 |= 0x80;
//enable timer 0
}
void InitTimerDelay1(void)
{
T2CTL1 = 0x28; // disable T3,one shot mode, prescaler 32
T2H = 0x00; T2L = 0x01;
// T3 start = 0x0001
T2RH = (RELOAD >> 8);
T2RL = (RELOAD & 0xFF);
IRQ0ENH &= ~0x80;
// disable timer1 interrupt T3I
IRQ0ENL &= ~0x80;
IRQ0 &= ~0x80;
// clear timer3 interrupt flag
T2CTL1 |= 0x80;
// Enable timer3
}
void InitTimer1(void)
{
PCAF |= 0x02;
T1CTL1 = 0x2B;

//T1OUT --> PC1


//PWM mode, prescaler = 32,
low first per period, disable T1
//T1 start = 0x0001

T1H = 0x00;
T1L = 0x01;
T1RH = (RELOADPWM>>8); //T1 reload value
T1RL = (RELOADPWM & 0xFF);
T1PWMH = (PWM>>8);
//T1 PWM value
T1PWML = (PWM & 0xFF);
IRQ0ENH &= ~0x40; //disable timer interrupt T1I
IRQ0ENL &= ~0x40;
IRQ0 &= ~0x40;
//clear timer1 interrupt flag
T1CTL1 |= 0x80;
//enable timer 1

}
void InitTimerDelay2(void)
{
T0CTL1 = 0x28; // disable T3,one shot mode, prescaler 32
T0H = 0x00; T0L = 0x01;
// T3 start = 0x0001
T0RH = (RELOAD >> 8);

Page 4 of 6

EE197 E-H

5 April 2011

T0RL = (RELOAD & 0xFF);


IRQ0ENH &= ~0x20;
// disable timer1 interrupt T3I
IRQ0ENL &= ~0x20;
IRQ0 &= ~0x20;
// clear timer3 interrupt flag
T0CTL1 |= 0x80;
// Enable timer3

PCOUT |= 0x04;
InitTimerDelay0();
while(!(IRQ0&0x40))
{
sense_current();
}
IRQ0 &= ~0x40;
return;

}
void InitTimer2(void)
{
PCAF |= 0x80;
T2CTL1 = 0x2B;

//T2OUT --> PC7


//PWM mode, prescaler = 32,
low first per period, disable T2
//T2 start = 0x0001

T2H = 0x00;
T2L = 0x01;
T2RH = (RELOADPWM>>8); //T2 reload value
T2RL = (RELOADPWM & 0xFF);
T2PWMH = (PWM>>8); //T2 PWM value
T2PWML = (PWM & 0xFF);
IRQ0ENH &= ~0x80; //disable timer interrupt T2I
IRQ0ENL &= ~0x80;
IRQ0 &= ~0x80;
//clear timer2 interrupt flag
T2CTL1 |= 0x80; //enable timer 2

}
void stage_3(void)
{
PAAF &= ~0x02;
PADD &= ~0x02;
PAOUT &= ~0x02;

if(RELOAD<=4001)
{
while(1)
{
if(PAIN&0x10)break;
}
}

void stage_1(void)
{
//cancel alt func of PC7
//set PC7 as output
//set PC7 low
//set PA2 high
//set PC6 high

if(RELOAD>4001)InitTimerDelay1();
while(!(IRQ0&0x80))
{
sense_current();
}
IRQ0 &= ~0x80;
return;

InitTimer0();
if(RELOAD<=4001)
{
while(1)
{
if(PAIN&0x80)break;
}
}

}
void stage_4(void)
{
PAOUT &= ~0x04;
PCOUT |= 0x40;

if(RELOAD>4001)InitTimerDelay0();
while(!(IRQ0&0x40))
{
sense_current();
}
IRQ0 &= ~0x40;
return;

//set PA2 low


//set PC6 high

InitTimerDelay1();
while(!(IRQ0&0x80))
{
sense_current();
}
IRQ0 &= ~0x80;
return;

}
void stage_2(void)
{
PCOUT &= ~0xC2;

//cancel alt func of PA1


//set PA1 as output
//set PA1 low

InitTimer1();

PCAF &= ~0x80;


PCDD &= ~0x80;
PCOUT &= ~0x80;
PAOUT |= 0x04;
PCOUT |= 0x40;

//set PC2 high

//set PC1,PC6,and PC7 low

void stage_5(void)
{

Page 5 of 6

EE197 E-H

PCAF &= ~0x02;


PCDD &= ~0x02;
PCOUT &= ~0x02;

5 April 2011

//cancel alt func of PC1


//set PC1 as output
//set PC1 low

InitTimer2();
if(RELOAD<=4001)
{
while(1)
{
if(PAIN&0x40)break;
}
}

PCDD &= ~0xC6; //set PC1,PC2,PC6, and PC7 as


output
//----------------------dynamic breaking-------------------------PAOUT &= ~0x02;
//set PA1 low
PCOUT &= ~0x82;
//set PC1 and PC7 low
delay();
PAOUT &= ~0x04;
//set PA2 low
PCOUT &= ~0x44;
//set PC2 and PC6 low
//-----------------------------------------------------------------while(1)
{
if(!(PDIN&0x40))break;
}

if(RELOAD>4001)InitTimerDelay2();
while(!(IRQ0&0x20))
{
sense_current();
}
IRQ0 &= ~0x20;
return;
}

sense_current();
while(1)
{
stage_1();
sense_current();
stage_2();
sense_current();
stage_3();
sense_current();
stage_4();
sense_current();
stage_5();
sense_current();
stage_6();
sense_current();
if(RELOAD>3001)
RELOAD=RELOAD-1000;
}

void stage_6(void)
{
PAOUT |= 0x04;
PCOUT &= ~0x04;

//set PA2 high


//set PC2 low

InitTimerDelay2();
while(!(IRQ0&0x20))
{
sense_current();
}
IRQ0 &= ~0x20;
return;
}
void sense_current(void)
{
float volts;
Init_ADC();
volts=(float)(Poll_ADC())/512.0;
PWM=RELOADPWM*(0.7+(0.1*volts));
}
void main(void)
{
PWM=RELOADPWM*0.6;
PADD |= 0xD0;
//set PA4,PA6, and PA7 as input
PDDD |= 0x4C;
//set PD2,PD3, and PD6 as input
PADD &= ~0x06; //set PA1 and PA2 as output

/*
while(1)
{
stage_1();
sense_current();
stage_2();
sense_current();
stage_3();
sense_current();
stage_4();
sense_current();
stage_5();
sense_current();
stage_6();
sense_current();
}
*/
}
*/End of Code*/

Page 6 of 6

You might also like