This project shows how to control a PC CD-ROM (or DVD-ROM) drive brushless motor (sensorless BLDC motor) using PIC16F887 microcontroller and L6234 3-phase motor driver.
This BLDC motor is the spindle motor of the CD-ROM drive and I chose it because it’s a low power BLDC motor which can be easily driven by the L6234 driver.
Related Projects:
The following topic contains more details about this project and BEMF technique.
Brushless DC motor control with PIC16F887 microcontroller
About L6234 3-phase motor driver:
The L6234 is a DMOSs triple half-bridge driver with input supply voltage up 52V and output current of
5A. It can be used in a very wide range of applications.
It has been realized in Multipower BCD60II technology which allows the combination of isolated DMOS
transistors with CMOS and Bipolar circuits on the same chip. It is available in Power DIP 20 (16+2+2)
and in Power SO 20 packages.
All the inputs are TTL/CMOS compatible and each half bridge can be driven by its own dedicated input
and enable.
The DMOS structure has an intrinsic free wheeling body diode so the use of external diodes, which are
necessary in the bipolar configuration, can be avoided. The DMOS structure allows a very low quiescent
current of 6.5 mA typ. at Vs=42V , irrespective of the load.
Block diagram:
L6234 Pin configuration:
The L6234 chip is available in 20 pin PowerDIP package (16+2+2) and in PowerSO20, each package has its pin configuration as shown below:
The L6234 driver has 3 outputs: OUT1, OUT2 and OUT3. Each output is controlled with 2 pins: input (IN) and enable (EN), for example OUT1 is controlled with IN1 and EN1. The figure below shows the control logic for each half-bridge:
Hardware required:
- PIC16F887 microcontroller — datasheet
- CD-ROM brushless motor
- L6234 three phase motor driver — datasheet
- 20 MHz crystal oscillator
- 2 x 1N4148 diode
- 6 x 33k ohm resistor
- 3 x 10k ohm resistor
- 4 x 1 ohm resistor (with 2 W or higher)
- 100 uF electrolytic capacitor (with 16V or higher)
- 1 uF electrolytic capacitor (with 16V or higher)
- 2 x 22pF ceramic capacitor
- 220 nF (0.22 uF) ceramic capacitor
- 100 nF (0.1 uF) ceramic capacitor
- 10 nF (0.01 uF) ceramic capacitor
- 10k ohm potentiometer
- 5V source
- 12V source
- Breadboard
- Jumper wires
Brushless motor control with PIC16F887 and L6234 driver circuit:
The following image shows project circuit diagram.
Note that all grounded terminals are connected together.
In this project we need two power sources, the first one with 5V and used to power the microcontroller. The other one with 12V which is used to power the L6234 driver and therefore the brushless motor.
The PIC16F887 runs with 20MHz crystal oscillator (5 MIPS), MCLR pin function is disabled.
Brushless motor control with PIC16F887 and L6234 driver code:
The C code below is for CCS C compiler, it was tested with version 5.051.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 | /************************************************************************************** Sensorless brushless DC ( BLDC ) motor control with PIC16F887 microcontroller and L6234 3-phase motor driver. Crystal oscillator used @ 20MHz. C Code for CCS C compiler. This is a free software with NO WARRANTY. http://simple-circuit.com/ ***************************************************************************************/ #define PWM_MIN_DUTY 200 #define PWM_START_DUTY 300L // Letter L for 'Long' (16-bit number) #include <16F887.h> #device ADC = 10 #fuses NOMCLR, HS, NOBROWNOUT, NOLVP #use delay(clock = 20MHz) #use fast_io(D) void AH_BL(); void AH_CL(); void BH_CL(); void BH_AL(); void CH_AL(); void CH_BL(); void bldc_move(); int8 bldc_step = 0; int16 motor_speed; #INT_COMP void comparator_isr() // Comparator ISR { // BEMF debounce for(int8 j = 0; j < 20; j++) { if(bldc_step & 1) { if(!C1OUT) j -= 1; } else { if(C1OUT) j -= 1; } } bldc_move(); clear_interrupt(INT_COMP); // Clear comparators interrupt flag } void bldc_move() // BLDC motor commutation function { switch(bldc_step) { case 0: AH_BL(); setup_comparator(CP1_B3_A3); // Sense BEMF C (pin RA3 positive, RB3 negative) break; case 1: AH_CL(); setup_comparator(CP1_A1_A3); // Sense BEMF B (pin RA3 positive, RA1 negative) break; case 2: BH_CL(); setup_comparator(CP1_A0_A3); // Sense BEMF A (pin RA3 positive, RA0 negative) break; case 3: BH_AL(); setup_comparator(CP1_B3_A3); // Sense BEMF C (pin RA3 positive, RB3 negative) break; case 4: CH_AL(); setup_comparator(CP1_A1_A3); // Sense BEMF B (pin RA3 positive, RA1 negative) break; case 5: CH_BL(); setup_comparator(CP1_A0_A3); // Sense BEMF A break; } bldc_step++; if(bldc_step >= 6) bldc_step = 0; } void main() { output_d(0); // PORTD initial state set_tris_d(0); // Configure all PORTD pins as outputs setup_timer_2(T2_DIV_BY_1, 255, 1); // Set PWM frequency to 19.53KHz and 10-bit resolution setup_adc(ADC_CLOCK_INTERNAL); // Set ADC module clock source to internal setup_adc_ports(sAN4); // Configure AN4 pin as analog set_adc_channel(4); // Select channel 4 (AN4) ENABLE_INTERRUPTS(GLOBAL); // Enable global interrupts ENABLE_INTERRUPTS(PERIPH); // Enable periphiral interrupts clear_interrupt(INT_COMP); // Clear comparators interrupt flag // Motor start set_pwm1_duty(PWM_START_DUTY); // Set PWM duty cycle int16 i = 5000; while(i > 100) { delay_us(i); bldc_move(); i = i - 20; } ENABLE_INTERRUPTS(INT_COMP); // Enable comparators interrupt while(TRUE) { READ_ADC(ADC_START_ONLY); // Start analog conversion delay_ms(50); // wait 50 ms motor_speed = read_adc(ADC_READ_ONLY); // Read conversion result if(motor_speed < PWM_MIN_DUTY) motor_speed = PWM_MIN_DUTY; set_pwm1_duty(motor_speed); // Set PWM duty cycle } } void AH_BL() { setup_ccp1(CCP_OFF); output_d(0x50); setup_ccp1(CCP_PWM| CCP_PULSE_STEERING_D); // PWM output on pin P1D (RD7), others OFF } void AH_CL() { output_d(0x30); } void BH_CL() { setup_ccp1(CCP_OFF); output_d(0x28); setup_ccp1(CCP_PWM| CCP_PULSE_STEERING_C); // PWM output on pin P1C (RD6), others OFF } void BH_AL() { output_d(0x88); } void CH_AL() { setup_ccp1(CCP_OFF); output_d(0x84); setup_ccp1(CCP_PWM| CCP_PULSE_STEERING_B); // PWM output on pin P1B (RD5), others OFF } void CH_BL() { output_d(0x44); } |
Brushless motor control with PIC16F887 and L6234 video:
The small video below shows my prototype hardware circuit.
Discover more from Simple Circuit
Subscribe to get the latest posts sent to your email.
How would I connect an AS5048 magnetic encoder to it which runs I2C?