BLDC Control
BLDC Control
Master’s Thesis
presented by
I hereby declare in lieu of an oath that I have produced this work by myself.
All used sources are listed in the bibliography and content taken directly or
indirectly from other sources is marked as such. This work has not been
submitted to any other board of examiners and has not yet been published.
I am fully aware of the legal consequences of making a false declaration.
Eidesstattliche Erklärung
Ich versichere an Eides statt, dass ich die vorliegende Arbeit selbstständig
angefertigt habe. Alle benutzten Quellen sind im Literaturverzeichnis aufge-
führt und die wörtlich oder inhaltlich entnommenen Stellen als solche ken-
ntlich gemacht. Die Arbeit wurde bisher keiner anderen Prüfbehörde vorgelegt
und noch nicht veröffentlicht. Ich bin mir bewusst, dass eine unwahre Erk-
lärung rechtliche Folgen hat.
Place/Date Signature
There is no lack of time, there is lack of interest.
Because when one really wants something,
dawn becomes day, Tuesday becomes Saturday
and a moment becomes an opportunity.
Acknowledgements
I
Abstract
III
Contents
Preface I
Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . . . . I
Abstract . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . III
Contents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . VI
Glossary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . VIII
List of Tables . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . IX
List of Figures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . XII
List of Code Snippets . . . . . . . . . . . . . . . . . . . . . . . . . . XIII
1. Introduction 1
1.1. Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.2. Objective . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.3. BLDC Motor . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3.1. History . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.3.2. Operation of the BLDCM . . . . . . . . . . . . . . . . 3
Field Oriented Control . . . . . . . . . . . . . . . . . . 5
Hall effect sensors . . . . . . . . . . . . . . . . . . . . . 5
Sensorless control . . . . . . . . . . . . . . . . . . . . . 7
3. Implementation 21
3.1. The Capture/Compare Unit 6 . . . . . . . . . . . . . . . . . . 21
3.1.1. PWM generation . . . . . . . . . . . . . . . . . . . . . 22
3.2. Speed and current controller . . . . . . . . . . . . . . . . . . . 23
3.2.1. MAC unit . . . . . . . . . . . . . . . . . . . . . . . . . 24
3.2.2. Speed calculation . . . . . . . . . . . . . . . . . . . . . 26
Speed reference calculation . . . . . . . . . . . . . . . . 26
V
Motor speed calculation . . . . . . . . . . . . . . . . . 26
3.3. Hall sensor control . . . . . . . . . . . . . . . . . . . . . . . . 27
3.4. Sensorless control . . . . . . . . . . . . . . . . . . . . . . . . . 29
3.5. ADC measurements . . . . . . . . . . . . . . . . . . . . . . . . 30
3.6. Protections . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
3.7. Interrupts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
3.8. Transition from Hall to Sensorless mode . . . . . . . . . . . . 35
3.8.1. Situation A . . . . . . . . . . . . . . . . . . . . . . . . 36
3.8.2. Situation B . . . . . . . . . . . . . . . . . . . . . . . . 36
3.8.3. Situation C . . . . . . . . . . . . . . . . . . . . . . . . 36
3.8.4. Situation D . . . . . . . . . . . . . . . . . . . . . . . . 37
3.8.5. Software implementation of the transition . . . . . . . 37
3.9. Software design . . . . . . . . . . . . . . . . . . . . . . . . . . 39
References 41
Appendices 47
B. Flowcharts 117
B.1. Flowcharts of the control process . . . . . . . . . . . . . . . . 117
VI
Acronyms
µC Microcontroller
ADC Analog-to-Digital Converter
BEMF Back Electro-Motive Force
BLDC Brushless Direct Current
CAN Controller Area Network
CCU6 Capture/Compare Unit 6
CPU Central Processing Unit
TM
DAVE Digital Application Virtual Engineer
DC Direct Current
DSP Digital Signal Processing
EMF Electro-Motive Force
FOC Field Oriented Control
GPIO General Purpose Input/Output
GPT General Purpose Timer
HW Hardware
IGBT Insulated Gate Bipolar Transistor
IGCT Integrated Gate Commutated Thyristor
ITC Interrupt Controller
JTAG Join Test Action Group
LED Light-Emitting Diode
VII
MAC Multiply-Accumulate unit
MOSFET Metal-Oxide-Semiconductor Field-Effect Transistor
PEC Peripheral Event Controller
PI Proportional-Integral
PMSM Permanent Magnet Synchronous Machine
PWM Pulse-Width Modulation
RPM Revolutions Per Minute
SW Software
UART Universal Asynchronous Receiver-Transmitter
USB Universal Serial Bus
ZCP Zero-Crossing Point
VIII
List of Tables
2.1. Pin selection . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
IX
List of Figures
XI
B.12.Flowchart of Transition . . . . . . . . . . . . . . . . . . . . . . 129
B.13.Flowchart of CCU60_viNodeI2 . . . . . . . . . . . . . . . . . 130
B.14.Flowchart of Speed_calc . . . . . . . . . . . . . . . . . . . . . 131
B.15.Flowchart of CCU60_viNodeI3 . . . . . . . . . . . . . . . . . 132
B.16.Flowchart of Sensorless_calc . . . . . . . . . . . . . . . . . . . 133
B.17.Flowchart of ADC0_viSRN0 . . . . . . . . . . . . . . . . . . . 134
List of Code Snippets
2.1. User’s code gap example . . . . . . . . . . . . . . . . . . . . . 19
XIII
1
1. Introduction
1.1. Motivation
Electrical mobility consciousness has increased steadily over the past few
years. Seems that the use of electricity as power source is gaining credibility
and is settling on as the future substitute for fossil fuels for mobility, in favour
of a cleaner and better world.
Therefore, motion control plays a leading role in the future development
of this technology, due to the needs of an efficient drive with the best pos-
sible performance provided by a cost-effective solution, to make the most of
the available energy. But electrical mobility is not only related to ground
transportation, but all kinds of mobility, which have different issues and
challenges.
1.2. Objective
The aim of this project is to confront the problems that an electrical drive
can come across in an aircraft electrically propelled. In this case, the pos-
sibility of a failure of the position sensors is taken into account, and this
thesis is intended to find a suitable solution for the BLDC control, whether
the position sensors are functional or they break down. The implementation
of the project encompasses the pin selection for the hardware and the soft-
ware design for hall sensor mode or sensorless mode, as well as the detailed
explanation for further test and modification by future contributors to the
project.
CHAPTER 1. INTRODUCTION
2 1.3. BLDC MOTOR
1.3.1. History
CHAPTER 1. INTRODUCTION
1.3. BLDC MOTOR 3
The BLDC motor unlike a DC motor, does not use brushes for commuta-
tion, instead, they are electronically commutated. They have many advan-
tages over DC motors, some of them are [2]:
• High dynamic response.
• High efficiency.
• Long operating life.
• Lower operation noise.
• Higher speed range.
CHAPTER 1. INTRODUCTION
4 DC
2.1 Brushless 1.3. BLDC MOTOR
2 THEORIE
BLDC motors are synchronous motors, which means that the magnetic
gezeigt. Fürfield
einegenerated
kontinuierliche Drehung
by the stator des
and the Motorsfield
magnetic ist generated
es nötig die Leistungselektronik
by the rotor
rotate
sechs Mal mit at the einem
jeweils same frequency,
anderensoMOSFET-Paar
they do not experience slip as theDa
zu schalten. induction
mithilfe der Hall-
motors. To rotate the BLDC motor, the stator windings have to be energized
◦
sensoren sechs
in a Positionen mitonjeweils
sequence, based 60position.
the rotor Verschiebung dekodiert
A full rotation werden
period in können, werden
hall sensor
mode issoshown
die Hallsensoren in figure 1.1.
angebracht, dass mit einer Änderung einer Hallsensorkodierung eine
Änderung des MOSFET-Paars einhergeht.
GMR-Sensor Mithilfe von Hallsensoren ist es möglich die Rotorposition bei einer Pol-
haarzahl von eins auf sechs Stellen einzugrenzen. Für einfache Anwendungen, bei de-
nen Position nicht genauer benötigt
CHAPTERwird, reichen diese Informationen, um das richtige
1. INTRODUCTION
MOSFET-Paar anzusteuern. Steigen die Anforderungen an Position und Drehzahldyna-
mik, muss eine genauere Methode für Position- und Drehzahlbestimmung verwendet wer-
den. Eine Möglichkeit ist die Verwendung eines giant magnetoresistance (GMR)-Sensors.
Der GMR-Sensor nutzt den GMR-Effekt, der bei Strukturen mit wiederholenden Schich-
1.3. BLDC MOTOR 5
There are many ways to control a BLDC motor, each one with its advan-
tages and disadvantages, the most used are:
• Field Oriented Control (FOC) (Sinusoidal)
• Hall sensor control (Trapezoidal)
• Sensorless control (Trapezoidal)
These kinds of devices are based on Hall-effect theory, which states that if
an electric current-carrying conductor is kept in a magnetic field, the mag-
netic field exerts a transverse force on the moving charge carriers that tends
to push them to one side of the conductor. A build-up of charge at the sides of
the conductors will balance this magnetic influence producing a measurable
voltage between the two sides of the conductor. The presence of this mea-
surable transverse voltage is called the Hall-effect because it was discovered
by Edwin Hall in 1879.
Most BLDC motors have three Hall sensors inside the stator on the non-
driving end of the motor. Whenever the rotor magnetic poles pass near the
Hall sensors they give a high or low signal indicating the N or S pole is
passing near the sensors as shown in figure 1.2 [5]. Based on the combination
of these three Hall sensor signals, the exact sequence of commutation can be
determined.
Embedding the Hall sensors into the stator is a complex process because
any misalignment in these Hall sensors with respect to the rotor magnets
will generate an error in determination of the rotor position. To simplify the
CHAPTER 1. INTRODUCTION
6 1.3. BLDC MOTOR
process of mounting the Hall sensors onto the stator some motors may have
the Hall sensor magnets on the rotor, in addition to the main rotor magnets.
Therefore, whenever the rotor rotates the Hall sensor magnets give the same
effect as the main magnets. The Hall sensors are normally mounted on a
printed circuit board and fixed to the enclosure cap on the non-driving end.
This enables users to adjust the complete assembly of Hall sensors to align
with the rotor magnets in order to achieve the best performance [6].
A BLDC motor is driven by voltage strokes coupled with the rotor position.
These strokes must be properly applied to the active phases of the three-phase
winding system so that the angle between the stator flux and the rotor flux
is kept close to 90o to get the maximum generated torque. Therefore, the
controller needs some means of determining the rotor’s orientation/position,
the Hall-effect sensors.
The process of switching the current to flow through only two phases for
every 60 electrical degree rotation of the rotor is called electronic commuta-
tion. The motor is supplied from a three-phase inverter, and the switching
actions can be simply triggered by the use of signals from position sensors
that are mounted at appropriate points around the stator.
Such a drive usually also has a current loop to regulate the stator current,
and an outer speed loop for speed control. The speed of the motor can be
controlled if the voltage across the motor is changed, which can be achieved
easily varying the duty cycle of the PWM signal used to control the six
switches of the three-phase bridge. Only two inverter switches, one in the
upper inverter bank and one in the lower inverter bank, are conducting at
any instant. These discrete switching events ensure that the sequence of
conducting pairs of stator terminals is maintained [7].
One of the hall sensors changes the state every 60 electrical degrees of ro-
tation. Given this, it takes six steps to complete an electrical cycle. However,
one electrical cycle may not correspond to a complete mechanical revolution
of the rotor. The number of electrical cycles to be repeated to complete a
mechanical rotation is determined by the rotor pole pairs. For each rotor pole
pair, one electrical cycle is completed. The number of electrical cycles/ro-
tations equals the rotor pole pairs [2]. This sequence of conducting pairs is
essential to the production of a constant output torque.
In summary, permanent magnet motor drives require a rotor position sen-
sor to properly perform phase commutation, but there are several drawbacks
when such types of position sensors are used. The main drawbacks are the
increased cost and size of the motor, and a special arrangement needs to be
CHAPTER 1. INTRODUCTION
1.3. BLDC MOTOR 7
made for mounting the sensors. Further, hall sensors are temperature sensi-
tive and hence the operation of the motor is limited, which could reduce the
system reliability because of the extra components and wiring [8]. To reduce
cost and improve reliability such position sensors may be eliminated. To this
end, many sensorless schemes have been reported for position (and speed)
control of BLDC motors [9].
One of the advantages of this control is that, with only two phases con-
ducting the motor can rotate and with the hall sensor signals the position
and speed can be calculated, so the Microcontroller (µC) does not need a
large computing capability as the ones used for FOC, reducing the final cost.
If sensors are used for FOC, normally they are more expensive than hall ef-
fect sensors, but also more precise, such as incremental encoders or resolvers.
The ease of control and the good performance/cost ratio makes the use of
hall effect sensors one of the most used control techniques for BLDC motors.
Sensorless control
Problems with the cost and reliability of rotor position sensors have moti-
vated research in the area of position sensorless BLDC machine drives. The
sensorless control does not use any position sensor, it is based on the mea-
surement of the non-conducting phase of the motor and the commutation
time is calculated based on the Back Electro-Motive Force (BEMF). The
BEMF in a BLDC motor is trapezoidal, as seen in figure 1.3, whereas in
PMSM is sinusoidal. A BLDC motor can be driven with sinusoidal currents
and a PMSM can be driven with direct currents, but for better performance,
PMSM should be excited by sinusoidal currents and BLDC motors by direct
currents.
CHAPTER 1. INTRODUCTION
8 1.3. BLDC MOTOR
Figure 1.3.: Variation of the BEMF in the phases of a BLDC motor [12]
CHAPTER 1. INTRODUCTION
1.3. BLDC MOTOR 9
E = 2N lrBω (1.1)
where N is the number of winding turns per phase, l is the length of the
rotor, r is the internal radius of the rotor, B is the rotor magnet flux density
and ω is the motor’s angular velocity.
The main objective in this sensorless control is to detect the ZCP. The ZCP
is where the BEMF value is null, which occurs 30o after the commutation,
thus, at half time between two commutations.
In figure 1.4 is depicted the motor terminal model, where Lx is the phase
inductance, R is the phase resistance, E is the BEMF, Vn and Vx are, re-
spectively, the star connection and phase voltages referenced to ground [14].
CHAPTER 1. INTRODUCTION
10 1.3. BLDC MOTOR
Ix Lx Ex
Vx Vn
As phase C is not conducting, the current flows only through phase A and
B. Therefore:
Ia = −Ib
Including this into the above equations and adding the three terminal
voltage equations, the result is:
Va + Vb + Vc = Ea + Eb + Ec + 3Vn
As was depicted in figure 1.3, at the ZCP the sum of the three BEMF is
null, then the above equation can be rewritten as:
Va + Vb + Vc = +3Vn (1.3)
At ZCP the BEMF of phase C is also 0, so its phase equation is equal to:
CHAPTER 1. INTRODUCTION
1.3. BLDC MOTOR 11
Vc = Vn (1.4)
Inserting equation 1.4 in equation 1.3 and assuming that high-side Metal-
Oxide-Semiconductor Field-Effect Transistor (MOSFET) of phase A and low-
side MOSFET of phase B are closed, the final equation is:
VDC + 0 + Vc = +3Vc
where Vc at the ZCP is finally:
VDC
Vc = (1.5)
2
So, as seen in equation 1.5, the Software (SW) in the implemented sensor-
less control will detect the ZCP when the phase voltage is half of the DC link
and proceed to calculate the time for the next commutation period. This
process will be explained in detail in section 3.4.
CHAPTER 1. INTRODUCTION
2. Hardware and software tools
The hardware used in this thesis is the Infineon Thechnologies’ Easy Kit
XE167F depicted in figure 2.1. This kit includes a µC from the XE166
family, the XE167F-96F66F and many peripherals such as an on board Uni-
versal Serial Bus (USB) to Join Test Action Group (JTAG)/Universal Asyn-
chronous Receiver-Transmitter (UART) interface, a potentiometer, a push-
button, Light-Emitting Diodes (LEDs) and the documentation and examples
needed for a quick start [15].
13
14 2.1. XE167F EASY KIT
2.1.1. XE167F-96F66F
The XE167F Easy Kit board includes all the necessary peripherals to per-
form a complete motion control chain. It includes two connectors BU101 and
BU102 specially designed to act as the interface to a power board for motion
control [15]. The Easy Kit board is shown in figure 2.3.
To develop the software, it is necessary to first select the needed pins. The
needs of the control are:
• 6 PWM signals
– 3 for high-side MOSFETs
– 3 for low-side MOSFETs
• 7 ADC channels
– 3 for phase voltages
– 1 for DC link voltage
– 1 for DC link current
– 2 for phase currents (for future FOC implementation)
• 3 pins for protection
– 1 for overvoltage
– 1 for overtemperature
– 1 for a driver error latch
• 3 inputs for hall sensors
To select the most suitable pins of the µC, the before mentioned connectors
BU101 and BU102 are used. The final pin selection, with their function and
connector of the board is detailed in the table 2.1.
Once the pins have been selected, the next step is to configure the periph-
erals of the µC to use this pins with their corresponding function.
TM
2.2. DAvE version 2
TM
Digital Application Virtual Engineer (DAVE ) is a free application with
which the user can start developing the code for the µC. It provides a visual
interface that makes it easier to configure the different peripherals and ini-
tialise the desired application, generating the needed C-code with the main
driver functions and interrupts. The main screen of the XE167F-96F66F
TM
in the DAVE environment is depicted in figure 2.4. In this project, the
TM
second version of DAVE generation tools is used, because it is the one
compatible with the XE166 family [17].
This programm will generate the main function and the peripheral initial-
isation as well as the interrupt functions, so there is only the need to create
the application specific code inside the generated functions. For that pur-
pose, the generated files include gaps where the user can introduce its own
TM
code, so that, if the DAVE project is modified, this code will stay intact.
This gaps are implemented as in listing 2.1:
TM
Once the peripherals are configured with the DAVE environment, the
application code must be added and edited in the C compiler. Infineon
products can be programmed in many development environments, but the
most common used are Tasking and Keil.
2.3. Keil
To develop all the code and compile the software, the latest version of the
Keil compiler (Keil µVision3) is used. This software includes the necessary
TM
files to program the µC and can directly import a DAVE project.
This is the last step of the tool chain, where finally the code is devel-
oped and loaded into the µC. The programming environment is depicted in
figure 2.5.
In this chapter are explained the main parts of the developed code, such
as the use of the CCU6, the speed and current controllers, the two control
modes, protection routines and the transition between control modes.
The most important peripherals used to develop the software are the ADCs
and the CCU6, the ones that receive the signals to decide the commutation
time and allow the protection interrupt routines and fast output responses.
21
22 3.1. THE CAPTURE/COMPARE UNIT 6
The control method in both hall sensor mode and sensorless mode is with
unipolar PWM. This means that only the high-side MOSFET is modulated
when it is enabled, whereas the low-side MOSFET stays closed the whole
period. Unipolar switching mode reduces electromagnetic noise, DC bus
ripple and commutation losses because there is less switching [20]. As most
of the time the motor will run with hall sensors active, this method will be
implemented as the primary control, while the sensorless control will only
take part if the hall sensors fail.
The modulation is done with the T13, and the channels which are allowed
to be modulated by the T13 are configured in the register CCU60_MODCTR
shown in figure 3.2.
CHAPTER 3. IMPLEMENTATION
3.2. SPEED AND CURRENT CONTROLLER 23
The even bits of the T13MODEN correspond to the outputs CC6x, while
the odd bits to the COUT6x. So the final configuration for the register is as
in listing 3.1.
The high-side MOSFET will be closed when the T13 value is over the
compare register CCU60_CC63R, as shown in figure 3.3.
COUT60
CC60
COUT61
CC61
COUT62
CC62
CC63
The speed and current controller are both implemented using the common
used Proportional-Integral (PI) controller, but in a cascade control system.
A cascade control is characterized by a master control loop (the outer and
slower one) and a faster, slave, inner loop. The cascade control inner loop
compensates for specific disturbances at source and largely prevents them
from affecting the process being controlled, improving considerably the dy-
namic response. To implement a cascade control, the inner loop must have
a faster response than the outer loop, at least 3-5 times faster [21]. This is
permits that, in an electric motor, the speed can be the outer or primary loop
and the current can be the inner or secondary loop, due to the fact that the
CHAPTER 3. IMPLEMENTATION
24 3.2. SPEED AND CURRENT CONTROLLER
electrical time constant is normally much more smaller than the mechanical
time constant. A block diagram of a cascade loop is depicted in figure 3.4.
+ PI + PI PWM/ Va
V
ωref ωerr iref ierr α b BLDC
controller controller Driver Vc
- -
ω i
The speed PI controller will execute every 1 ms, whereas the current PI
every 50 µs, synchronised with the T13 period match.
The cascade control implementation in software uses the MAC unit of the
µC. The MAC unit enhances strongly the DSP performance and 32 bit data
processing capability. It is a built-in unit in the CPU core, which means
that can be considered as an additional arithmetic unit dedicated for Digital
Signal Processing (DSP) and 32 bit calculation. In the execution stage of
the instruction processing pipeline, the instruction will be put into the ALU
or MAC unit to be executed according to which instruction set (normal or
MAC) the code comes from. If the instruction comes from normal instruction
set, the code execution will be done in the ALU unit. If the instruction is
from the MAC instruction set with CoXXX prefix, this instruction will be
processed in the MAC unit [22].
Infineon and Keil provides a library with many mathematical functions
which use this unit to reduce the calculation time in complex routines. In this
project some of these functions are used, i.e. the pi_controller64 function.
This function calculates the output of a PI controller whose inputs and output
are in 1Q15. The calculation is done in only 42 clock cycles, which means
only 636,4 ns.
Listing 3.2 shows the code where the PI is implemented. See that is totally
implemented in assembler and the commands used are referenced to the MAC
unit.
CHAPTER 3. IMPLEMENTATION
3.2. SPEED AND CURRENT CONTROLLER 25
CHAPTER 3. IMPLEMENTATION
26 3.2. SPEED AND CURRENT CONTROLLER
In both control methods, the speed reference is not set directly, but con-
stantly increased or decreased as a ramp. This makes that the controller
follows the new vale avoiding oscillations and great current spikes due to big
accelerations or decelerations. The RampUp() and Speed_ref_ramp() func-
tions are the ones that compute this constant approach to the end reference
value.
The function RampUp() will increment the counter every T13 period match,
i.e. every 50 µs, and when the counter value is equal to the predefined
time step, it will call the Speed_ref_ramp() and reset the counter. Inside
the Speed_ref_ramp(), the speed reference used in the PI is incremented or
decremented if it is not equal to the end reference (the final value to achieve).
The RampUp function also recalculates the time step necessary if the end
reference is modified, in order to reach the end value in the predefined time
stored in the variable rampup_time.
60
n= (3.1)
speed_buf f ∗ T 12resolution
CHAPTER 3. IMPLEMENTATION
3.3. HALL SENSOR CONTROL 27
However at the beginning there are not enough samples to implement the
average of the speed, so only the sector time is used, and the equation to
convert it to RPM is slightly different:
60
n=
sector_time ∗ 6 ∗ P p ∗ T 12resolution
The main control of the motor will be with the hall sensors active. The
hall sensor signals are connected to pins 10.7, 10.8 and 10.9 as shown in ta-
ble 2.1. In this mode, the timer T12 is configured as a timer, the registers
CCU60_CC61 and CCU60_CC62 as compare registers, and the CCU60_CC60
as a capture register, which will read the hall sensors input. In table 3.1, the
different registers and its function are listed.
The timer T12 clock frequency will be 1/256 the Central Processing Unit
(CPU) clock frequency, whereas the T13 will have the same clock as the
CPU. This makes the period of T13 to be short enough to modulate the
output signals between commutation (fpwm = 25 kHz), while the timer T12
can be used to measure the speed without overflowing too fast.
CHAPTER 3. IMPLEMENTATION
28 3.3. HALL SENSOR CONTROL
After a short time to avoid noise in the sensor signals, the commutation is
requested when CCU60_CC61 compare register is matched and is synchro-
nized at T13 one match. The speed calculation is done when T12 equals
CCU60_CC62 compare register [23].
Stores-value-in-
CC60_R Period-time-out-
and-reset-the-timer- error
T12PR
Launches-speed-
calculation
CC62_R
CC61_R
Commutation-
after-short-time
CCPOSx
1 0
COUT6x
This values are stored in the variable SP_Tab_r_l. Each element of this
variable consists of the current hall signal, the expected hall signal and the
corresponding output. The order of the table is selected so, for an index
equivalent at the actual hall sensor state, it returns the next commutation
pattern. So a load of the next pattern is done as in listing 3.3.
CHAPTER 3. IMPLEMENTATION
3.4. SENSORLESS CONTROL 29
For the sensorless control we also use the T13 and T12 of the CCU6 with
the same configuration. But the registers are not configured as in hall sensor
mode, therefore, they are all in compare mode. Despite this change, the
CCU60_CC61 and CCU60_CC62 have the same function as in hall sensor
mode, in order to make the two control methods as much code-compatible
as possible [24].
The difference in this method is that the speed is not calculated between
commutations, but between ZCPs. Also the timer T12 is restarted after
detecting a ZCP. As was deduced in equation 1.5, the ZCP is reached when
the non-fed phase voltage equals half of the DC link voltage. When this it is
detected, the software will recalculate the next commutation time and store
it in CC60_CC61R, to request the commutation at the required moment.
The CC60_CC62R, which triggers the interrupt for the speed calculation,
has a value a little bit higher than CC60_CC61R, the same as in hall sensor
mode. The T12PR is still used to trigger a time-out error interrupt if needed.
To detect the ZCP, many measures must be done during each sector. These
measures can not be done randomly, because the measured value may not be
always appropriate. To evaluate the BEMF properly, the voltage measure-
ment must be done while the two phases are conducting, that is, after the
compare match of T13. The performance in sensorless mode is illustrated in
figure 3.6.
It is also important, that the BEMF measurement do not start just after
the commutation, since the commutation spikes could lead to a false ZCP,
this is achieved by the delay between CC60_CC61R and CC60_CC62R,
making CC60_CC62R set the start of a slope 0 (rising) or 1 (falling). The
code in 3.4 shows how inside the interrupt the corresponding slope, based on
the previous ZCP detection, is set. More detailed explanation in appendix B.
CHAPTER 3. IMPLEMENTATION
30 3.5. ADC MEASUREMENTS
StoresUvalueUinUCC60_R,U PeriodUtime-outU
resetUtheUtimerUT12UandUloadU error
CC61_R
T12PR
LaunchesUspeedU
calculation
CC62_R Dead-timeUwhereUBEMFU
CC61_R }U
valuesUareUignoredU
ZCP ZCP
COUT6x
CommutationUatU
CC61_RUmatch
Figure 3.6.: T13 operation in Sensorless mode
CHAPTER 3. IMPLEMENTATION
3.5. ADC MEASUREMENTS 31
the time requirements, the table 3.3 shows when each channel is converted.
The figure 3.7 show the ADC conversions synchronised with the T13 during
the switch pattern A+ B-, that is, measuring BEMF of phase C.
COUT60
CC61
Delay 4us
ADC0
IDC
ADC1
VC
VDC
T13
CC63
As can be seen in figure 3.7, although the conversions of the phase voltages
samples are synchronised with the T13 compare match, there is a delay
between the compare event and the start of the conversion. This delay is
done in order to avoid the noise detection caused by the commutation of
the MOSFETs, as shown in figure 3.8, and to take into account the delay
introduced by the optocoupler used in the hardware to isolate the ADC from
the high voltage circuit.
This delay introduced by the optocoupler has been measured and is equal
to 4µs, so it is necessary to add a delay by software, to select the appropri-
CHAPTER 3. IMPLEMENTATION
32 3.5. ADC MEASUREMENTS
ate time, the number of cycles used to service the interrupt and start the
conversion must be taken into account:
The 4µs delay is equivalent to 264 clock cycles, which means that the delay
function must last:
To implement this delay this the function _nop_() is used, which is equal to
1 cycle delay. Taking into account the optimization level and the loop check,
the final loop implemented is in the listing 3.5.
for(x=0; x<200; x++) {
_nop_(); // No
operation function delay
}
Listing 3.5: Forced delay for a correct BEMF measurement
CHAPTER 3. IMPLEMENTATION
3.6. PROTECTIONS 33
3.6. Protections
The protection routines are the most important, because they prevent the
motor from being damaged. There are many different errors that can cause
permanent damage to the motor, so the software must identify and prevent
the damage by stopping the motor if any error signal is detected and register
which fault caused the motor to stop. In table 3.4 are listed the errors and
how are they handled by the software.
Error Handled by
Overcurrent ADC0_SRN0INT (Over specified limit)
Overvoltage Main loop
Overtemperature Main loop
Driver error CCU60_IS_TRPF (TRAP)
Time-out CCU60_IS_T12PM (T12 Period match)
Wrong Hall Event CCU60_IS_WHE
Most of the error signals will stop the motor in case they are latched, with
the exception of the overcurrent and wrong hall event erros. The overcurrent
interrupt will check the value of the measured current and, if its inside a
specified limit, it will not stop the motor until a predefined amount of time
is exceeded, avoiding a motor stop only if momentary current peaks occur.
The wrong hall event error occurs when the hall sensor signals fail, in this
case, before stopping the motor, the software will try to change to sensorless
control if possible. This error is the purpose of the thesis and is treated into
detail in section 3.8.
3.7. Interrupts
The architecture of the XE167F supports several mechanisms for fast and
flexible response to service requests from internal or external sources:
• Interrups generated by the Interrupt Controller (ITC)
• DMA transfers issued by the Peripheral Event Controller (PEC)
• Traps caused by the TRAP instruction or system specific states
CHAPTER 3. IMPLEMENTATION
34 3.7. INTERRUPTS
The selection of the interrupts and their routines is one of the most im-
portant parts of the application, due to the fact that being two different
control methods, both need to work with the same interrupts and with as
much code-sharing as possible to allow a fast transition from one control to
the other and reduce the size of the final application.
CHAPTER 3. IMPLEMENTATION
3.8. TRANSITION FROM HALL TO SENSORLESS MODE 35
A B C D
Expected0next0
commutation
Slope0=000or0Slope0=01
BEMF0not0detected0yet0in0 Slope0=020or0Slope0=03
this0sector BEMF0already0detected0
in0this0sector
ZCP
CC62R
CC61R
Last0correct0hall0
event
CHAPTER 3. IMPLEMENTATION
36 3.8. TRANSITION FROM HALL TO SENSORLESS MODE
3.8.1. Situation A
This situation can occur if, after a correct hall input, the sensors stop
working without having been done the commutation. If that happens, the
software has to force the commutation, load the next pattern and reconfigure
the timers and registers for the sensorless mode.
The reconfiguration of the registers is the same in all the possible situa-
tions, since it disables the hall sensor mode and enables all the registers as
in compare mode. It also disables the wrong hall event interrupt.
To restart the timer, as the BEMF has not been detected yet, the timer
T12 must be loaded with half of the sector time, which corresponds to the
actual value of zc, since instead of measuring time between ZCP, as the timer
is restarted every commutation, only stores half of the time between ZCP.
Therefore, the timer T12 is restarted with the variable zc plus the actual T12
value.
3.8.2. Situation B
In situation B, the only difference is that the commutation has already been
done, so there is no need to do it. The transition is done by reconfiguring
the registers, loading the next pattern and restarting the timer T12 as in
subsection 3.8.1. Neither in situation A nor in situation B the compare
registers CCU60_61R and CCU60_62R need to be modified, given that as
the BEMF has not been detected yet, the sensorless software control will
change them when it is detected.
3.8.3. Situation C
This stretch is the last stretch where the BEMF has not been detected.
Unlike the previous situations, the commutation and load of the next pattern
has already been done, so the routine only have to reconfigure the registers
and reload the timer T12 as in subsection 3.8.1.
CHAPTER 3. IMPLEMENTATION
3.8. TRANSITION FROM HALL TO SENSORLESS MODE 37
3.8.4. Situation D
The last stretch corresponds to the region where the BEMF has already
been detected, so in this case the compare registers must be reloaded to do
the next commutation and the timer is reset to a different value than in the
previous situation, due to the fact that now it will directly measure the time
between ZCP. In this case, the timer T12 is reset with the actual value of
T12 minus the actual zc value.
CHAPTER 3. IMPLEMENTATION
38 3.8. TRANSITION FROM HALL TO SENSORLESS MODE
}
if(bemf_aux < CCU60_CC62R) // If the update of the pattern
was not done yet...
{
CCU60_MCMOUTS = CCU60_MCMOUTS = SP_Tab_r_l[((CCU60_MCMOUT
& 0x3800) >> 11) + direction]; // ... load next
commutation pattern.
}
}
else // If bemf has already been detected in this sector...
{
CCU60_T12MSEL = 0x0111; // ... change hall sensor mode
to sensorless mode.
CCU60_IEN &= 0x97FF; // ... disable wrong hall event
or idle interrupts.
CCU60_TCTR4 = 0x0045; // ... T12 reset and stop.
CCU60_T12 = bemf_aux - zc_time; // ... set the
counter time to the difference between the actual value
and half the sector time.
CCU60_T12PR = (zc_time << 1) + zc_time; // ... set the
time out limit to 1.5 the sector time.
CCU60_CC60SR = (zc_time << 1); // ... set the CC60R for
speed measurement with the time between zero crossing
points.
CCU60_CC61SR = zc_time - 5; // ... initialize the CCU61
register with half of the time between zero crossings,
// so that it commutates within the required time (with an
advance).
CCU60_CC62SR = CCU60_CC61SR + 10; // ... initialize CCU62
some time after to calculate the speed.
CCU60_TCTR4 = 0x0040; // ... shadow transfer request for
T12.
CCU60_TCTR4 = 0x0002; // ... start T12.
}
}
else // If bemf detection is not possible...
{
Motor_stop(); // ... stop the motor.
}
// USER CODE END
CCU60_ISR |= 0x2000; // ... clear flag CCU60_IS_WHE.
}
CHAPTER 3. IMPLEMENTATION
3.9. SOFTWARE DESIGN 39
CHAPTER 3. IMPLEMENTATION
References
41
42 References
less motor using pll and third harmonic back emf. Industrial Electronics,
IEEE Transactions on, 53(2):421–428, 2006.
[11] JX Shen, ZQ Zhu, and David Howe. Sensorless flux-weakening control of
permanent-magnet brushless machines using third harmonic back emf.
IEEE Transactions on Industry Applications, 40(6):1629–1636, 2004.
[12] Daniel Torres. Sensorless BLDC Motor Control with Back-EMF Filter-
ing Using a Majority Function. Digi-Key Article Library, October 2011.
Contributed By Convergence Promotions LLC.
[13] U. Vinatha, S. Pola, and K.P. Vittal. Recent developments in con-
trol schemes of bldc motors. In Proceedings of the IEEE International
Conference on Industrial Technology (ICIT 2006), Mumbai, India, De-
cember 2006.
[14] Bilal Akin and Manish Bhardwaj. Sensorless Trapezoidal Control of
BLDC Motors. Texas Instruments Incorporated, 655303, Dallas, Texas
75265, July 2013. SPRABQ7.
[15] Infineon Technologies AG, 81726 Munich, Germany. XE166 family Easy
Kit Manual, 2007-06 edition, June 2007.
[16] Infineon Technologies AG, 81726 Munich, Germany. XE167 Datasheet,
2008-08 edition, August 2008.
[17] Infineon DAvE information website. http://www.infineon.com/cms/
en/product/microcontrollers/development-tools,-software-
and-kits/dave-tm-version-2-low-level-code-generation/
channel.html?channel=db3a3043134dde6001134ee4d3b30265.
[18] Infineon Technologies AG, 81726 Munich, Germany. Technical details
on CAPCOM6 module, January 2001. AP1607310.
[19] Infineon Technologies AG, 81726 Munich, Germany. XE166 Derivatives
Volume 2: Peripheral Units, 2008-08 edition, August 2008. User’s Man-
ual, V2.1.
[20] Eduardo Viramontes. BLDC Motor Control with Hall Effect Sensors
Using the 9S08MP. Systems and Applications Engineering Freescale
Technical Support, April 2010. AN4058.
[21] Peter Thomas. How to tune cascade loops. Control Specialists Ltd.,
expertune user conference edition, April 2007.
References
[22] Infineon Technologies AG, 81726 Munich, Germany. DSP Optimization
Guide for XC2000, XE1 6 6 and XC166 Microcontroller Families with
MAC Unit, 2007-10 edition, October 2007. APP1611311.
[23] Infineon Technologies AG, 81726 Munich, Germany. Speed control
of Brushless DC motor with Hall sensor using DAvE Drive for In-
fineon XC164CM/CS microcontrollers, 2007-07-04 edition, July 2007.
AP1611710.
[24] Infineon Technologies AG, 81726 Munich, Germany. Sensorless Control
of BLDC Motor using XE164F Microcontroller, 2010-03 edition, March
20110. AP16173.
[25] Infineon Technologies AG, 81726 Munich, Germany. XE166 Derivatives
Volume 1: System Units, 2008-08 edition, August 2008. User’s Manual,
V2.1.
43
Appendices
45
Appendix A.
47
48
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\MAIN.C
//****************************************************************************
// @Module Project Settings
// @Filename MAIN.C
// @Project Aircraft.dav
//----------------------------------------------------------------------------
// @Controller Infineon XE167F-96F66
//
// @Compiler Keil
//
// @Codegenerator 2.2
//
// @Description This file contains the project initialization function.
//
//----------------------------------------------------------------------------
// @Date 26/08/2014 17:45:06
//
//****************************************************************************
//****************************************************************************
// @Project Includes
//****************************************************************************
#include "MAIN.H"
//****************************************************************************
// @Macros
//****************************************************************************
//****************************************************************************
// @Defines
//****************************************************************************
//****************************************************************************
// @Typedefs
//****************************************************************************
//****************************************************************************
// @Imported Global Variables
//****************************************************************************
Page: 1
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\MAIN.C
//****************************************************************************
// @Global Variables
//****************************************************************************
//****************************************************************************
// @External Prototypes
//****************************************************************************
//****************************************************************************
// @Prototypes Of Local Functions
//****************************************************************************
//****************************************************************************
// @Function void MAIN_vInit(void)
//
//----------------------------------------------------------------------------
// @Description This function initializes the microcontroller.
//
//----------------------------------------------------------------------------
// @Returnvalue None
//
//----------------------------------------------------------------------------
// @Parameters None
//
//----------------------------------------------------------------------------
// @Date 26/08/2014
//
//****************************************************************************
void MAIN_vInit(void)
{
// USER CODE BEGIN (Init,2)
/// -----------------------------------------------------------------------
/// Configuration of the System Clock:
/// -----------------------------------------------------------------------
/// - VCO clock used, input clock is connected
/// - input frequency is 8,00 MHz
/// - system clock is 66.00 MHz
Page: 2
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\MAIN.C
// -----------------------------------------------------------------------
// Initialization of the Peripherals:
// -----------------------------------------------------------------------
// -----------------------------------------------------------------------
// Initialization of the Bank Select registers:
// -----------------------------------------------------------------------
//****************************************************************************
// @Function void MAIN_vUnlockProtecReg(void)
//
//----------------------------------------------------------------------------
// @Description This function makes it possible to write one protected
// register.
//
//----------------------------------------------------------------------------
// @Returnvalue None
//
//----------------------------------------------------------------------------
// @Parameters None
//
//----------------------------------------------------------------------------
// @Date 26/08/2014
//
//****************************************************************************
void MAIN_vUnlockProtecReg(void)
{
uword uwPASSWORD;
Page: 3
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\MAIN.C
//****************************************************************************
// @Function void MAIN_vLockProtecReg(void)
//
//----------------------------------------------------------------------------
// @Description This function makes it possible to lock one protected
// register.
//
//----------------------------------------------------------------------------
// @Returnvalue None
//
//----------------------------------------------------------------------------
// @Parameters None
//
//----------------------------------------------------------------------------
// @Date 26/08/2014
//
//****************************************************************************
void MAIN_vLockProtecReg(void)
{
uword uwPASSWORD;
//****************************************************************************
// @Function void MAIN_vChangeFreq(void)
//
//----------------------------------------------------------------------------
// @Description This function is used to select the external crystal and
// configure the system frequency to 80Mhz/66Mhz.
//
//----------------------------------------------------------------------------
// @Returnvalue None
//
//----------------------------------------------------------------------------
// @Parameters None
//
//----------------------------------------------------------------------------
// @Date 26/08/2014
//
//****************************************************************************
Page: 4
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\MAIN.C
void MAIN_vChangeFreq(void)
{
SCS_SwitchToHighPrecBandgap();
//For application and internal application resets, the complete PLL configuration cou
ld be avoided
//The entry from application resets and internal application reset is covered in the
following differentiation
//in int/ext clock in lock/unlocked state.
{
//estimate the K1 value and the current frequency
//reduce K2/P/N values in steps so that the frequency
//jumps is limited to 20MHz or factor of 5 whichever is minimum
NOP();
}
//****************************************************************************
// @Function void main(void)
//
//----------------------------------------------------------------------------
// @Description This is the main function.
//
//----------------------------------------------------------------------------
// @Returnvalue None
//
//----------------------------------------------------------------------------
// @Parameters None
//
Page: 5
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\MAIN.C
//----------------------------------------------------------------------------
// @Date 26/08/2014
//
//****************************************************************************
void main(void)
{
// USER CODE BEGIN (Main,2)
MAIN_vInit();
while(1)
{
Page: 6
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\MAIN.H
//****************************************************************************
// @Module Project Settings
// @Filename MAIN.H
// @Project Aircraft.dav
//----------------------------------------------------------------------------
// @Controller Infineon XE167F-96F66
//
// @Compiler Keil
//
// @Codegenerator 2.2
//
// @Description This file contains all function prototypes and macros for
// the MAIN module.
//
//----------------------------------------------------------------------------
// @Date 26/08/2014 17:45:06
//
//****************************************************************************
#ifndef _MAIN_H_
#define _MAIN_H_
//****************************************************************************
// @Project Includes
//****************************************************************************
//****************************************************************************
// @Macros
//****************************************************************************
//****************************************************************************
// @Defines
//****************************************************************************
#define KEIL
Page: 1
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\MAIN.H
//****************************************************************************
// @Typedefs
//****************************************************************************
{
long yn; // PI integral buffer
int kp; // Proportional constant
//****************************************************************************
// @Imported Global Variables
//****************************************************************************
//****************************************************************************
// @Global Variables
//****************************************************************************
//****************************************************************************
// @Prototypes Of Global Functions
Page: 2
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\MAIN.H
//****************************************************************************
void MAIN_vUnlockProtecReg(void);
void MAIN_vLockProtecReg(void);
void MAIN_vChangeFreq(void);
//****************************************************************************
// @Interrupt Vectors
//****************************************************************************
//****************************************************************************
// @Project Includes
//****************************************************************************
#include <Intrins.h>
#include "XE16xREGS.H"
#include "SCS.H"
#include "IO.H"
#include "CCU60.H"
#include "ADC0.H"
#include "ADC1.H"
Page: 3
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\ADC0.C
//****************************************************************************
// @Module Analog / Digital Converter (ADC0)
// @Filename ADC0.C
// @Project Aircraft.dav
//----------------------------------------------------------------------------
// @Controller Infineon XE167F-96F66
//
// @Compiler Keil
//
// @Codegenerator 2.2
//
// @Description This file contains functions that use the ADC0 module.
//
//----------------------------------------------------------------------------
// @Date 26/08/2014 17:45:07
//
//****************************************************************************
//****************************************************************************
// @Project Includes
//****************************************************************************
#include "MAIN.H"
//****************************************************************************
// @Macros
//****************************************************************************
//****************************************************************************
// @Defines
//****************************************************************************
//****************************************************************************
// @Typedefs
//****************************************************************************
//****************************************************************************
// @Imported Global Variables
//****************************************************************************
Page: 1
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\ADC0.C
//****************************************************************************
// @Global Variables
//****************************************************************************
//****************************************************************************
// @External Prototypes
//****************************************************************************
//****************************************************************************
// @Prototypes Of Local Functions
//****************************************************************************
//****************************************************************************
// @Function void ADC0_vInit(void)
//
//----------------------------------------------------------------------------
// @Description This is the initialization function of the ADC function
// library. It is assumed that the SFRs used by this library
// are in reset state.
//
// Following SFR fields will be initialized:
// GLOBCTR - Global Control
// RSPR0 - Priority and Arbitration Register
// ASENR - Arbitration slot enable register
// CHCTRx - Channel Control Register x
// RCRx - Result Control Register x
// KSCFG - Module configuration Register
// INPCR - Input class Registers
// CHINPRx - Channel Interrupt register
// EVINPRx - Event Interrupt register
// SYNCTR - Synchronisation control register
// LCBRx - Limit check boundary register
// PISEL - Port input selection
// QMR0 - Sequential 0 mode register
// CRMR1 - Parallel mode register
// QMR2 - Sequential 2 mode register
//
//----------------------------------------------------------------------------
// @Returnvalue None
//
//----------------------------------------------------------------------------
// @Parameters None
//
//----------------------------------------------------------------------------
// @Date 26/08/2014
//
//****************************************************************************
Page: 2
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\ADC0.C
void ADC0_vInit(void)
{
// USER CODE BEGIN (ADC0_Init,2)
/// -----------------------------------------------------------------------
/// Configuration of ADC0 kernel configuration register:
/// -----------------------------------------------------------------------
ADC0_KSCFG = 0x0003; // load ADC0 kernel configuration register
/// -----------------------------------------------------------------------
/// Configure global control register:
/// -----------------------------------------------------------------------
/// --- Conversion Timing -----------------
/// - conversion time (CTC) = 01,29 us
/// _Analog clock is 1/5th of module clock and digital clock is 1/1 times
/// of module clock
/// -----------------------------------------------------------------------
/// Configuration of Arbitration Slot enable register and also the Source
/// Priority register:
/// -----------------------------------------------------------------------
/// - Arbitration Slot 0 is disabled
/// -----------------------------------------------------------------------
/// Configuration of Channel Control Registers:
/// -----------------------------------------------------------------------
/// Configuration of Channel 3
/// - the result register0 is selected
/// - the limit check 7 is selected
Page: 3
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\ADC0.C
/// -----------------------------------------------------------------------
/// Configuration of Sample Time and Resolution:
/// -----------------------------------------------------------------------
/// -----------------------------------------------------------------------
/// Configuration of Result Control Registers:
/// -----------------------------------------------------------------------
/// Configuration of Result Control Register 0
/// - the data reduction filter is disabled
/// - the event interrupt is disabled
/// - the wait-for-read mode is disabled
Page: 4
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\ADC0.C
/// -----------------------------------------------------------------------
/// Configuration of Channel Interrupt Node Pointer Register:
/// -----------------------------------------------------------------------
/// - the SR0 line become activated if channel 3 interrupt is generated
/// -----------------------------------------------------------------------
/// Configuration of Event Interrupt Node Pointer Register for Source
/// Interrupts:
/// -----------------------------------------------------------------------
/// - the SR 0 line become activated if the event 1 interrupt is generated
/// -----------------------------------------------------------------------
/// Configuration of Event Interrupt Node Pointer Register for Result
/// Interrupts:
/// -----------------------------------------------------------------------
/// -----------------------------------------------------------------------
/// Configuration of Service Request Nodes 0 - 3 :
/// -----------------------------------------------------------------------
/// SRN0 service request node configuration:
/// - SRN0 interrupt priority level (ILVL) = 7
/// - SRN0 interrupt group level (GLVL) = 0
/// - SRN0 group priority extension (GPX) = 0
Page: 5
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\ADC0.C
ADC_0IC = 0x005C;
/// -----------------------------------------------------------------------
/// Configuration of Limit Check Boundary:
/// -----------------------------------------------------------------------
/// -----------------------------------------------------------------------
/// Configuration of Gating source and External Trigger Control:
/// -----------------------------------------------------------------------
/// - No Gating source selected for Arbitration Source 0
/// -----------------------------------------------------------------------
/// Configuration of Conversion Queue Mode Register:Sequential Source 0
/// -----------------------------------------------------------------------
/// - the gating line is permanently Disabled
/// - the external trigger is disabled
/// - the trigger mode 0 is selected
/// -----------------------------------------------------------------------
/// Configuration of Conversion Queue Mode Register:Sequential Source 2
/// -----------------------------------------------------------------------
/// - the gating line is permanently Disabled
/// - the external trigger is disabled
/// - the trigger mode 0 is selected
/// -----------------------------------------------------------------------
/// Configuration of Conversion Request Mode Registers:Parallel Source
/// -----------------------------------------------------------------------
/// - the gating line is permanently Enabled
/// - the external trigger is disabled
/// - the source interrupt is disabled
/// - the autoscan functionality is disabled
/// -----------------------------------------------------------------------
/// Configuration of Synchronisation Registers:
/// -----------------------------------------------------------------------
/// - ADC0 is master
ADC0_SYNCTR |= 0x0010; // Synchronisation register
Page: 6
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\ADC0.C
//****************************************************************************
// @Function void ADC0_viSRN0(void)
//
//----------------------------------------------------------------------------
// @Description This is the interrupt service routine for the Service
// Request Node 0 of the ADC0 module.
//
//----------------------------------------------------------------------------
// @Returnvalue None
//
//----------------------------------------------------------------------------
// @Parameters None
//
//----------------------------------------------------------------------------
// @Date 26/08/2014
//
//****************************************************************************
Page: 7
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\ADC0.C
Page: 8
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\ADC0.H
//****************************************************************************
// @Module Analog / Digital Converter (ADC0)
// @Filename ADC0.H
// @Project Aircraft.dav
//----------------------------------------------------------------------------
// @Controller Infineon XE167F-96F66
//
// @Compiler Keil
//
// @Codegenerator 2.2
//
// @Description This file contains all function prototypes and macros for
// the ADC0 module.
//
//----------------------------------------------------------------------------
// @Date 26/08/2014 17:45:07
//
//****************************************************************************
#ifndef _ADC0_H_
#define _ADC0_H_
//****************************************************************************
// @Project Includes
//****************************************************************************
//****************************************************************************
// @Macros
//****************************************************************************
//****************************************************************************
// @Defines
//****************************************************************************
Page: 1
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\ADC0.H
//****************************************************************************
// @Typedefs
//****************************************************************************
//****************************************************************************
// @Imported Global Variables
//****************************************************************************
//****************************************************************************
// @Global Variables
//****************************************************************************
Page: 2
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\ADC0.H
//****************************************************************************
// @Prototypes Of Global Functions
//****************************************************************************
void ADC0_vInit(void);
//****************************************************************************
// @Interrupt Vectors
//****************************************************************************
Page: 3
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\ADC1.C
//****************************************************************************
// @Module Analog / Digital Converter (ADC1)
// @Filename ADC1.C
// @Project Aircraft.dav
//----------------------------------------------------------------------------
// @Controller Infineon XE167F-96F66
//
// @Compiler Keil
//
// @Codegenerator 2.2
//
// @Description This file contains functions that use the ADC1 module.
//
//----------------------------------------------------------------------------
// @Date 26/08/2014 17:45:07
//
//****************************************************************************
//****************************************************************************
// @Project Includes
//****************************************************************************
#include "MAIN.H"
//****************************************************************************
// @Macros
//****************************************************************************
//****************************************************************************
// @Defines
//****************************************************************************
//****************************************************************************
// @Typedefs
//****************************************************************************
//****************************************************************************
// @Imported Global Variables
//****************************************************************************
Page: 1
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\ADC1.C
//****************************************************************************
// @Global Variables
//****************************************************************************
//****************************************************************************
// @External Prototypes
//****************************************************************************
//****************************************************************************
// @Prototypes Of Local Functions
//****************************************************************************
//****************************************************************************
// @Function void ADC1_vInit(void)
//
//----------------------------------------------------------------------------
// @Description This is the initialization function of the ADC function
// library. It is assumed that the SFRs used by this library
// are in reset state.
//
// Following SFR fields will be initialized:
// GLOBCTR - Global Control
// RSPR0 - Priority and Arbitration Register
// ASENR - Arbitration slot enable register
// CHCTRx - Channel Control Register x
// RCRx - Result Control Register x
// KSCFG - Module configuration Register
// INPCR - Input class Registers
// CHINPRx - Channel Interrupt register
// EVINPRx - Event Interrupt register
// SYNCTR - Synchronisation control register
// LCBRx - Limit check boundary register
// PISEL - Port input selection
// QMR0 - Sequential 0 mode register
// CRMR1 - Parallel mode register
// QMR2 - Sequential 2 mode register
//
//----------------------------------------------------------------------------
// @Returnvalue None
//
//----------------------------------------------------------------------------
// @Parameters None
//
//----------------------------------------------------------------------------
// @Date 26/08/2014
//
//****************************************************************************
Page: 2
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\ADC1.C
void ADC1_vInit(void)
{
// USER CODE BEGIN (ADC1_Init,2)
/// -----------------------------------------------------------------------
/// Configuration of ADC0 kernel configuration register:
/// -----------------------------------------------------------------------
ADC0_KSCFG = 0x0003; // load ADC0 kernel configuration register
/// -----------------------------------------------------------------------
/// Configure global control register:
/// -----------------------------------------------------------------------
/// --- Conversion Timing -----------------
/// - conversion time (CTC) = 01,29 us
/// _Analog clock is 1/5th of module clock and digital clock is 1/1 times
/// of module clock
/// -----------------------------------------------------------------------
/// Configuration of Arbitration Slot enable register and also the Source
/// Priority register:
/// -----------------------------------------------------------------------
/// - Arbitration Slot 0 is enabled
/// -----------------------------------------------------------------------
/// Configuration of Channel Control Registers:
/// -----------------------------------------------------------------------
/// Configuration of Channel 1
/// - the result register0 is selected
/// - the limit check 0 is selected
Page: 3
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\ADC1.C
/// -----------------------------------------------------------------------
/// Configuration of Sample Time and Resolution:
/// -----------------------------------------------------------------------
/// -----------------------------------------------------------------------
/// Configuration of Result Control Registers:
/// -----------------------------------------------------------------------
/// Configuration of Result Control Register 0
/// - the data reduction filter is disabled
/// - the event interrupt is disabled
/// - the wait-for-read mode is disabled
Page: 4
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\ADC1.C
/// -----------------------------------------------------------------------
/// Configuration of Channel Interrupt Node Pointer Register:
/// -----------------------------------------------------------------------
/// - the SR0 line become activated if channel 1 interrupt is generated
Page: 5
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\ADC1.C
/// -----------------------------------------------------------------------
/// Configuration of Event Interrupt Node Pointer Register for Source
/// Interrupts:
/// -----------------------------------------------------------------------
/// - the SR 0 line become activated if the event 0 interrupt is generated
/// - the SR 0 line become activated if the event 1 interrupt is generated
/// -----------------------------------------------------------------------
/// Configuration of Event Interrupt Node Pointer Register for Result
/// Interrupts:
/// -----------------------------------------------------------------------
/// -----------------------------------------------------------------------
/// Configuration of Service Request Nodes 0 - 3 :
/// -----------------------------------------------------------------------
/// -----------------------------------------------------------------------
/// Configuration of Limit Check Boundary:
/// -----------------------------------------------------------------------
/// -----------------------------------------------------------------------
/// Configuration of Gating source and External Trigger Control:
/// -----------------------------------------------------------------------
/// - No Gating source selected for Arbitration Source 0
/// -----------------------------------------------------------------------
/// Configuration of Conversion Queue Mode Register:Sequential Source 0
/// -----------------------------------------------------------------------
/// - the gating line is permanently Enabled
Page: 6
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\ADC1.C
/// -----------------------------------------------------------------------
/// Configuration of Conversion Queue Mode Register:Sequential Source 2
/// -----------------------------------------------------------------------
/// - the gating line is permanently Disabled
/// - the external trigger is disabled
/// - the trigger mode 0 is selected
/// -----------------------------------------------------------------------
/// Configuration of Conversion Request Mode Registers:Parallel Source
/// -----------------------------------------------------------------------
/// - the gating line is permanently Enabled
/// - the external trigger is disabled
/// - the source interrupt is disabled
/// - the autoscan functionality is disabled
/// -----------------------------------------------------------------------
/// Configuration of Synchronisation Registers:
/// -----------------------------------------------------------------------
/// - ADC1 is master
ADC1_SYNCTR |= 0x0010; // Synchronisation register
Page: 7
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\ADC1.H
//****************************************************************************
// @Module Analog / Digital Converter (ADC1)
// @Filename ADC1.H
// @Project Aircraft.dav
//----------------------------------------------------------------------------
// @Controller Infineon XE167F-96F66
//
// @Compiler Keil
//
// @Codegenerator 2.2
//
// @Description This file contains all function prototypes and macros for
// the ADC1 module.
//
//----------------------------------------------------------------------------
// @Date 26/08/2014 17:45:07
//
//****************************************************************************
#ifndef _ADC1_H_
#define _ADC1_H_
//****************************************************************************
// @Project Includes
//****************************************************************************
//****************************************************************************
// @Macros
//****************************************************************************
//****************************************************************************
// @Defines
//****************************************************************************
Page: 1
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\ADC1.H
//****************************************************************************
// @Typedefs
//****************************************************************************
//****************************************************************************
// @Imported Global Variables
//****************************************************************************
//****************************************************************************
// @Global Variables
//****************************************************************************
//****************************************************************************
// @Prototypes Of Global Functions
//****************************************************************************
void ADC1_vInit(void);
//****************************************************************************
// @Interrupt Vectors
//****************************************************************************
Page: 2
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\ADC1.H
Page: 3
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\CCU60.C
//****************************************************************************
// @Module Capture / Compare Unit 60 (CCU60)
// @Filename CCU60.C
// @Project Aircraft.dav
//----------------------------------------------------------------------------
// @Controller Infineon XE167F-96F66
//
// @Compiler Keil
//
// @Codegenerator 2.2
//
// @Description This file contains functions that use the CCU60 module.
//
//----------------------------------------------------------------------------
// @Date 26/08/2014 17:45:07
//
//****************************************************************************
//****************************************************************************
// @Project Includes
//****************************************************************************
#include "MAIN.H"
//****************************************************************************
// @Macros
//****************************************************************************
//****************************************************************************
// @Defines
//****************************************************************************
//****************************************************************************
// @Typedefs
//****************************************************************************
//****************************************************************************
// @Imported Global Variables
//****************************************************************************
Page: 1
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\CCU60.C
//****************************************************************************
// @Global Variables
//****************************************************************************
//****************************************************************************
// @External Prototypes
//****************************************************************************
Page: 2
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\CCU60.C
//****************************************************************************
// @Prototypes Of Local Functions
//****************************************************************************
//****************************************************************************
// @Function void CCU60_vInit(void)
//
//----------------------------------------------------------------------------
// @Description This is the initialization function of the CCU60 function
// library. It is assumed that the SFRs used by this library
// are in reset state.
//
//----------------------------------------------------------------------------
// @Returnvalue None
//
//----------------------------------------------------------------------------
// @Parameters None
//
//----------------------------------------------------------------------------
// @Date 26/08/2014
//
//****************************************************************************
void CCU60_vInit(void)
{
// USER CODE BEGIN (Init,2)
/// -----------------------------------------------------------------------
/// Configuration of KERNEL REGISTERS :
/// -----------------------------------------------------------------------
/// - CCU60 Module is enabled.
/// - The CCU60 module clock = 66,000 MHz.
/// - T12 is enabled.
/// - T13 is enabled.
/// - MCM is enabled.
/// -----------------------------------------------------------------------
/// Configuration of CCU60 Timer 12:
/// -----------------------------------------------------------------------
/// - Timer 12 Input clock factor (T12CLK) is 0
/// - prescaler factor is 1
/// - Timer 12 run bit is reset
/// - Single shot mode is disabled
/// - Timer 12 works in edge aligned mode
/// - Interrupt on period match is enabled
/// - Interrupt on one match is disabled
/// - No External run selection is selected.
Page: 3
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\CCU60.C
/// -----------------------------------------------------------------------
/// Configuration of T13HR Signal:
/// -----------------------------------------------------------------------
/// - Signal T13HRA is selected as Input
/// -----------------------------------------------------------------------
/// Configuration of CCU60 Timer 13:
/// -----------------------------------------------------------------------
/// - Timer 13 Input Clock factor (T13CLK) is 0
/// - prescaler factor is 0
/// - Timer 13 run bit is reset
/// - Trigger control is disabled
/// - No External run selection is selected.
/// - Timer mode is selected.
/// -
/// - Single shot mode is disabled
/// - Interrupt on period match is enabled
/// - Interrupt on compare match is enabled
/// -----------------------------------------------------------------------
/// Configuration of Multi Channel Mode:
/// -----------------------------------------------------------------------
/// - Multi channel mode is enabled
/// -----------------------------------------------------------------------
/// Configuration of CCU60 Channel 0:
/// -----------------------------------------------------------------------
/// - Hall sensor mode is selected
/// - The output CC60 is set to the passive state
/// - The trap functionality of the pin CC60 is enabled
/// - The passive level of the output CC60 is '0'
/// - The output COUT60 is set to the passive state
/// - The trap functionality of the pin COUT60 is enabled
/// - The passive level of the output COUT60 is '0'
/// - Dead time generation is disabled
/// -----------------------------------------------------------------------
/// Configuration of CCU60 Channel 1:
/// -----------------------------------------------------------------------
/// - Hall sensor mode is selected
/// - The output CC61 is set to the passive state
/// - The trap functionality of the pin CC61 is enabled
/// - The passive level of the output CC61 is '0'
/// - The output COUT61 is set to the passive state
Page: 4
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\CCU60.C
/// -----------------------------------------------------------------------
/// Configuration of CCU60 Channel 2:
/// -----------------------------------------------------------------------
/// - Hall sensor mode is selected
/// - The output CC62 is set to the passive state
/// - The trap functionality of the pin CC62 is enabled
/// - The passive level of the output CC62 is '0'
/// - The output COUT62 is set to the passive state
/// - The trap functionality of the pin COUT62 is enabled
/// - The passive level of the output COUT62 is '0'
/// - Dead time generation is disabled
/// -----------------------------------------------------------------------
/// Configuration of CCU60 Channel 3:
/// -----------------------------------------------------------------------
/// - T13 output is not inverted
/// -----------------------------------------------------------------------
/// Configuration of CCU60 trap control:
/// -----------------------------------------------------------------------
/// - Trap can only be generated by SW by setting the bit TRPF
/// - The trap state is left immediately without any synchronization to
/// T12 or T13
/// - The trap state can be left as soon as bit TRPF is reset by SW
/// (according to TRPPEN, TRPM0 and TRPM1)
/// - Trap interrupt is enabled
/// -----------------------------------------------------------------------
/// Configuration of CCU60 interrupt control:
/// -----------------------------------------------------------------------
/// - For channel 0 interrupts is node I1 selected
/// - For channel 1 interrupts is node I1 selected
/// - For channel 2 interrupts is node I2 selected
Page: 5
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\CCU60.C
/// -----------------------------------------------------------------------
/// Configuration of the used CCU60 Channel Port Pins:
/// -----------------------------------------------------------------------
/// - P10.0 is used for CCU60 output(CC60)
/// - P10.1 is used for CCU60 output(CC61)
/// - P10.2 is used for CCU60 output(CC62)
/// - P10.3 is used for CCU60 output(COUT60)
/// - P10.4 is used for CCU60 output(COUT61)
/// - P10.5 is used for CCU60 output(COUT62)
/// - P10.7 is used for CCU60 input(CCPOS0A)
/// - P10.8 is used for CCU60 input(CCPOS1A)
/// - P10.9 is used for CCU60 input(CCPOS2A)
/// - P10.6 is used for CCU60 input(CTRAPA)
/// -----------------------------------------------------------------------
/// Configuration of the used CCU60 Channels Interrupts:
/// -----------------------------------------------------------------------
/// NodeI1 service request node configuration:
/// - NodeI1 interrupt priority level (ILVL) = 8
/// - NodeI1 interrupt group level (GLVL) = 0
/// - NodeI1 group priority extension (GPX) = 0
CCU60_1IC = 0x0060;
CCU60_2IC = 0x0055;
CCU60_3IC = 0x005A;
/// -----------------------------------------------------------------------
/// Configuration of T12, T13 ---- CCU60_TCTR4 Register:
/// -----------------------------------------------------------------------
/// - Enable shadow transfer of T12 and T13
/// - Timer 12 run bit is reset
/// - Timer 13 run bit is reset
CCU60_TCTR4 = 0x4040; // load CCU60 timer control register 4
Page: 6
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\CCU60.C
//****************************************************************************
// @Function void CCU60_viNodeI1(void)
//
//----------------------------------------------------------------------------
// @Description This is the interrupt service routine for the CCU60 node
// I1. If the content of the corresponding compare timer
// (configurable) equals the content of the capture/compare
// register or if a capture event occurs at the associated
// port pin, the interrupt request flag is set and an
// interrupt is triggered (only if enabled).
// Please note that you have to add application specific code
// to this function.
//
//----------------------------------------------------------------------------
// @Returnvalue None
//
//----------------------------------------------------------------------------
// @Parameters None
//
//----------------------------------------------------------------------------
// @Date 26/08/2014
//
//****************************************************************************
Page: 7
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\CCU60.C
Page: 8
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\CCU60.C
2.
}
}
else // If bemf detection i
s not possible...
{
Motor_stop(); // ... stop the mot
or.
}
// USER CODE END
//****************************************************************************
// @Function void CCU60_viNodeI2(void)
//
//----------------------------------------------------------------------------
// @Description This is the interrupt service routine for the CCU60 node
// I2. If the content of the corresponding compare timer
// (configurable) equals the content of the capture/compare
// register or if a capture event occurs at the associated
// port pin, the interrupt request flag is set and an
// interrupt is triggered (only if enabled).
// Please note that you have to add application specific code
// to this function.
//
//----------------------------------------------------------------------------
// @Returnvalue None
//
//----------------------------------------------------------------------------
// @Parameters None
//
//----------------------------------------------------------------------------
// @Date 26/08/2014
//
//****************************************************************************
Page: 9
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\CCU60.C
if (slope == 2) //
If a falling edge of the bemf has been detected...
{
slope = 0;
// ... we need to look for rising edge.
}
if (slope == 3) //
If a rising edge of the bemf has been detected...
{
slope = 1;
// ... we need to look for falling edge.
}
if (hall_counter < 2) //
If motor speed is too small...
{
speed_meas = 0;
}
// ... reset to 0 (Only done at the first measurements of the speed).
// USER CODE END
//****************************************************************************
// @Function void CCU60_viNodeI3(void)
//
//----------------------------------------------------------------------------
// @Description This is the interrupt service routine for the CCU60 node
// I3. If the content of the corresponding compare timer
// (configurable) equals the content of the capture/compare
// register or if a capture event occurs at the associated
// port pin, the interrupt request flag is set and an
// interrupt is triggered (only if enabled).
// Please note that you have to add application specific code
// to this function.
//
//----------------------------------------------------------------------------
// @Returnvalue None
//
//----------------------------------------------------------------------------
// @Parameters None
//
//----------------------------------------------------------------------------
// @Date 26/08/2014
//
//****************************************************************************
Page: 10
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\CCU60.C
if(spd_loop==1) // If 1
ms reached...
{
speed_ref_pu = FloatTo1Q15((float)(speed_ref/MAX_SPEED)); //
... calculate the speed reference in pu (1Q15).
speed_meas_pu = FloatTo1Q15((float)(speed_meas/MAX_SPEED)); //
... calculate the measured speed in pu (1Q15).
PI_spd_out = pi_controller64(&PI_spd.yn, speed_ref_pu, speed_meas_pu); //
... compute the I_ref.
spd_loop=0; //
... reset the counter.
}
else // If 1
ms not reached...
{
spd_loop++; //
Page: 11
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\CCU60.C
Page: 12
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\CCU60.H
//****************************************************************************
// @Module Capture / Compare Unit 60 (CCU60)
// @Filename CCU60.H
// @Project Aircraft.dav
//----------------------------------------------------------------------------
// @Controller Infineon XE167F-96F66
//
// @Compiler Keil
//
// @Codegenerator 2.2
//
// @Description This file contains all function prototypes and macros for
// the CCU60 module.
//
//----------------------------------------------------------------------------
// @Date 26/08/2014 17:45:07
//
//****************************************************************************
#ifndef _CCU60_H_
#define _CCU60_H_
//****************************************************************************
// @Project Includes
//****************************************************************************
//****************************************************************************
// @Macros
//****************************************************************************
//****************************************************************************
// @Defines
//****************************************************************************
Page: 1
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\CCU60.H
//****************************************************************************
// @Typedefs
//****************************************************************************
//****************************************************************************
// @Imported Global Variables
//****************************************************************************
//****************************************************************************
// @Global Variables
//****************************************************************************
//****************************************************************************
// @Prototypes Of Global Functions
//****************************************************************************
void CCU60_vInit(void);
//****************************************************************************
// @Interrupt Vectors
//****************************************************************************
Page: 2
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\FUNC.C
#include "MAIN.H"
// Variable declaration
// Global variables
int C_SDATA direction; // Index-offset for reading the swi
tching pattern, depending on the specified motor direction.
int C_SDATA once; // Variable to allow motor start.
unsigned int C_SDATA sv_start_ref; // Start speed reference for motor
start.
unsigned int C_SDATA sv_start_ref0; // Copy of start reference to check
changes in end reference and recalculate ramp time.
unsigned int C_SDATA sv_end_ref; // End speed reference for motor st
art.
int C_SDATA motor_status; // Motor stop command.
int C_SDATA direction_user; // Variable which stores the desire
d direction of rotation.
unsigned long C_SDATA rampup_time; // Time to achieve the end referenc
e.
int C_SDATA trap_reset; // Set to '1' to reset the 'Latched
CTRAP' condition.
unsigned int C_SDATA speed_ref; // Desired motor speed reference.
unsigned int C_SDATA circ_index; // Index to access the circular buf
fer used in motor speed computation.
unsigned int C_SDATA speed_buffer[6*PP]; // Buffer to preserve the previous
samples of motor speed.
int C_SDATA oc_counter; // Counter to specify the time limi
t for motor overcurrent.
unsigned long C_SDATA time_step; // Sets the increment frequency of
the speed reference.
unsigned long C_SDATA counter1; // Counter to increase the speed re
ference.
unsigned long C_SDATA speed_acumm; // Accumulator to calculate the ave
rage motor speed.
int C_SDATA hall_counter; // Counter to start taking into acc
ount speed measurements.
int C_SDATA speed_counter; // Counter to start measuring avera
ge speed.
int C_SDATA increment_free; // Flag to specify that T13 interru
Page: 1
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\FUNC.C
pt has occured.
int C_SDATA spd_loop; // Speed closed loop prescaler.
int C_SDATA Idc_meas; // DC link current measurement.
unsigned int C_SDATA speed_meas; // Variable to store the actual mot
or speed (sector).
// BEMF
unsigned int C_SDATA compare_value; // DC link voltage/2
int C_SDATA slope; // Slope of the bemf: Rising = 0, F
alling = 1.
int C_SDATA CH_conv; // Stores the last converted channe
l to apply the corresponding offset.
unsigned int C_SDATA zc_time; // Time between zero crossing point
s in sensorless mode.
unsigned int C_SDATA bemf_aux; // Stores the current value of T12
to change to sensorless mode.
unsigned int C_SDATA back_emf_measure; // Last measured bemf.
int C_SDATA slope_known; // Slope of the bemf is detected .
int C_SDATA bemf_counter1; // Counter for detection of bemf.
// PI variables
struct PI_cont C_SDATA PI_spd; // PI speed variable.
struct PI_cont C_SDATA PI_curr; // PI current variable.
int C_SDATA PI_spd_out; // PI speed output.
int C_SDATA PI_curr_out; // PI current output.
// Function declaration
// Modulation pattern
#define MCMOUTS_CTE_R(curhs,exphs,mcmps) (curhs << 11) | (exphs << 8) | (mcmps
)
#define MCMOUTS_CTE_L(curhs,exphs,mcmps) (curhs << 11) | (exphs << 8) | (mcmps
)
Page: 2
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\FUNC.C
};
// Function implementation
//****************************************************************************
// @Function void ADC_OFFSET(int CH_OFFSET)
// Description This function computes the ADC offset value, by taking
// 65,536 samples of the ADC measured data. This computed
// offset value is preserved in the variable adc_offset_resX.
// Parameters Channel to be converted
//----------------------------------------------------------------------------
void ADC_OFFSET(int CH_OFFSET)
{
unsigned int i = 0;
adc_offset_acumm = 0; // Reset the ac
cumulator.
switch(CH_OFFSET)
{
case 1: // Phase A.
for(i = 0; i < 65535; i++) // Until al
l samples not accumulated, be in the loop.
{
ADC1_CRPR1 = 0x0001; // Requ
est 'start sampling' command to the ADC.
while(!(ADC1_VFR & 0x0001)); // Wait
until valid conversion.
adc_offset_acumm += (ADC1_RESR0>>2 & 0x03FF); // Accu
mulate the sample, right aligned.
}
adc_offset_resA = (int)(adc_offset_acumm >> 16); // Do the a
verage of all the samples.
break;
case 4: // Phase B
for(i = 0; i < 65535; i++) // Until al
l samples not accumulated, be in the loop.
{
ADC1_CRPR1 = 0x0004; // Requ
est 'start sampling' command to the ADC.
while(!(ADC1_VFR & 0x0001)); // Wait
until valid conversion.
adc_offset_acumm += (ADC1_RESR0>>2 & 0x03FF); // Accu
mulate the sample, right aligned.
}
adc_offset_resB = (int)(adc_offset_acumm >> 16); // compute
the average of all the samples.
break;
case 7: // Phase C
for(i = 0; i < 65535; i++) // Until al
l samples not accumulated, be in the loop.
{
ADC1_CRPR1 = 0x0007; // Requ
est 'start sampling' command to the ADC.
while(!(ADC1_VFR & 0x0001)); // Wait
until valid conversion.
adc_offset_acumm += (ADC1_RESR0>>2 & 0x03FF); // Accu
mulate the sample, right aligned.
}
adc_offset_resC = (int)(adc_offset_acumm >> 16); // Do the a
verage of all the samples.
break;
case 3: // DC link curr
ent.
for(i = 0; i < 65535; i++) // Until al
l samples not accumulated, be in the loop.
{
ADC0_CRPR1 = 0x0003; // Requ
est 'start sampling' command to the ADC.
while(!(ADC0_VFR & 0x0001)); // Wait
Page: 3
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\FUNC.C
//****************************************************************************
// @Function void Motor_start(void)
// Description This function executes the functions required for Motor
// start-up such as initialization of motor related variables,
// initialization of motor SFRs, etc.
// It also ensures that the start reference is always lower
// than the end reference.
//----------------------------------------------------------------------------
void Motor_start(void)
{
if(once == 0) // Execute only the first t
ime.
{
once = 0x0001; // Set the flag so that thi
s code never executes until next motor start-up.
status_word = 0x0001; // Set 'status_on' flag to
convey to the user that 'Motor_start' command is issued.
//****************************************************************************
// @Function void Init_control(void)
// Description This function initialises various variables required
// for motor start-up.
//----------------------------------------------------------------------------
void Init_control(void)
Page: 4
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\FUNC.C
int i = 0;
for(i = 0;i<(6*PP);i++)
{
speed_buffer[i] = 0; // Initialise the speed buffer.
}
speed_acumm = 0x00000008; // Initialise speed accumulator with 8 so that divi
sion by 8 won't result in zero.
circ_index = 0x0000; // Initialise the circular index for speed measurem
ent.
speed_counter = 0x0000; // Initialise the speed counter.
hall_counter = 0x0000; // Initialise the hall counter.
oc_counter = 0x0000; // Initialise the s/w time base for overcurrent det
ection.
}
//****************************************************************************
// @Function void Commutation_init(void)
// Description This function initialises the SFRs required for motor start-up
// such as loading of the modulation register, enabling of the timers,
// enabling of the interrupts etc.
//----------------------------------------------------------------------------
void Commutation_init(void)
{
int aux = 0;
aux = ((P10_IN & 0x0380)>>7) + direction; // Read the hall sensor pins from t
he corresponding port.
Page: 5
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\FUNC.C
interrupts.
//****************************************************************************
// @Function void Motor_stop(void)
// Description This function implements the functions required for motor
// stop such as switching off the PWM, all MOSFETs, stopping
// all timers etc.
//----------------------------------------------------------------------------
void Motor_stop(void)
{
CCU60_IEN &= 0x3FFF; // Wrong hall event and idle interrupts dis
abled.
//****************************************************************************
Page: 6
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\FUNC.C
//****************************************************************************
// @Function void Speed_ref_ramp(void)
// Description This function increments/decrements the actual speed
// reference until it becomes equal to the speed end reference.
//----------------------------------------------------------------------------
void Speed_ref_ramp(void)
{
if(sv_end_ref > speed_ref) // If the end reference hasn't b
een reached...
{
speed_ref += 1; // ... increment speed refe
rence.
}
if(sv_end_ref < speed_ref) // If the actual reference is gr
eater than end reference...
{
speed_ref -= 1; // ... decrement the speed
reference.
Page: 7
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\FUNC.C
//****************************************************************************
// @Function void Speed_calc(void)
// Description This function computes the actual motor speed from the
// measured time between two hall events or zero crossing points.
//----------------------------------------------------------------------------
int Speed_calc(unsigned int time_meas, int* speed_counter, int limit)
{
unsigned int time = 0;
unsigned long speed_cal = 0;
//****************************************************************************
// @Function void Sensorless_calc(void)
Page: 8
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\FUNC.C
bemf_counter1 = 0;
// ... reset the counter.
}
Page: 9
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\FUNC.C
}
}
if(zc_time > 70) // If t
he value has sense (not just after the commutation)...
{
slope_known = 1; //
... the slope is already known.
}
}
else // If the s
lope is known...
{
if(slope == 0) // If w
e are looking for a rising edge...
{
if(back_emf_measure >= compare_value) //
If the bemf is greater than half of bus voltage...
{
bemf_counter1++;
// ... increase 'bemf_counter'.
if(bemf_counter1 == 2)
// If two valid samples are detected...
{
zc_time = CCU60_T12;
// ... save the captured time between two zero crossings (in sensorless mode).
status_bemf = 1;
// ... set the bemf detection status flag.
bemf_counter1 = 0;
// ... reset sample counter.
slope = 3;
// ... slope = 3, so that next we start looking for falling edge.
if(status_hs_error)
// If sensorless mode...
{
CCU60_CC60SR = zc_time;
// ... set the CC60R for speed measurement with the time between zero cross
ing points.
CCU60_CC61SR = (zc_time>>1) - 5;
// ... initialize the CCU61 register with half of the time between zero cro
ssings,
Page: 10
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\FUNC.C
{
zc_time = CCU60_T12;
// ... save the captured time between two zero crossings (in sensorless mode).
status_bemf = 1;
// ... set the bemf detection status flag.
bemf_counter1 = 0;
// ... reset sample counter.
slope = 2;
// ... slope = 2, so that next we start looking for rising edge.
if(status_hs_error)
// If sensorless mode...
{
CCU60_CC60SR = zc_time;
// ... set the CC60R for speed measurement with the time between zero cross
ing points.
CCU60_CC61SR = (zc_time>>1) - 5;
// ... initialize the CCU61 register with half of the time between zero cro
ssings,
Page: 11
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\FUNC.H
// Status word
extern C_BDATA status_word; // Full status motor state.
// Global variables
extern int C_SDATA direction; // Index-offset for reading the swi
tching pattern, depending on the specified motor direction.
extern int C_SDATA once; // Counter to specify the time limi
t for motor Overcurrent.
extern unsigned int C_SDATA sv_start_ref; // Start speed reference for motor
start.
extern unsigned int C_SDATA sv_end_ref; // End speed reference for motor st
art.
extern int C_SDATA motor_status; // Motor stop command.
extern int C_SDATA direction_user; // User desired direction.
extern unsigned long C_SDATA rampup_time; // Time to achieve the end referenc
e.
extern int C_SDATA trap_reset; // Set to '1' to reset the 'Latched
CTRAP' condition.
// PI variables
extern struct PI_cont C_SDATA PI_spd; // PI speed variable.
extern struct PI_cont C_SDATA PI_curr; // PI current variable.
// Import functions
extern void Motor_start(void);
extern void Motor_stop(void);
// Function inlines
//*************************************************************************************
************
// @Function void INIT_PI_VAR(void)
// Description This function initialises the PI gain & Limit variables with the co
rresponding
// user values in 'CONFIG.H'.
//-------------------------------------------------------------------------------------
------------
INLINE void INIT_PI_VAR(void)
{
PI_spd.ymax = PI_SPEED_YMAX; // Initialise the PI upper limit variable.
PI_spd.ymin = PI_SPEED_YMIN; // Initialise the PI lower limit variable.
PI_spd.kp = PI_SPEED_KP; // Initialise the PI proportional gain variable
.
PI_spd.ki = PI_SPEED_KI; // Initialise the PI integral gain variable.
//*************************************************************************************
************
// @Function void MOTOR_START_PARAMS(void)
// Description This Function loads the values for the motor start.
//-------------------------------------------------------------------------------------
------------
INLINE void MOTOR_START_PARAMS(void)
{
trap_reset = 1; // Set the 'trap_reset' flag so that 't
rap' flag is cleared under power ON.
status_ctrap = 0; // Clear the trap flag to allow the mot
or to run.
Page: 1
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\FUNC.H
//*************************************************************************************
************
//*************************************************************************************
************
// @Function void INIT_CTRL_VAR(void)
// Description This function initialises the various intermediate variables that a
re required to
// be set to pre-defined default values before any motor related opera
tion.
//-------------------------------------------------------------------------------------
------------
INLINE void INIT_CTRL_VAR(void)
{
direction = 0x0; // Initialise default motor direction to clockwise.
once = 0x0; // Clear the variable 'once' so that by default mot
or stop is assumed.
status_word = 0x0002; // Initialise status flags to reflect motor stopped
condition.
INIT_PI_VAR(); // Execute PI initialisation routine.
MOTOR_START_PARAMS(); // Execute control panel dependent variable initial
isation routine.
}
//*************************************************************************************
************
// @Function void TRAP_RESET(void)
// Description This Function will reset the trap flag if requested.
//-------------------------------------------------------------------------------------
------------
INLINE void TRAP_RESET(void)
{
if (trap_reset == 1) // If trap reset requested...
{
trap_reset = 0; // ... acknowledge the request.
status_ctrap = 0; // ... reset the trap flag.
}
}
//*************************************************************************************
************
// @Function void MOTOR_OPERATION(void)
// Description This Function will start or stop the motor depending on present inp
uts.
//-------------------------------------------------------------------------------------
------------
INLINE void MOTOR_OPERATION(void)
{
if (status_ctrap) // If trap flag is set...
{
motor_status = 1; // ... stop de motor.
}
else // If trap flag is not set...
{
if (motor_status == 0) // If the start of the motor is requested...
Page: 2
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\FUNC.H
{
Motor_start(); // ... start the motor.
}
else // If the start of the motor is not requested..
.
{
Motor_stop(); // ... stop the motor.
}
}
}
Page: 3
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\CONFIG.H
// Speed PI
#define PI_SPEED_YMAX 16368 // Corresponding to an ADC read of 7.5
A (shifted to 1Q15) [ADC range 0 A - 15 A, nominal current = 7 A]
#define PI_SPEED_YMIN 0 // The minimum output of the speed PI i
s 0 A
#define PI_SPEED_KP 358 // Kp has to be divided by 64, to scale
it for the output calculation, where it is multiplied by 64 (0.7 in 1Q15 divided by
64)
#define PI_SPEED_KI 229 // Ki parameter of the speed PI control
ler in per unit (0.007 in 1Q15)
// Current PI
#define PI_CURR_YMAX 32112 // Corresponding to 98% of duty cycle [
0.98 to 1Q15]
#define PI_CURR_YMIN 0 // Corresponding to 0% of duty cycle
#define PI_CURR_KP 205 // Kp has to be divided by 64, to scale
it for the output calculation, where it is multiplied by 64 (0.4 in 1Q15 divided by
64)
#define PI_CURR_KI 16 // Ki parameter of the current PI contr
oller in per unit (0.0005 in 1Q15)
// Motor parameters
#define PP 4 // Pole pairs
#define MAX_SPEED 9000 // Max. speed that the motor can achiev
e without field weakening (No load speed)
// User configuration
#define MOTOR_DIRECTION 0 // Clockwise = 0, Counterclockwise = 1
#define RAMP_UP_TIME 1600000 // Time to achieve the speed end refere
nce (value = time*64*fpwm = 1s*64*25000s-1
#define MOTOR_START_REF 600 // Start reference of the motor speed
#define MOTOR_END_REF 3000 // End reference of the motor speed
#define TIME_CURRENT_MAX 1000 // Maximum time overcurrent (up to 10 A
) is allowed before stopping the motor [TIMER_CURRENT_MAX=tmax/T13CM=40ms/40us]
// Speed calculation
#define SPEED_CONSTANT 15468750 // SPEED_CONSTANT=(60s/min)/(Step size
of T12)
// Sensorless
#define BEMF_AUX_VAL11 0x18 // Phase A inactive (B+ C-)
#define BEMF_AUX_VAL12 0x24 // Phase A inactive (C+ B-)
#define BEMF_AUX_VAL21 0x12 // Phase B inactive (A+ C-)
#define BEMF_AUX_VAL22 0x21 // Phase B inactive (C+ A-)
#define BEMF_AUX_VAL31 0x06 // Phase C inactive (A+ B-)
#define BEMF_AUX_VAL32 0x09 // Phase C inactive (B+ A-)
Page: 1
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\DSPLIB_KEIL.H
/**********************************************************************************
* Module Header File
* Filename DspLib_Keil.h
* Project DSP library for C166S V2 Core
*----------------------------------------------------------------------------------
* Compiler: Keil
*
* Version: V 1.0
*
* Description:
* This header file lists
* 1. Typedef statements
* 2. All the functions of DSP Library
*----------------------------------------------------------------------------------
* Date: March 2008
**********************************************************************************/
#ifndef _DSPLIB_KEIL_H_
#define _DSPLIB_KEIL_H_
//*********************************************************************************
// This contains the user defined data types for the complex functions
//-----------------------------------------------------------------------------
typedef struct
{
short real;
short imag;
}CplxS;
typedef struct
{
long real;
long imag;
}CplxL;
Page: 1
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\DSPLIB_KEIL.H
Page: 2
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\DSPLIB_KEIL.H
Page: 3
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\DSPLIB_KEIL.H
Page: 4
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\DSPLIB_KEIL.H
);
extern DataS Bit_reverse(
DataS* X, // index input vector
DataS N // the size of the vector
);
extern void real_DIT_FFT(
DataS* x, // inpu vector
DataS* index, // bit reversed input indecies
DataS exp, // exponent of vector size
DataS* table, // trigonomic function table
DataS* X // output of FFT
);
extern void real_DIF_IFFT(
DataS* x, // output of IFFT
DataS* index, // bit reversed input indecies
DataS exp, // exponent of vector size
DataS* table, // trigonomic function table
DataS* X // inpu vector
);
extern void real_DIT_IFFT(
DataS* x, // output of IFFT
DataS* index, // bit reversed input indecies
DataS exp, // exponent of vector size
DataS* table, // trigonomic function table
DataS* X // inpu vector
);
//***************************** Statistical functions **************************
extern void Auto_raw(
DataS* x, // Pointer to input vector in 1Q15 format
DataS* y, // Pointer to output vector in 1Q15 format
DataS N_x, // Size of input vector
DataS N_y // Size of output vector, N_y <= N_x
);
extern void Auto_bias(
DataS* x, // Pointer to input vector in 1Q15 format
DataS* y, // Pointer to output vector in 1Q15 format
DataS N_x, // Size of input vector
DataS N_y // Size of output vector, N_y <= N_x
);
extern void Auto_unbias(
DataS* x, // Pointer to input vector in 1Q15 format
DataS* y, // Pointer to output vector in 1Q15 format
DataS N_x, // Size of input vector
DataS N_y // Size of output vector, N_y <= N_x
);
extern void Cross_raw(
DataS* x1, // Pointer to the first input vector in 1Q15 format
DataS* x2, // Pointer to the second input vector in 1Q15 forma
t
DataS* y, // Pointer to output vector in 1Q15 format
DataS N_x1, // Size of first input vector
DataS N_x2 // Size of second input vector, N_x2 <= N_x1
);
extern void Cross_bias(
DataS* x1, // Pointer to the first input vector in 1Q15 format
DataS* x2, // Pointer to the second input vector in 1Q15 forma
t
DataS* y, // Pointer to output vector in 1Q15 format
DataS N_x1, // Size of first input vector
DataS N_x2 // Size of second input vector, N_x2 <= N_x1
);
extern void Cross_unbias(
DataS* x1, // Pointer to the first input vector in 1Q15 format
DataS* x2, // Pointer to the second input vector in 1Q15 forma
t
DataS* y, // Pointer to output vector in 1Q15 format
DataS N_x1, // Size of first input vector
DataS N_x2 // Size of second input vector, N_x2 <= N_x1
Page: 5
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\DSPLIB_KEIL.H
);
extern void Convol(
DataS* x, // pointer to vector x
DataS* h, // pointer to input vector x
DataS* y, // pointer to output
DataS* d_buffer, // pointer to delay buffer
DataS N_x, // size of vector x
DataS N_h // size of vector h
);
//------------------- END OF FILE ----------------------------------------------
#endif
Page: 6
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\FloatTo1Q15.c
/******************************************************************************
; Module: FloatTo1Q15
; Filename: FloatTo1Q15.c
; Project: DSP library for C166S V2 Core
;------------------------------------------------------------------------------
; Compiler: Keil
;
; Version: V1.0
;
; Description: Changing the float format to 1Q15 format
;
; Date: Sept 2007
;
; Copyright: Infineon Technologies AG
;*****************************************************************************/
/******************************************************************************
; DataS FloatTo1Q15(float X);
;
; INPUTS:
; X the input value in float format
;
; RETURN:
; Y the output value in 1Q15 format
;
; ALGORITHM: According to the IEEE-754 format
;
; REGISTER USAGE:
; 1. From .c file to .asm file:
; (R8)=mmmmmmmmmmmmmmmm
; (R9)=seeeeeeeemmmmmmm (s:sign; e:exponent; m:mantissa)
;
; 2. From .asm file to .c file:
; (R4)=y
;
; Assumption:
;
;*****************************************************************************/
#include "DspLib_Keil.h"
DataS FloatTo1Q15(float x)
{
__asm
{
//read the exponent bits in R3
MOV R3,R9 ;(R3)=R9
SHL R3,#1h ;(R3)<<1
SHR R3,#8h ;(R3)>>8 = e
SUB R3,#7fh
JMPR cc_ULT,next ;if((R3)<127), jump
//if x=1
MOV R4,#07fffh ;(R4)=32767, in the case x=1
//read sign bit
MOV R2,R9 ;(R2)=(R9)
SHR R2,#0fh ;(R2)=(R2)>>15 =s
JMPR cc_Z,ende
//if x=-1
MOV R4,#8000h ;(R4)=32768, in the case x=-1
RET
next:
//read the mantissa in R4
MOV R4,R9 ;(R4)=(R9)
SHL R4,#9h ;(R4)<<9
SHR R4,#1h ;(R4)>>1
SHR R8,#8h ;(R8)>>8
Page: 1
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\FloatTo1Q15.c
RET
next1:
SHR R4,R3
//read the sign bit R2
MOV R2,R9 ;(R2)=(R9)
SHR R2,#0fh ;(R2)=(R2)>>15 =s
JMPR cc_Z,ende
NEG R4
ende:
RET
}
}
//------------------- END OF FILE ----------------------------------------------
Page: 2
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\PI_CTRL.C
//*****************************************************************************/
// @Module PI Controller
// @Filename PI_CTRL.C
// @Controller XC16x Series
//
//
// @Description This file contains functions for PI Control algorithms
//
//****************************************************************************
//****************************************************************************
// @Function
//
// int pi_controller64(long *pi_parameter,int reference,int actual)
//
//----------------------------------------------------------------------------
// @Description
//
// PI-Controller
// derived from transfer function G = kp + 1/(p*Ti)
//
// e(k) = reference - actual T0 =
// yn(k+1)= yn(k) + ki * e(k) ki = T0/Ti
// y(k+1) = yn(k+1) + kp * e(k) * 64
//----------------------------------------------------------------------------
// Computing time 42 CPU-cycle
//
//----------------------------------------------------------------------------
// @Returnvalue
//
//----------------------------------------------------------------------------
// @Parameters
//
//--------------------------- Arguments -------------------------------------
// reference : reference value
// actual : actual value
//
// struct pi_parameter
// {
// int yn; Integral buffer
// int kp; Proportional Constant
// int ki; Integral Constant
// int ymax; Limit value max
// int ymin; Limit value min
// };
//---------------------------------------------------------------------------
// Register modified:
//
// R1,R3,R4,R5,R6,R7,R8,R9,R10
//
//----------------------------------------------------------------------------
//
//****************************************************************************
Page: 1
C:\Users\Pablo\Documents\Universidad\PFC\Software\Definitivo\PI_CTRL.C
#pragma endasm
a = reference;
a = actual;
a = *pi_parameter;
Page: 2
Flowcharts
117
118 B.1. FLOWCHARTS OF THE CONTROL PROCESS
Main
MAIN_vinit()
ADC_OFFSET()
INIT_CTRL_VAR()
TRAP_RESET()
MOTOR_OPERATION () Motor_stop
RampUp() status_overvoltemp = 1
NO YES
Overvoltage or
overtemperature?
APPENDIX B. FLOWCHARTS
B.1. FLOWCHARTS OF THE CONTROL PROCESS 119
Main_vInit()
MAIN_vUnlockProtecReg()
MAIN_vChangeFreq()
IO_vInit()
CCU60_vInit()
ADC0_vInit()
ADC1_vInit()
MAIN_vLockProtecReg()
Return
APPENDIX B. FLOWCHARTS
120 B.1. FLOWCHARTS OF THE CONTROL PROCESS
TRAP_RESET()
trap_reset
requested?
NO
YES
trap_reset = 0
status_ctrap = 0
Return
APPENDIX B. FLOWCHARTS
B.1. FLOWCHARTS OF THE CONTROL PROCESS 121
MOTOR_OPERATION()
Is a trap YES
latched?
Set stop
command
NO
NO Is the motor
ready to start?
YES
Motor_stop() Motor_start()
Return
APPENDIX B. FLOWCHARTS
122 B.1. FLOWCHARTS OF THE CONTROL PROCESS
Motor_start()
NO
Is the first time?
YES
once = 1
status_on = 1
YES
sv_start_ref =
sv_end_ref
sv_start_ref0 = sv_start_ref
speed_ref = sv_start_ref
Init_control()
Commutation_init
Return
APPENDIX B. FLOWCHARTS
B.1. FLOWCHARTS OF THE CONTROL PROCESS 123
Motor_stop()
Disable Trap
Update status_word
Update direction
return
APPENDIX B. FLOWCHARTS
124 B.1. FLOWCHARTS OF THE CONTROL PROCESS
Init_control
Return
APPENDIX B. FLOWCHARTS
B.1. FLOWCHARTS OF THE CONTROL PROCESS 125
Commutation_init()
Run T13
Run T12
Enable Trap
Return
APPENDIX B. FLOWCHARTS
126 B.1. FLOWCHARTS OF THE CONTROL PROCESS
RampUp()
NO
Is the period time
reached?
YES
Increment counter
YES
Speed_ref_ramp()
Reset counter
NO
Is there a new end
reference?
YES
Return
APPENDIX B. FLOWCHARTS
B.1. FLOWCHARTS OF THE CONTROL PROCESS 127
Speed_ref_ramp
NO
Is the end
reference bigger?
YES
Increase
speed
reference
NO
Is the end
reference lower?
YES
Decrease
speed
reference
Return
APPENDIX B. FLOWCHARTS
128 B.1. FLOWCHARTS OF THE CONTROL PROCESS
CCU60_viNodeI1
NO
Is CCU60_IS_T12PM?
YES
status_timeout = 1
Motor_stop()
NO
Is CCU60_IS_TRPF
YES
status_ctrap = 1
Motor_stop()
NO
Is CCU60_IS_WHE?
YES
status_hs_error = 1
YES
Is possible to change to
sensorless?
NO
1
Motor_stop()
Return
APPENDIX B. FLOWCHARTS
B.1. FLOWCHARTS OF THE CONTROL PROCESS 129
Save actual
time T12
NO
Reconfigure
Reconfigure registers
registers
NO
Force
commutation
NO
Load next
pattern
Return
APPENDIX B. FLOWCHARTS
130 B.1. FLOWCHARTS OF THE CONTROL PROCESS
CCU60_viNodeI2
NO
Is CCU60_IS_ICC62R
YES
Load next
pattern
Speed_calc
Set Rising
NO edge
detection
YES
Have we detected a
rising edge before?
Set falling
NO edge
detection
Reset speed
YES
to 0
Return
APPENDIX B. FLOWCHARTS
B.1. FLOWCHARTS OF THE CONTROL PROCESS 131
Speed_calc()
Accumulate
new measure
Substract old
sample
NO
Update the
buffer index
Return
APPENDIX B. FLOWCHARTS
132 B.1. FLOWCHARTS OF THE CONTROL PROCESS
CCU60_viNodeI3
T13 Compare NO
Match?
YES
NO
T13 Period
Match
YES
Is BEMF already NO
detected?
Sensorless_calc
YES
Do the
control loops
Update Duty
Cycle
Return
APPENDIX B. FLOWCHARTS
B.1. FLOWCHARTS OF THE CONTROL PROCESS 133
Sensorless_calc()
NO Is the slope
known?
YES
NO Is BEMF ZC
detected in the NO
Rising
assumed slope? edge?
YES YES
BEMF NO NO BEMF
NO Is a detected? detected?
reasonable
value? YES YES
Slope_known = 1
Save zc time Save zc time
Slope = 3 Slope = 2
Sensorless NO NO Sensorless
mode? mode?
YES YES
Set the compare registers for Set the compare registers for
the next commutation and the next commutation and
speed measurement speed measurement
Return
APPENDIX B. FLOWCHARTS
134 B.1. FLOWCHARTS OF THE CONTROL PROCESS
ADC0_viSRN0
Is it between a NO
tolerance limit?
YES
NO Maximal time
exceeded?
YES
Status_overcurrent = 1
Motor_stop()
Return
APPENDIX B. FLOWCHARTS