Sensorless BLDC motor controller using PIC18F4550 microcontroller

With PIC18F4550 8-bit microcontroller we can easily build a simple ESC (Electronic Speed Controller) for brushless DC motors. This topic shows how did I made an ESC using the PIC18F4550 microcontroller and few other components.

First the brushless dc motor is a 3-phase motor comes in two main types: sensored and sensorless. The sensorless BLDC motor control technique is based on the BEMF (Back Electromotive Force) produced in the stator windings.

For more details about the sensorless BLDC motor and how to control it, see the following project:
Brushless DC motor control with PIC16F887 microcontroller

Hardware Required:

  • PIC18F4550 microcontroller
  • Brushless DC motor
  • 6 x 06N03LA N-type mosfet (or equivalent)  – datasheet
  • 3 x IR2101 (or IR2101S) gate driver IC  – datasheet
  • LM339 quad comparator IC
  • 6 x 33k ohm resistor
  • 6 x 10k ohm resistor
  • 6 x 10 ohm resistor
  • 3 x IN4148 diode
  • 3 x 10uF capacitor
  • 3 x 2.2uF capacitor
  • 8 MHz crystal oscillator
  • 2 x 22pF ceramic capacitor
  • 10k ohm potentiometer
  • 12V source
  • 5V source
  • Breadboard
  • Jumper wires

Sensorless BLDC motor controller using PIC18F4550 microcontroller circuit:
Circuit schematic diagram is shown below.

Brushless motor controller using PIC18F4550 ESC

Note that all grounded terminals are connected together.

As known the brushless motors are 3-phase motors. In the circuit diagram above the 3 phases are named: Phase A, Phase B and Phase C.

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 three-phase bridge and therefore the BLDC motor.

The first three 33k (connected to motor phases) and the three 10k resistors are used as voltage dividers, the other three 33k resistors generate the virtual natural point.

In this project we need 3 comparators to compare the BEMF of each phase with respect to the virtual natural point because we need to detect the zero crossing of each phase, here I used the LM339 quad comparator chip. The virtual point is connected to the inverting input ( – ) of the three comparators as shown in the circuit diagram above. BEMF A is connected to the non-inverting pin ( + ) of comparator number 2, BEMF B is connected to the positive terminal of comparator 1 and BEMF C is connected to the positive terminal of comparator 3. Comparator 4 is not used and all its terminals should be grounded.

As known the comparator output is logic 1 if the non-inverting voltage is greater than the inverting voltage and vice versa.

The LM339 outputs are open collector which means a pull up resistors are needed, for that I used three 10 K ohm resistors.

The outputs of the 3 comparators are connected to PIC18F4550 external interrupt pins INT0 (RB0), INT1 (RB1) and INT2 (RB2) respectively for BEMF A, BEMF B and BEMF C.

The PIC18F4550 microcontroller has one CCP (Capture/Compare/PWM) module and one ECCP (Enhanced CCP) module. The CCP module can generate one PWM signal on pin RC1. The ECCP module can generate two PWM signals on pin RD5 (full bridge reverse mode) and pin RD7 (full bridge forward mode). So with that we have 3 PWM signals which are then connected to HIN pins of the IR2101 gate drivers (pwming high side mosfets only).

In this project the PIC18F4550 microcontroller runs with 8 MHz crystal oscillator and MCLR pin function is disabled.

C Code:
The C code was tested with CCS C compiler version 5.051. The compiler may give a warning, it is not a problem at all, just ignore it!

As mentioned above the microcontroller runs with 8 MHz crystal oscillator, in the code the PLL is enabled (PLL2) which makes the CPU runs at 48 MHz (12 MIPS).

Timer2 module is configured to give a PWM signal with frequency of 46.875 KHz and resolution of 10 bits. The configuration line is:
setup_timer_2(T2_DIV_BY_1, 255, 1);
where Timer2 prescaler = 1, preload (PR2) = 255
PWM frequency and resolution can be calculated using the functions below (Fosc = 48 MHz):
PWM_freqency = Fosc/{[(PR2) + 1] * 4 * (TMR2 Prescale Value)} = 46.875 KHz
Resolution = log[4(PR2 + 1)]/log(2) = 10 bits

All PWM signals have the same frequency since they use the same timer module (Timer2).

Full C code is below with some descriptions through comments.

Finally the small video shows a simple hardware circuit of the project:


  1. hello,i’m azizah..can i know why i cannot run this coding..the coding become fatal error..i hope you can help..i’m very urgent to use this coding

    1. Use this code with CCS C compiler, you will get some errors if you’re using MPLAB XC8 or mikroC.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.