The easiest way to control a sensorless BLDC motor is through an ESC (Electronic Speed Controller). This topic shows how to drive a BLDC motor using an ESC and PIC16F887 microcontroller. Topics related to this post: PIC16F887 Timers and Interrupts
The basic components of the ESC is a microcontroller and at least 6 mosfets. It also consists of other components such as voltage regulator, capacitors, resistors ..... The controlling of the ESC is similar to the controlling of servo motor, the ESC controls the speed of the BLDC motor while the servo motor controller controls the position (moving angle) of a DC motor.
To drive the ESC or servo motor we've to provide a repeated 50Hz PWM signal (20 ms period) with a duty cycle between 5 and 10% (1 ms to 2 ms pulse). The following figure shows the PWM signal needed by the ESC:
Hardware Required:
PIC16F887 microcontroller
ESC (Electronic Speed Controller) __ I used 30A ESC
Brushless DC motor __ I used 2210 - 1000KV BLDC motor
10K ohm potentiometer
Breadboard
Battery (or high power 12V source)
Jumper wires
Sensorless brushless DC motor drive with an ESC and PIC16F887 circuit:
The two thick wires black and red are the ESC input power which normally comes from a battery (11.1V, 14.8V ....). There are also 3 thick wires which are black, red and brown (in my ESC white). The black and red are 5V voltage source which can be used to supply the microcontroller circuit as what I have done, or the microcontroller circuit can be supplied from an other source and in this case the red wire will not be used. The brown wire is the PWM signal wire and this wire is used to send PWM pulses from the microcontroller to the ESC through pin RD0.
In my hardware circuit I replaced the battery with 12V 10A DC voltage source.
The potentiometer which is connected to RA0 is used to control the speed of the BLDC motor.
In this example the PIC16F887 uses its internal oscillator and MCLR pin function is disabled.
Sensorless brushless DC motor drive with an ESC and PIC16F887 CCS C code:
Timer1 module is used to measure pulses width, it's configured to increment every 1 us.
/* Sensorless brushless DC motor drive with an ESC and PIC16F887 CCS PIC C code PIC16F887 runs with 8MHz internal oscillator http://ccspicc.blogspot.com/ electronnote@gmail.com*/#include <16F887.h>
#device ADC = 10
#fuses NOMCLR, NOBROWNOUT, NOLVP, INTRC_IO
#usedelay(clock = 8MHz)
#use fast_io(D)
int16 i;
void main(){
setup_oscillator(OSC_8MHZ); // Set internal oscillator to 8MHz
output_d(0);
set_tris_d(0); // Configure PORTD pins as outputs
setup_adc(ADC_CLOCK_INTERNAL); // ADC module uses its internal oscillator
setup_adc_ports(sAN0); // Configure AN0 as analog input pin
set_adc_channel(0);
setup_timer_1(T1_INTERNAL | T1_DIV_BY_2); // Setup Timer1 module: internal source + 2 prescalerwhile(TRUE){
set_timer1(0); // Set Timer1 value to 0
output_high(PIN_D0);
i = read_adc(); // Read analog value from channel 0 and store it in 'i'if(i > 1000)
i = 1000;
i = i + 1000;
while(get_timer1() < i);
output_low(PIN_D0);
while(get_timer1() < 19999);
}
}
In this blog there are some topics shows how to drive a cd-rom (dvd-rom) spindle motor using different types of PIC microcontrollers. This topic shows how to control the speed of a sensored BLDC motor using PIC16F887 microcontroller.
The BLDC motor is a three phase DC motor without brushes.
Basically there are two types of BLDC motors: sensored and sensorless. The sensored BLDC motor has 3 hall effect sensors which detect the rotor position while the sensorless BLDC motor has no hall effect sensors and it uses back emf to detect the rotor position.
The sensored BLDC motor is easy to drive because always we know the position of its rotor with the help of the hall effect sensors.
As mentioned above, the BLDC motor is a 3 phase DC motor which means it has 3 winding on the stator core. Two windings are excited at a time to create a rotating electric field. This method is fairly easy to implement, but to prevent the permanent magnet rotor from getting locked with the stator, the excitation on the stator must be sequenced in a specific manner while knowing the exact position of the rotor magnets.
The sensored BLDC motor has 3 hall effect sensors (Sensor A, Sensor B and Sensor C) to sense rotor position, this sensors are placed as shown in the following picture. The motor which I'm going to drive has pinout as shown below (other motors may have another pinout).
In this motor each hall effect sensor has 4 pins: VCC, GND and two outputs (some sensors come with 3 pins: VCC, GND and output).
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.
A three phase bridge is used to energize the BLDC motor windings.
According to the hall effect sensors, the 3 phase inverter bridge is controlled as shown in the following table:
CD-ROM Sensored brushless DC motor drive with PIC16F887 microcontroller circuit:
In the circuit there are 3 comparators A, B and C (LM339) which are used with the hall effect sensors to detect rotor position. The complete circuit of the LM339 is shown below:
Also in the circuit there are 8 AND and 3 NOT gates, and for that I used 2 x SN74LS08 (each one contains 4 AND gates) and one SN74LS04. The complete circuit of the three ICs is shown below:
The two gates AND1 and AND2 are used to create two PWM signals from single PWM signal because PIC16F887 microcontroller has only two PWM modules and our project needs 3.
The other AND gates (AND3 - 8) and the NOT gates are used to drive the bridge mosfets and also provides a good protection to our mosfets because high and low mosfets of one line must not be ON at the same time.
A 10K ohm potentiometer is used to control the speed of the BLDC motor where its output is connected to AN0.
A 20MHZ crystal oscillator is used and MCLR pin function is disabled. CD-ROM Sensored brushless DC motor drive with PIC16F887 microcontroller C code:
The following is code is for CCS PIC C compiler.
The potentiometer is used to vary the duty cycle of PWM1 and PWM2 signals which causes the speed of the BLDC motor to change. The outputs are controlled according to the following table:
The two PWM modules of the PIC16F887 are used to generate two PWM signals. Timer2 module is configured so that the each PWM signal has a frequency of 4.88KHz and 10-bit resolution: setup_timer_2(T2_DIV_BY_4, 255, 1);
The potentiometer is used to change the duty cycle of the PWM signal which causes the speed of the BLDC motor to change.
The complete C code of this project is as the one below:
/* CD-ROM sensored BLDC motor drive with PIC16F887 microcontroller CCS PIC C code PIC16F887 runs with 20MHz crystal oscillator http://ccspicc.blogspot.com/ electronnote@gmail.com*/#include <16F887.h>
#device ADC = 10
#fuses NOMCLR, NOBROWNOUT, NOLVP, HS
#usedelay(clock = 20MHz)
#use fast_io(B)
#use fast_io(D)
int8 hall, prev_hall;
int16speed;
void bldc_move(){
switch(hall){
case 1:
setup_ccp2(CCP_PWM);
output_d(0x12);
break;
case 2:
setup_ccp2(CCP_OFF);
output_d(0x0B);
break;
case 3:
setup_ccp2(CCP_PWM);
output_d(0x18);
break;
case 4:
setup_ccp2(CCP_PWM);
output_d(0x0C);
break;
case 5:
setup_ccp2(CCP_OFF);
output_d(0x0E);
break;
case 6:
setup_ccp2(CCP_PWM);
output_d(3);
break;
default:
setup_ccp2(CCP_OFF);
output_d(0);
break;
}
}
void main(){
output_b(0);
set_tris_b(7); // Configure RB0, RB1 and RB2 as digital input pins
port_b_pullups(7); // Enable internal weak pull-ups for RB0, RB1 and RB2
output_d(0);
set_tris_d(0); // Configure PORTD pins as outputs
setup_ccp1(CCP_PWM); // Configure CCP1 module as PWM
setup_ccp2(CCP_OFF); // CCP2 module OFF
setup_adc(ADC_CLOCK_INTERNAL); // ADC module uses its internal oscillator
setup_adc_ports(sAN0); // Configure AN0 as analog input pin
set_adc_channel(0); // Select channel AN0
setup_timer_2(T2_DIV_BY_4, 255, 1); // Set PWM frequency to 4.88KHz with a resolution of 10 bits
delay_ms(1000); // Wait 1 second
read_adc(ADC_START_ONLY); // ADC start onlywhile(TRUE){
if(!adc_done()){ // If the conversion is completedspeed = read_adc(ADC_READ_ONLY); // ADC read only
set_pwm1_duty(speed); // Set PWM1 duty cycle
set_pwm2_duty(speed); // Set PWM2 duty cycle
read_adc(ADC_START_ONLY); // ADC start only
}
hall = input_b() & 7; // Read hall effect sensors from pins: RB0, RB1 and RB2if(hall != prev_hall){ // If the rotor position changed
bldc_move(); // Move the rotor according to hall effect senors state
prev_hall = hall; // Save current rotor position
}
}
}
Finally the following video shows a simple hardware circuit of the project.
In the following topic URL we've seen how to control BLDC motor speed and direction of rotation using PIC18F4550 microcontroller and 3-phase bridge circuit: CD-ROM Spindle motor (BLDC) control with PIC18F4550 microcontroller
This topic shows how to make the same controller using L293D motor driver 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:
Complete circuit schematic is shown below:
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).
PIC18F4550 microcontroller internal oscillator is used (8MHz). BLDC Motor control using PIC18F4550 and L293D CCS PIC C code:
// Sensored BLDC motor controller using PIC18F4550 and L293D CCS C code// http://ccspicc.blogspot.com/// electronnote@gmail.com#include <18F4550.h>
#device ADC = 10
#fuses NOMCLR INTRC_IO
#usedelay(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 changevoid rb_isr(void){
hall = (input_b() >> 4) & 7;
if(Direction == 1)
output_d(MoveTable1[hall]);
else
output_d(MoveTable2[hall]);
clear_interrupt(INT_RB);
}
void main(){
setup_oscillator(OSC_8MHZ); // Set internal oscillator to 8MHz
setup_adc_ports(AN0); // Configure RA0 (AN0) pin as analog
output_b(0); // PORTB initial state
set_tris_b(0xF7); // TRISB configurartion
port_b_pullups(TRUE); // Enable PORTB internal pull-ups
output_d(0); // PORTD initial state
set_tris_d(0); // Configure PORTD pins as outputs
setup_adc(ADC_CLOCK_DIV_8); // Set ADC conversion time to 64Tosc
set_adc_channel(0); // Select channel 0 input
setup_timer_2(T2_DIV_BY_1, 199, 1); // Timer2 configuration for PWM
setup_ccp1(CCP_OFF);
enable_interrupts(GLOBAL); // Enable global interruptswhile(TRUE){
if(!input(PIN_B1)){ // If RB1 button pressedif(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;
output_d(MoveTable1[hall]);
}
}
if(!input(PIN_B2)){ // If RB1 button pressedif(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;
output_d(MoveTable2[hall]);
}
}
while(Direction != 0){
set_pwm1_duty(read_adc());
if(!input(PIN_B0)){
disable_interrupts(INT_RB); // Disable PORTB IOC
output_d(0);
setup_ccp1(CCP_OFF); // CCP1 OFF
Direction = 0;
}
}
}
}
BLDC Motor controller using PIC18F4550 and L293D video:
The following video shows project hardware circuit.
References: Microchip: Sensored BLDC Motor Control Using dsPIC30F2010 (AN957). Microchip: Brushless DC Motor Control Made Easy (AN857). L293D Datasheet.
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:
Complete circuit schematic is shown below:
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:
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.
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:
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>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#device ADC = 10
#usedelay(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 changevoid rb_isr(void){
hall = (input_b() >> 4) & 7;
if(Direction == 1)
output_d(MoveTable1[hall]);
else
output_d(MoveTable2[hall]);
clear_interrupt(INT_RB);
}
void main(){
output_b(0); // PORTB initial state
set_tris_b(0xF7);
port_b_pullups(TRUE); // Enable PORTB internal pull-ups
output_d(0);
set_tris_d(0);
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
enable_interrupts(GLOBAL);
while(TRUE){
if(!input(PIN_B1)){ // If RB1 button pressedif(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;
output_d(MoveTable1[hall]);
}
}
if(!input(PIN_B2)){ // If RB1 button pressedif(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;
output_d(MoveTable2[hall]);
}
}
while(Direction != 0){
set_pwm1_duty(read_adc());
if(!input(PIN_B0)){
disable_interrupts(INT_RB); // Disable PORTB IOC
output_d(0);
setup_ccp1(CCP_OFF); // CCP1 OFF
Direction = 0;
}
}
}
}
CD-ROM BLDC Motor control using PIC16F877A and L293D:
The following video shows project hardware circuit.
References: Microchip: Sensored BLDC Motor Control Using dsPIC30F2010 (AN957). Microchip: Brushless DC Motor Control Made Easy (AN857).
L293D Datasheet.
CD-ROM Sensored brushless (BLDC) motor control using PIC18F4550 microcontroller
This topic shows an easy way for controlling cd-rom drive (or dvd-rom) spindle motor using PIC18F4550 microcontroller.
There are different spindle motor types used in the cd-rom drives and the one used here is sensored brushless DC motor (BLDC motor), so be careful with your BLDC motor type and if it has less than 11 pins that means your motor is not concerned.
This motor is three phase motor, it has three stator phases that are excited two at a time to create arotating electric field. This method is fairly easy to implement, but to prevent the permanent magnet rotor from getting locked with the stator, the excitation on the stator must be sequenced in a specific manner while knowing the exact position of the rotor magnets.
The sensored BLDC motor has 3 hall effect sensors (Sensor A, Sensor B and Sensor C) to sense rotor position, this sensors are placed as shown in the following picture with pinout configuration:
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.
A three phase bridge is used to energize the BLDC motor windings.
Each phase driver requires 2 pins one for the high side and the other
one for the low side which means a total of 6 pins are required to
drive the three phase bridge. In this project 6 pins of PORTD will be
used.
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:
Table 1
Rotation direction2 is accomplished by driving current through the motor coils in the direction opposite of that for rotation direction1.
Table 2
CD-ROM sensored brushless DC (BLDC) motor speed and direction control using PIC18F4550 microcontroller:
The following image shows project circuit schematic diagram.
In the circuit there are 3 pushbuttons connected to RB0, RB1 and RB2. The buttons connected to RB1 and RB2 are for starting the BLDC motor direction1 or direction2, and RB0 button stops the BLDC motor.
Each hall effect sensor has 4 pins:
H+ and H- : sensor power supply pins
OUT+ and OUT- : sensor output pins.
For the system power supply there is +5V and +12V. The +12V supplies the 3 phase bridge circuit which is the same as the motor supply voltage.
LM339 consists of four independent precision voltage comparators. 3 camparators are needed for the 3 hall effect sensors as shown in the circuit schematic above. LM339 needs +5V power supply voltage which is connected as shown below:
74LS08 contains four independent 2-input AND gates. 3 AND gates are needed to make 3 PWM signals. The 74LS08 must be supplied with +5V as shown below:
CD-ROM sensored brushless DC (BLDC) motor control with PIC18F4550 microcontroller CCS PIC C compiler code:
This is the full code of this project. The code is small and not complicated.
RB interrupt on change (IOC) is used to interrupt when the rotor changes its position.
A potentiometer connected to analog channel 0 is used to control the BLDC motor speed in both directions.
// CD-ROM Sensored BLDC motor control with PIC18F4550 CCS C code// http://ccspicc.blogspot.com/// electronnote@gmail.com#include <18F4550.h>
#device ADC = 10
#fuses NOMCLR HSPLL PLL2 CPUDIV1
#usedelay(clock = 48000000)
#use fast_io(B)
#use fast_io(D)
int8 hall, Direction = 0;
constint8 MoveTable1[8] = {0, 33, 6, 36, 24, 9, 18, 0};
constint8 MoveTable2[8] = {0, 18, 9, 24, 36, 6, 33, 0};
#INT_EXT// External interrupt ISRvoid ext_isr(void){
disable_interrupts(INT_RB);
output_d(0);
setup_ccp1(CCP_OFF); // CCP1 OFF
Direction = 0;
clear_interrupt(INT_EXT);
}
#INT_RB// RB port interrupt on change ISRvoid rb_isr(void){
hall = (input_b() >> 4) & 7;
if(Direction == 1)
output_d(MoveTable1[hall]);
else
output_d(MoveTable2[hall]);
clear_interrupt(INT_RB);
}
void main(){
setup_adc_ports(AN0); // Configure RA0 (AN0) pin as analog
output_b(0); // PORTB initial state
set_tris_b(0xF7); // TRISB configurartion
port_b_pullups(TRUE); // Enable PORTB internal pull-ups
output_d(0); // PORTD initial state
set_tris_d(0); // Configure PORTD pins as outputs
setup_adc(ADC_CLOCK_DIV_64); // Set ADC conversion time to 64Tosc
set_adc_channel(0); // Select channel 0 input
setup_timer_2(T2_DIV_BY_16, 250, 1); // Timer2 configuration for PWM
setup_ccp1(CCP_OFF);
enable_interrupts(GLOBAL); // Enable global interrupts
enable_interrupts(INT_EXT); // Enable external interrupt
delay_ms(100); // Wait 100mswhile(TRUE){
if(!input(PIN_B1)){ // If RB1 button pressedif(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;
output_d(MoveTable1[hall]);
}
}
if(!input(PIN_B2)){ // If RB1 button pressedif(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;
output_d(MoveTable2[hall]);
}
}
while(Direction != 0){
set_pwm1_duty(read_adc());
}
}
}
CD-ROM BLDC motor control with PIC18F4550 microcontroller:
The following video shows a hardware circuit for this project.
References:
Microchip: Sensored BLDC Motor Control Using dsPIC30F2010 (AN957).
Microchip: Brushless DC Motor Control Made Easy (AN857).
Sensored BLDC motor control using PIC16F877A - CCS PIC C compiler
This topic shows an easy way to drive a Cd-Rom sensored brushless DC motor (BLDC motor) using PIC16F877A microcontroller with CCS PIC C code.
This motor is three phase motor, it has three stator phases that are excited two at a time to create arotating electric field. This method is fairly easy to implement, but to prevent the permanent magnet rotor from getting locked with the stator, the excitation on the stator must be sequenced in a specific manner while knowing the exact position of the rotor magnets.
The sensored BLDC motor has 3 hall effect sensors (Sensor A, Sensor B and Sensor C), this sensors sense the rotor position. 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.
A three phase bridge is used to energize the BLDC motor windings.
Each phase driver requires 2 pins one for the high side and the other one for the low side which means a total of 6 pins are required to drive the three phase bridge. In this project 6 pins of PORTD will be used.
The 3 hall effect sensors needs 3 pins and for that RB4, RB5 and RB6 are used.
A lookup table is used to commutate the motor driver according to the following table:
CD-ROM sensored brushless DC (BLDC) motor speed control with PIC16F877A microcontroller:
The following image shows project circuit schematic diagram.
LM339 consists of four independent precision voltage comparators. 3 camparators are needed for the 3 hall effect sensors as shown in the circuit schematic above. A +5V is needed for the LM339 chip as shown below:
74LS08 contains four independent 2-input AND gates. 3 AND gates are needed to make 3 PWM signals. The 74LS08 must be supplied with +5V as shown below:
The CD-ROM BLDC motor pin configurations is shown in the following image where the rotor has been removed :
In this BLDC motor each hall effect sensor has 4 pins:
H+ and H- : sensor power supply pins
OUT+ and OUT- : sensor output pins.
For the system power supply there is +5V and +12V. The +12V supplies the 3 phase bridge circuit which is the same as the motor supply voltage. CD-ROM sensored brushless DC (BLDC) motor control with PIC16F877A microcontroller CCS PIC C compiler code:
This is the full code of this project. The code is small and not complicated.
RB interrupt on change (IOC) is used to interrupt when the rotor changes its position.
A potentiometer connected to analog channel 0 is used to control the BLDC motor speed.
The PWM frequency is 500Hz and the duty cycle is related to analog channel 0 reading.
// CD-ROM Sensored BLDC motor control with PIC16F877A CCS C code// http://ccspicc.blogspot.com/// electronnote@gmail.com#include <16F877A.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#device ADC = 10
#usedelay(clock = 8000000)
#use fast_io(B)
#use fast_io(D)
int8 hall;
int8 MoveTable[8] = {0, 33, 6, 36, 24, 9, 18, 0};
int16 value;
#INT_RB// RB port interrupt on changevoid rb_isr(void){
hall = (input_b() >> 4) & 7;
output_d(MoveTable[hall]);
clear_interrupt(INT_RB);
}
void main(){
output_b(0); // PORTB initial state
set_tris_b(0xF3);
port_b_pullups(TRUE); // Enable PORTB internal pull-ups
output_d(0);
set_tris_d(0);
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_16, 250, 1); // Set PWM frequency to 500Hz
setup_ccp1(CCP_OFF); // CCP1 OFF
enable_interrupts(GLOBAL);
delay_ms(100); // Wait 100mswhile(TRUE){
if(!input(PIN_B0)){ // If RB0 button pressedif(input(PIN_B2)){ // Check if motor is already running
disable_interrupts(INT_RB);
output_d(0);
setup_ccp1(CCP_OFF); // CCP1 OFF
output_low(PIN_B2); // RB2 LED OFF
}
}
if(!input(PIN_B1)){ // If RB1 button pressedif(!input(PIN_B2)){ // Check if motor is already running
output_high(PIN_B2); // RB2 LED ON
clear_interrupt(INT_RB); // Clear RB IOC flag bit
enable_interrupts(INT_RB); // Enable PORTB IOC
setup_ccp1(CCP_PWM); // Configure CCP1 as a PWM
hall = (input_b() >> 4) & 7;
output_d(MoveTable[hall]);
}
}
if(input(PIN_B2)){
read_adc(ADC_START_ONLY);
while(!adc_done()); // Wait until conversion complete
value = read_adc(ADC_READ_ONLY); // Read ADC value
set_pwm1_duty(value); // Set PWM duty cycle
}
}
}
CD-ROM BLDC motor control with PIC16F877A microcontroller:
The following video shows a hardware circuit for this project..
References:
Microchip: Sensored BLDC Motor Control Using dsPIC30F2010 (AN957).
Microchip: Brushless DC Motor Control Made Easy (AN857).