Six-Step Sensorless BLDC Motor Drive Example Software For The STM32™
Six-Step Sensorless BLDC Motor Drive Example Software For The STM32™
User manual
Six-step sensorless BLDC motor drive example software for the
STM32™
Introduction
The example program is written specifically to run on the STEVAL-IHM040V1 board using
the STM32F100C8T6 but can be adapted to run on other STM32 microcontrollers with
minor modifications. The program is written in C and provides the main functions of
sensorless synchronization to the permanent magnet rotor position of a 3-phase BLDC
motor along with 3-phase bridge commutation, speed regulation, acceleration/deceleration
control, and gating control logic which is specific to the STMicroelectronics® SLLIMM™
module STGIPN3H60. The driving logic can be easily adapted to any monolithic or discrete
3-phase bridge which requires six logic control signals. Deadtime functionality is provided
within the STM32.
Contents
1 Theory of operation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
5 1 millisecond routine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
6 10 millisecond routine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Background code that runs every loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
8 Variable descriptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
10 Revision history . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19
1 Theory of operation
The structure of the program consists of a continuously running background loop with one
time driven interrupt. Pulse width modulation for the motor control and time base interrupt
are both implemented using the advance timer (Timer1) in the STM32. The time driven
interrupt is triggered once each period by Timer1 channel 4. The signal from channel 4
triggers the execution of the “PWM Interrupt Service Routine” (PWMISR) but is not seen on
any hardware output from the processor. PWMISR executes once each PWM cycle just
before the end of the cycle (during the “off” period, just before the start of the next cycle
when the transistors are turned back on). Having CH4 available on Timer1 along with the
3 PWM channels, which actually control the transistor bridge, gives the ability to precisely
place the synchronous execution of the PWMISR anywhere within the PWM period. The
primary function of the PWMISR is to sample the motor terminal voltage of the floating
phase in order to capture line to neutral back EMF (BEMF). This information is processed by
the STARTSTATE state machine (also in the PWMISR) in order to determine BEMF zero
crossings and, ultimately, bridge commutation timing. The PWMISR also handles startup
alignment and open loop ramp-up as well as motor current sampling. Since the PWM period
is fixed at 50 microseconds (20 KHz), the interrupt runs once every 50 microseconds and
serves as the timing heartbeat for the entire program.
The program also includes one event driven interrupt, the Timer1 break interrupt. Execution
of this interrupt service routine is triggered by a falling edge on the Timer1 break input pin,
which is a hardware indication of an uncontrolled overcurrent situation. This interrupt service
routine does nothing more than set the global overcurrent flag true. The outputs that drive
the inverter bridge are automatically set to their safe state via hardware within the STM32.
The background loop consists of non-critical code that runs at an uncontrolled rate
(once per loop) along with execution rate controlled sections that run at 100 microseconds,
1 millisecond, and 10 millisecond intervals. Execution of these routines is not directly driven
by a timer interrupt but is, instead, driven by the polling of individual software timers that are
updated by the PWMISR. In this way, we are assured that these routines will run, on
average, 10K, 1K, and 100 times per second but they do not present any interrupt priority
management issues.
The 100 microsecond routine has only one function, which is to implement a state variable
type observer which accepts the motor commutation step as its input (as determined by the
STARTSTATE state machine) and outputs an actual relative motor position, an observed
motor position, and an observed speed. The observed speed is used as feedback for the
speed regulator.
The 1 millisecond routine executes the timed overload function and the speed regulator. The
overload functions as a timed “pull back” type of controller which will decrease an overall
limit on applied duty cycle when the motor current exceeds the overload current threshold
for more than the allowable time. This allows the bridge to operate at higher current levels
for short time durations to allow for transient loads and motor acceleration, but prevents
operation at these levels for long periods that would eventually cause an overtemperature
condition on the SLLIMM module. The speed regulator monitors the speed reference and
speed estimate to determine a speed error and, from this, generates the commanded duty
cycle needed to keep the motor running at the desired speed. The speed regulator is
a conventional proportional plus integral type algorithm.
The 10 millisecond routine scales the speed command potentiometer (which is actually
sampled in the PWMISR) and also executes the acceleration/deceleration control algorithm
which translates the speed command (as received from the command potentiometer) to the
slew rate limited speed reference.
The free running section of the background loop manages the flashing LED display to
indicate fault status. The controlled execution rate sections of the background loop
(100 microsecond, 1 millisecond, and 10 millisecond) are triggered by use of the variables
heartbeat1time, heartbeat2time, heartbeat3time, and globalcounter. Globalcounter is
a 32-bit unsigned software timer which is incremented with each run of the PWMISR. Since
the PWMISR is timer controlled to run once each 50 microseconds, each “tick” of the
globalcounter is “worth” 50 microseconds. The globalcounter is continually incremented and
when it reaches the limit of its range, it will naturally roll over to zero and continue. Each time
one of the timed sections runs, it will “grab” the current value of globalcounter and save it in
its heartbeat (1, 2, or 3) time. Later, this heartbeat time (the time of the last execution) is
subtracted from the current time to calculate the time elapsed since the last execution.
When this elapsed time matches or exceeds the run period for a particular section, the
routine is executed. The 2's compliment arithmetic naturally handles any possible problems
arising from the roll over of globalcounter.
Each of the blocks of code is described by pseudocode in the following sections. Please
note that the double slash indicates that the remainder of the text line is a clarifying
comment for the reader.
Convert BEMF of floating phase via ADC and store in variable bemfsample
Increment zccounter, alignmentcounter, holdcounter, and ledtime while ADC is converting
(timers)
If (autostep flag is true) // ramping up or holding speed
{
Increment commcounter // measures time between steps in units of PWM periods
If (commcounter>step)
{
Commcounter = 0
Increment phase (rolling over to zero after five)
Increment position
Lookup TIM1_CCER value from table based on phase to commutate bridge
}
}
If (run flag is false) startstate = 0
Execute the startstate state machine
Determine and store ADC channel of BEMF to convert on next PWMISR run //
based on step
Convert motor current signal via ADC (with bipolar offset) and store in
variable ifb
Increment globalcounter while ADC is converting
Ifbsum = ifbsum + ifb // to be used in average current calculation
Increment ifbcount // to be used in average current calculation
Clear hardware interrupt
Demagcounter = 0
Demagthreshold = step * demagallowance/256
Advance case to 130
}
Case 130: // wait out demag time
Increment demagcounter
If (demagcounter>demagthreshold) advance case to 140
demagcounter = 0
demagthreshold = step * demagallowance/256
set state back to case 130 to wait out demag
If (phase = 0) // calculate current average over one cycle
{
ifbave = (ifbsum*4)/ifbcount // average current scaled for use by
overload routine
ifbcount = 0
ifbsum = 0
}
}
heartbeat1time = globalcounter
slong0 = position - (positionest/4096) // position observer error
(positionest scaled 4096X to improve resolution)
speedest = slong0
potitionest = positionest + speedest // integrate speedest to get
positionest
// check for and prevent eventual math rollover
If (positionest & 0x80000000) // if positionest is greater than ½ full scale
for variable size
{
positionest = positionest & 0x7FFFFFFF // subtract ½ full scale to prevent
eventual math rollover
position = position - 524288 // subtract ½ full scale / 4096 (to account for
scaling difference)
}
//************** end of 100 microsecond routine ****************
5 1 millisecond routine
heartbeat2time = globalcounter
// overlaod function
If (ifbave>overloadthreshold AND overload flag is false) overloadcounter =
overloadcounter + overloaduprate
else overloadcounter = overloadcounter - overloaddownrate
If (overloadcounter<0)
{
overloadcounter = 0
overloadflag = 0
}
If (overloadcounter>1,000,000) set overloadflag true
If (ifb>overloadsetpoint) AND overloadflag is true) overloaddclimit =
overloaddclimit-3
else overloaddclimit = everloaddclimit + 1
If (overloaddclimit>1000) overloaddclimit = 1000;
If (overloaddclimit<100) overloaddclimit = 100;
// limit integral term so that P + I will be less than the active duty cycle
limit
slong0 = activedclimit - propterm;
If (slong0<0) slong0 = 0; // slong0 holds maximum allowable intterm
slong0 = slong0 * intclampscaler; // slong0 holds max error integral
If (errorint>slong0) errorint = slong0;
If (errorint<0) errorint = 0;
intterm = (errorint*intgain)>>10; // apply integral gain
slong0 = propterm + intterm; // combine proportional and integral
If (slong0>activedclimit) slong0 = activedclimit;
If (slong0<100) slong0 = 100;
If (zcfound)
{
TIM1->CCR1= runningdc;
TIM1->CCR2 = runningdc;
TIM1->CCR3 = runningdc;
}
// ************** end of 1 millisecond routine *************************
6 10 millisecond routine
heartbeat3time = globalcounter;
potvalue = 4095 - adcread(2); // read pot channel
If (potvalue>200) set run flag true;
If (potvalue<100) set run flag false;
rpmcmd = potvalue*4;
If (rpmcmd<100) rpmcmd = 100;
// accel/decel control
slong0 = rpmcmd-rpmref;
If (slong0>acclim) slong0 = acclim;
If (slong0<-declim) slong0 = -declim;
rpmref = rpmref + slong0;
// ************** end of 10 millisecond routine *************************
8 Variable descriptions
overloadflag 8-bit logic flag If true, overload conditions exists and current is limited.
overcurrent 8-bit logic flag If true, overcurrent shutdown has occurred.
If true, the first BEMF zero crossing has been found, rotor sync. has been
zcfound 8-bit logic flag
established.
autostep 8-bit logic flag If true, system is either in ramping up or hold speed stepping mode.
run 8-bit logic flag If true, drive is either starting up or running.
risingedge 8-bit logic flag If true, looking for BEMF rising edge next, else looking for falling edge.
Used by the ledstate state machine to keep track of the number of LED
flashcounter 8-bit unsigned
flashes.
phase 8-bit unsigned Takes on the values from 0 to 5 to indicate the current commutation step.
Controls the delay from BEMF zero crossing detection (rising edge) until the
bridge is commutated. 0 to 255 represents 0 to 255/256 of a step (60 electrical
risingdelay 8-bit unsigned degrees). The nominal theoretical value is 128, which is 30 electrical degrees.
This is the phase shift between line to neutral ZC (which is sensed) and line to
line ZC, proper commutation time. Reducing will advance commutation timing.
Controls the delay from BEMF zero crossing detection (falling edge) until the
bridge is commutated. 0 to 255 represents 0 to 255/256 of a step (60 electrical
fallingdelay 8-bit unsigned degrees). The nominal theoretical value is 128, which is 30 electrical degrees.
This is the phase shift between line to neutral ZC (which is sensed) and line to
line ZC, proper commutation time. Reducing will advance commutation timing.
ledstate 8-bit unsigned State variable for the ledstate state machine.
flashcount 8-bit unsigned Set to command the required number of LED flashes to be displayed.
startstate 8-bit unsigned State variable for startstate state machine.
bemfchannel 8-bit unsigned Predetermined ADC channel of next BEMF (phase A, B, or C) to be sampled.
0 to 1200 represents 0 to 100% duty cycle. User designated max used to
maxdc 16-bit unsigned clamp the output of the speed regulator. This is superseded by a lower value in
case of overload.
0 to 1200 represents 0 to 100%. This is controlled by the overload function and
overloaddclimit 16-bit unsigned will be brought below the maxdc setting in case of overload, where it will
supersede.
0 to 1200 represents 0 to 100%. This will always be the lesser of maxdc or
activedclimit 16-bit unsigned
overloaddclimit and is always used as the actual limit.
0 to 4095 (ADC counts) represents 0 to 3.3 V DC. The current sensing signal
is read 1024 times at startup and averaged to determine this value. Since
ifboffset 16 -bit unsigned current is known to be zero, this represents the zero current offset of the
signal. During normal operation, this value is subtracted from each raw current
conversion to correct for the offset.
Used to measure the time delay from zero crossing to commutation. Each
commcounter 16-bit unsigned
count represents one PWM period or 50 microseconds.
Holds the last measured zero crossing to zero crossing interval. Each count
step 16-bit unsigned
represents one PWM period or 50 microseconds.
0 to 4095 (ADC counts) represents 0 to 3.3 V DC. This is the most recent
reading of motor terminal voltage from the floating phase. Scaling is 1 to 1 but
bemfsample 16-bit unsigned
the value is clamped in hardware since we are only looking for zero crossings
(positive or negative).
Used to measure the demag time allowance, which is the required waiting time
from commutation until valid BEMF sampling can resume. This allows time for
demagcounter 16-bit unsigned
the current in the floating phase to fall to zero. Each count represents one
PWM period or 50 microseconds.
Used to measure the time between zero crossings . Each count represents
one PWM period or 50 microseconds. zccounter value is incremented each
zccounter 16-bit unsigned
PWM cycle. Its value is transferred to step and it is cleared when ZC is
detected.
Most recent reading of command potentiometer. 0 to 4095 represents 0 to
potvalue 16-bit unsigned
100%.
0 to 1200 represents 0 to 100%. This is the actual duty cycle being applied to
runningdc 16-bit unsigned
the bridge when the motor is running.
Sets the time interval between zero crossing and commutation. Each count
commthreshold 16-bit unsigned
represents one PWM period or 50 microseconds.
Sets the time interval between commutation and the resumption of BEMF
demagthreshold 16-bit unsigned
sampling. Each count represents one PWM period or 50 microseconds.
Each “tick” is 1 millisecond. This software timer is used to measure out an
interval of 100 milliseconds after rotor sync. is achieved and before the speed
transitioncounter 32-bit unsigned
regulator is enabled, when the duty cycle is held constant to allow the system
to stabilize.
Each count is one step or 60 electrical degrees. This variable holds a relative
rotor position. It is incremented with each motor commutation but it is
position 32-bit unsigned
occasionally corrected so that it will not overflow. It serves as the primary input
to the speed observer.
This is a state variable of the speed observer. In the steady state, it will follow
positionest 32-bit unsigned
position but is scaled to be 4096 times bigger to enhance resolution.
Holds the value of globalcounter at the last execution of the 100 microsecond
heartbeat1time 32-bit unsigned routine. Each tick is one PWM cycle. It is used to control the execution rate of
the routine.
Holds the value of globalcounter at the last execution of the 1 millisecond
heartbeat2time 32-bit unsigned routine. Each tick is one PWM cycle. It is used to control the execution rate of
the routine.
Holds the value of globalcounter at the last execution of the 10 millisecond
heartbeat3time 32-bit unsigned routine. Each tick is one PWM cycle. It is used to control the execution rate of
the routine.
This is a global software timer which is incremented with each run of the PWM
globalcounter 32-bit unsigned interrupt service routine. It is a free running timer which is allowed to naturally
roll over.
This is a software timer that is used to measure the time that the motor is held
holdcounter 32-bit unsigned at a constant speed (in open loop stepping mode) at the end of the ramp-up
period, before BEMF sampling is commenced. Each “tick” in 50 microseconds.
This is a software timer that is used to measure the time that the motor is held
alignmentcounter 32-bit unsigned at the alignment stage before the ramp-up period. Each “tick” in 50
microseconds.
This variable controls the stepping rate during ramp-up. It increases in value
during ramp-up as the stepping rate is increased. The constant value of
rampspeed 32-bit unsigned
4,000,000,000 is divided by rampspeed to get the current step time (in units of
PWM cycles)
Used by the ledstate state machine to time out various time intervals. Each
ledtime 32-bit unsigned
“tick” is one PWM cycle.
speedest 16-bit signed Raw speed estimate output from speed observer.
Scaled speed derived from speedest and polepairs. Unit is revolutions per
rpm 16-bit signed
minute.
Raw, scaled RPM command. This is potvalue*4 so the range is 0 to 16,380.
rpmcmd 16-bit signed
Unit is revolutions per minute.
rpmref 16-bit signed Follows rpm cmd with a slew limit imposed.
Used to count the number of IFB samples summed into ifbsum. This is used
ifbcount 16-bit signed
during the calculation of ifbave.
Average motor current over one full electrical cycle. Used in overload
ifbave 16-bit signed
determination.
ifb 16-bit signed Most recent motor current sample.
Raw time integral of speed regulator error. This value is dynamically clamped
errorint 32-bit signed
so that the proportional plus integral sum does not exceed the duty cycle limit.
Summation of current samples taken in a given electrical cycle. It is used to
ifbsum 32-bit signed
calculate the average.
This variable is incremented and decremented in a weighted manner
depending on whether average current is above or below the overload
overloadcounter 32-bit signed
threshold. The value is clamped so that it cannot go below zero. When it
exceeds a fixed threshold, overload mode is initiated.
10 Revision history
Information in this document is provided solely in connection with ST products. STMicroelectronics NV and its subsidiaries (“ST”) reserve the
right to make changes, corrections, modifications or improvements, to this document, and the products and services described herein at any
time, without notice.
All ST products are sold pursuant to ST’s terms and conditions of sale.
Purchasers are solely responsible for the choice, selection and use of the ST products and services described herein, and ST assumes no
liability whatsoever relating to the choice, selection or use of the ST products and services described herein.
No license, express or implied, by estoppel or otherwise, to any intellectual property rights is granted under this document. If any part of this
document refers to any third party products or services it shall not be deemed a license grant by ST for the use of such third party products
or services, or any intellectual property contained therein or considered as a warranty covering the use in any manner whatsoever of such
third party products or services or any intellectual property contained therein.
UNLESS OTHERWISE SET FORTH IN ST’S TERMS AND CONDITIONS OF SALE ST DISCLAIMS ANY EXPRESS OR IMPLIED
WARRANTY WITH RESPECT TO THE USE AND/OR SALE OF ST PRODUCTS INCLUDING WITHOUT LIMITATION IMPLIED
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE (AND THEIR EQUIVALENTS UNDER THE LAWS
OF ANY JURISDICTION), OR INFRINGEMENT OF ANY PATENT, COPYRIGHT OR OTHER INTELLECTUAL PROPERTY RIGHT.
UNLESS EXPRESSLY APPROVED IN WRITING BY TWO AUTHORIZED ST REPRESENTATIVES, ST PRODUCTS ARE NOT
RECOMMENDED, AUTHORIZED OR WARRANTED FOR USE IN MILITARY, AIR CRAFT, SPACE, LIFE SAVING, OR LIFE SUSTAINING
APPLICATIONS, NOR IN PRODUCTS OR SYSTEMS WHERE FAILURE OR MALFUNCTION MAY RESULT IN PERSONAL INJURY,
DEATH, OR SEVERE PROPERTY OR ENVIRONMENTAL DAMAGE. ST PRODUCTS WHICH ARE NOT SPECIFIED AS "AUTOMOTIVE
GRADE" MAY ONLY BE USED IN AUTOMOTIVE APPLICATIONS AT USER’S OWN RISK.
Resale of ST products with provisions different from the statements and/or technical features set forth in this document shall immediately void
any warranty granted by ST for the ST product or service described herein and shall not create or extend in any manner whatsoever, any
liability of ST.
Information in this document supersedes and replaces all information previously supplied.
The ST logo is a registered trademark of STMicroelectronics. All other names are the property of their respective owners.