Use of PWM and ADC on MC56F84789 to Drive Dual PMS Motor FOC

Freescale Semiconductor
Application Note
Document Number:AN4608
Rev. 0, 10/2012
Use of PWM and ADC on
MC56F84789 to Drive Dual PMS
Motor FOC
by:
Jaroslav Musil
Contents
1 Introduction
1
Introduction............................................................1
With the computation power of Freescale digital signal
controllers (DSCs) and the flexibility of their peripherals, the
requirements for the applications grow up. One of such
requirements is to drive two permanent magnet synchronous
motors (PMSM) in field-oriented control (FOC) on a single
processor.
2
Digital signal controller (DSC)...............................2
3
Steps in configuration flow ....................................2
4
PWM configuration.................................................3
5
PWM A and PWM B synchronization....................6
6
PWM triggers for ADC...........................................9
7
ADC configuration................................................11
8
PWM and ADC signals
interconnection.....................................................13
9
Triggers startup sequence.....................................15
10
Reading ADC samples..........................................16
11
Complete code.......................................................19
12
Definitions and acronyms.....................................24
Dual PMSM FOC on a single processor brings more
complexity to the application, mainly in terms of the PWM
modules of synchronization of both the motors, the ADC
synchronization to both the PWM modules including a right
point to trigger the ADC, and finally, the time when the fast
and slow control loops of both the motors are calculated.
This application note guides:
• to set up and synchronize both the PWM modules
• how and where to generate trigger signals for the ADC
module from the PWM module
• when to call the fast and slow loop calculation of FOC
algorithm of both the motors
© 2012 Freescale Semiconductor, Inc.
Digital signal controller (DSC)
2 Digital signal controller (DSC)
One of suitable DSCs for dual motor control application is MC56F84789. This controller has the following features the
application can benefit from:
• 100 MHz core and peripheral clock
• Two 4-channel PWM modules with a possibility of multiple triggers
• High-speed 12-bit ADC with a possibility to sample two signals simultaneously
• Two crossbar units to interconnect signals between the peripherals
• And-Or-Invert to logically mix the signals among the peripherals
• Interrupt controller with priorities
The processor has much more modules but for this application note, only the above-mentioned ones will be discussed.
Figure 1 shows how the processor signals are connected to the power electronics on the board.
Figure 1. Processor connection to the board circuitry
3 Steps in configuration flow
In order to configure the DSC properly, follow the steps given below:
• PWM configuration: It configures the PWM A and B modules to generate signals to drive the motors.
• PWM A and B synchronization: It synchronizes the PWM A and B signals to be in phase shift of 90 degrees.
• PWM triggers for ADC: It sets up the points where the ADC will be triggered to sample the signals.
Use of PWM and ADC on MC56F84789 to Drive Dual PMS Motor FOC, Rev. 0, 10/2012
2
Freescale Semiconductor, Inc.
PWM configuration
• ADC configuration: It configures the ADC modules to sample the desired signals.
• PWM and ADC signal interconnection: It configures the crossbar switches and the AOI module to lead the PWM
triggered toward the ADC synchronization input.
• Triggers startup sequence: It enables the triggers in the correct sequence to be aligned with the ADC channels
sequence.
• Reading ADC samples: It sets up the interrupts to read the sampled values and call the algorithms.
All the above-mentioned steps are mentioned in detail, in the forthcoming sections.
4 PWM configuration
For the example of this application, the two motors will be driven with the same frequency of the PWM and the same
frequency of the fast control loop calculation. The PWM frequency is 10 kHz and the fast loop calculation will be in the ratio
1:1 with respect to the PWM frequency, therefore 10 kHz as well. Motor 1 will use the PWM A module, submodules 0–2
whereas Motor 2 will use the PWM B module, submodules 0–2; in complementary mode with non-inverted output logic.
The first step is to configure the PWM A and PWM B as shown in Figure 2.
Figure 2. PWM configuration
Clock for PWMs
To habilitate the clock for both PWM modules, it is necessary to configure the Peripheral Clock Register 3 (SIM_PCE3)
from the System Integration Module (SIM).
The following syntax can be used to enable the clock for PWM A channels 0–2:
SIM_PCE3 |= (SIM_PCE3_PWMACH0 | SIM_PCE3_PWMACH1 | SIM_PCE3_PWMACH2);
The following syntax can be used to enable the clock for PWM B channels 0–2:
SIM_PCE3 |= (SIM_PCE3_PWMBCH0 | SIM_PCE3_PWMBCH1 | SIM_PCE3_PWMBCH2);
PWM Control Register
Both the motors will use the half cycle every opportunity reload. The PWM clock frequency is maximum; so the prescaler is
1.
Therefore the control registers for both PWM A and PWM B modules will be set up using the following syntax.
Use of PWM and ADC on MC56F84789 to Drive Dual PMS Motor FOC, Rev. 0, 10/2012
Freescale Semiconductor, Inc.
3
PWM configuration
Motor 1:
PWMA_SM0CTRL = PWMA_SM0CTRL_HALF;
PWMA_SM1CTRL = PWMA_SM1CTRL_HALF;
PWMA_SM2CTRL = PWMA_SM2CTRL_HALF;
Motor 2:
PWMB_SM0CTRL = PWMB_SM0CTRL_HALF;
PWMB_SM1CTRL = PWMB_SM1CTRL_HALF;
PWMB_SM2CTRL = PWMB_SM2CTRL_HALF;
PWM Control 2 Register
The setup of the co-operation of the submodules requires PWM Control 2 Register to be properly set up.
1. Enable the PWM in the debug and wait mode, force initialization for the channels 0
2. For the channels 1 and 2, set the additional bits:
• initialization from the master sync from submodule 0
• master reload signal to force the update
• master reload from submodule 0 to reload value registers
• submodule 0 clock to be used as the clock source
The control registers for both the modules can be configured using the following syntax.
Motor 1:
PWMA_SM0CTRL2 = 0xC080;
PWMA_SM1CTRL2 = 0xC20E;
PWMA_SM2CTRL2 = 0xC20E;
Motor 2:
PWMB_SM0CTRL2 = 0xC080;
PWMB_SM1CTRL2 = 0xC20E;
PWMB_SM2CTRL2 = 0xC20E;
PWM modulo setup
The PWM modulo to generate 10 kHz is derived from the 100 MHz clock. Thus, the modulo is 100 MHz / 10 kHz = 10,000
ticks. The PWM modules have the INIT register value where the counter starts and VAL1 register value where the counter is
reinitialized. So, the INIT value will be set up to negative value of the half modulo, and the VAL1 value will be set up to
positive value of the half modulo–1. The reload is in the half cycle, that is, in the middle of these two values. To sum it up:
INIT =–5000 (0xEC78), VAL1 = 4999 (0x1387), VAL0 = 0. The following syntax can be used to configure it.
Motor 1:
PWMA_SM0INIT = 0xEC78;
PWMA_SM1INIT = 0xEC78;
PWMA_SM2INIT = 0xEC78;
PWMA_SM0VAL1 = 0x1387;
PWMA_SM1VAL1 = 0x1387;
PWMA_SM2VAL1 = 0x1387;
PWMA_SM0VAL0 = 0x0000;
PWMA_SM1VAL0 = 0x0000;
PWMA_SM2VAL0 = 0x0000;
Motor 2:
PWMB_SM0INIT = 0xEC78;
PWMB_SM1INIT = 0xEC78;
PWMB_SM2INIT = 0xEC78;
PWMB_SM0VAL1 = 0x1387;
PWMB_SM1VAL1 = 0x1387;
Use of PWM and ADC on MC56F84789 to Drive Dual PMS Motor FOC, Rev. 0, 10/2012
4
Freescale Semiconductor, Inc.
PWM configuration
PWMB_SM2VAL1 = 0x1387;
PWMB_SM0VAL0 = 0x0000;
PWMB_SM1VAL0 = 0x0000;
PWMB_SM2VAL0 = 0x0000;
50% duty cycle initialization
To initialize the module with the 50% duty cycle, it is necessary to set up the VAL2 and VAL3 registers. As it is the
Complementary mode, the VAL4 and VAL5 registers are not used for the PWM edges generation. VAL2 is loaded with a
negative value of the half modulo divided by 2; VAL3 is loaded with the positive value of the half modulo divided by 2.
Therefore VAL2 =–2500 (0xF63CU), VAL3 = 2500 (0x09C3). The following syntax can be used to configure it.
Motor 1:
PWMA_SM0VAL2 = 0xF63C;
PWMA_SM1VAL2 = 0xF63C;
PWMA_SM2VAL2 = 0xF63C;
PWMA_SM0VAL3 = 0x09C3;
PWMA_SM1VAL3 = 0x09C3;
PWMA_SM2VAL3 = 0x09C3;
Motor 2:
PWMB_SM0VAL2 = 0xF63C;
PWMB_SM1VAL2 = 0xF63C;
PWMB_SM2VAL2 = 0xF63C;
PWMB_SM0VAL3 = 0x09C3;
PWMB_SM1VAL3 = 0x09C3;
PWMB_SM2VAL3 = 0x09C3;
2 µs deadtime
To set up the deadtime, configure the DTCNT0 (top switch) and DTCNT1 (bottom switch) register values. The value is
derived from the module clock, therefore for 2 µs, the value will be 100 MHz x 2 µs = 200 (0x00C8). The following code
configures the deadtime:
Motor 1:
PWMA_SM0DTCNT0 = 0x00C8;
PWMA_SM1DTCNT0 = 0x00C8;
PWMA_SM2DTCNT0 = 0x00C8;
PWMA_SM0DTCNT1 = 0x00C8;
PWMA_SM1DTCNT1 = 0x00C8;
PWMA_SM2DTCNT1 = 0x00C8;
Motor 2:
PWMB_SM0DTCNT0 = 0x00C8;
PWMB_SM1DTCNT0 = 0x00C8;
PWMB_SM2DTCNT0 = 0x00C8;
PWMB_SM0DTCNT1 = 0x00C8;
PWMB_SM1DTCNT1 = 0x00C8;
PWMB_SM2DTCNT1 = 0x00C8;
Disable faults
This example will not use the fault logic, so it is necessary to disable the fault mapping registers using the following syntax.
Motor 1:
PWMA_SM0DISMAP0 = 0;
PWMA_SM1DISMAP0 = 0;
PWMA_SM2DISMAP0 = 0;
Use of PWM and ADC on MC56F84789 to Drive Dual PMS Motor FOC, Rev. 0, 10/2012
Freescale Semiconductor, Inc.
5
PWM A and PWM B synchronization
PWMA_SM0DISMAP1 = 0;
PWMA_SM1DISMAP1 = 0;
PWMA_SM2DISMAP1 = 0;
Motor 2:
PWMB_SM0DISMAP0 = 0;
PWMB_SM1DISMAP0 = 0;
PWMB_SM2DISMAP0 = 0;
PWMB_SM0DISMAP1 = 0;
PWMB_SM1DISMAP1 = 0;
PWMB_SM2DISMAP1 = 0;
LDOK bit
The final step before running PWM is to clear and set MCTRL[LDOK] using the following code.
Motor 1:
PWMA_MCTRL |= PWMA_MCTRL_CLDOK_0 | PWMA_MCTRL_CLDOK_1 | PWMA_MCTRL_CLDOK_2;
PWMA_MCTRL |= PWMA_MCTRL_LDOK_0 | PWMA_MCTRL_LDOK_1 | PWMA_MCTRL_LDOK_2;
Motor 2:
PWMB_MCTRL |= PWMB_MCTRL_CLDOK_0 | PWMB_MCTRL_CLDOK_1 | PWMB_MCTRL_CLDOK_2;
PWMB_MCTRL |= PWMB_MCTRL_LDOK_0 | PWMB_MCTRL_LDOK_1 | PWMB_MCTRL_LDOK_2;
The PWM A and PWM B are configured to generate a signal as shown in Figure 1. But to get their signals out on the pins,
the GPIO pins must be properly configured. So, certain GPIO E and GPIO G pins must be set up as peripherals. In case of
multiple peripheral options, the PWM option must be chosen. The GPIO E and GPIO G clocks must be also enabled. The
code is the following:
/* Enable GPIOE clock */
SIM_PCE0 |= SIM_PCE0_GPIOE;
/* PWMA PWMB */
GPIOE_PER |= (GPIOE_PER_PE_0 | GPIOE_PER_PE_1 | GPIOE_PER_PE_2 | GPIOE_PER_PE_3 |
GPIOE_PER_PE_4 | GPIOE_PER_PE_5 | GPIOE_PER_PE_8 | GPIOE_PER_PE_9);
SIM_GPSEL &= ~(SIM_GPSEL_E4 | SIM_GPSEL_E5);
SIM_GPSEH &= ~(SIM_GPSEH_E8 | SIM_GPSEH_E9);
/* Enable GPIOG clock */
SIM_PCE0 |= SIM_PCE0_GPIOG;
/* PWM B */
GPIOG_PER |= (GPIOG_PER_PE_0 | GPIOG_PER_PE_1 | GPIOG_PER_PE_2 | GPIOG_PER_PE_3);
SIM_GPSGL &= ~(SIM_GPSGL_G0 | SIM_GPSGL_G1 | SIM_GPSGL_G2 | SIM_GPSGL_G3);
Finally, the only missing items are to send the run command to the modules to start generation of the signal and to enable the
PWM signals out on the pins. The PWM modules must not be started at this time because it is needed to synchronize both the
PWMs.
5 PWM A and PWM B synchronization
The PWM A and PWM B have been configured; they haven’t been started yet. So the next step is to synchronize the PWM
modules somehow.
Use of PWM and ADC on MC56F84789 to Drive Dual PMS Motor FOC, Rev. 0, 10/2012
6
Freescale Semiconductor, Inc.
PWM A and PWM B synchronization
To calculate the fast loop algorithm in each PWM cycle, it is necessary to shift the PWM signals to each other because it is
impossible to calculate the algorithms of two motors at the same time. Therefore, the PWM signals must be shifted. To
effectively distribute the energy from the DC bus capacitor, it is recommended to avoid simultaneous switching; that is, to be
shifted by 180 degrees. As the MC56F84789 processor has good computation power to calculate the FOC algorithm quickly
and effectively, the signals will be shifted by 90 degrees to have an optimum.
The desired signals from both PWM modules are shown in Figure 3.
PWM 90-degree shift principle
As shown in Figure 3, the PWM B INIT value lags by 90 degrees with respect to the PWM A INIT value. This shift is equal
to the modulo divided by 4. When the PWM RUN signal is applied, the PWM module starts counting up from the INIT
value, which is beneficial for this application.
The process to synchronize the PWM modules includes:
• starting the PWM A module
• generating an interrupt at the modulo / 4 instant from the PWM A module
• starting the PWM B module from the generated PWM A module interrupt
• disabling the further interrupt for this PWM A module event
Modulo / 4 event configuration
Before starting the PWM A module, the interrupt on the module / 4 event must be programmed. To generate such an event,
the unused VAL5 value will be used. It does not matter which submodule will generate this event. In this example, the
submodule 1 VAL5 value will be used.
So in the code, the submodule 1 VAL5 is to be programmed with the modulo / 4 value, which is –2500 (0xF63C); the
compare interrupt of this submodule is to be enabled and the interrupt controller has to be programmed to enable this
interrupt.
The code lines are the following:
/* Sync for the other motor's PWM */
PWMA_SM1VAL5 = 0xF63C;
/* Compare interrupt of Value 5, used at init to sync PWM A and PWM B */
PWMA_SM1INTEN = PWMA_SM1INTEN_CMPIE_5;
/* Interrupt for the SM1 CMP Level 2 */
INTC_IPR9 |= INTC_IPR9_PWMA_CMP1;
Use of PWM and ADC on MC56F84789 to Drive Dual PMS Motor FOC, Rev. 0, 10/2012
Freescale Semiconductor, Inc.
7
PWM A and PWM B synchronization
Figure 3. PWM A and PWM B synchronization
VAL5 Compare interrupt service routine
The PWM submodule 1 VAL5 Compare interrupt has been configured. Now the interrupt service routine (ISR) must be
created to start the PWM B module.
The name of the ISR will be IsrPWMSync. A prototype for this routine must be created in the prototype section of the code:
void IsrPWMSync(void);
The name of this function must be copied into the vector table; in case the default CodeWarrior 10.2 project template is used,
it is in the file MC56F847xx_vector.asm (located in Project_Settings\Startup_Code). Thus at the address 0xAA, the interrupt
no. 85 for the PWM A submodule 1 will contain the following statement:
JSR
>FIsrPWMSync
The body of the function itself contains the following actions:
• if condition, if the source is the VAL5 Compare
• RUN command application on the PWM B module
• disabling the VAL5 Compare interrupt
• clearing the VAL5 Compare flag
So putting all this into the code will look like this:
#pragma interrupt alignsp
void IsrPWMSync(void)
{
if ((PWMA_SM1STS & PWMA_SM1STS_CMPF_5) > 0 )
{
/* Starts PWM B */
PWMB_MCTRL |= PWMB_MCTRL_RUN_0 | PWMB_MCTRL_RUN_1 | PWMB_MCTRL_RUN_2;
/* Disable PWM SM1 CMP interrupt from 5 */
PWMA_SM1INTEN &= ~PWMA_SM1INTEN_CMPIE_5;
Use of PWM and ADC on MC56F84789 to Drive Dual PMS Motor FOC, Rev. 0, 10/2012
8
Freescale Semiconductor, Inc.
PWM triggers for ADC
}
/* Clears compare flag */
PWMA_SM1STS |= PWMA_SM1STS_CMPF_5;
}
PWM A start
The PWM A and B channels have been configured, the synchronization event has been set up, and the interrupt service
routine is written. So now, the only action is to apply the RUN command on the PWM A and enable the PWM A and PWM
B signals out to the pins. When the PWM A is started, it will generate the programmed submodule 1 VAL5 Compare
interrupt where the PWM B will be started and this interrupt, blocked.
The code to start the PWM A is the following (this command is to be called after the PWM A and PWM B modules
configuration and after the Compare interrupt is set up):
PWMA_MCTRL |= PWMA_MCTRL_RUN_0 | PWMA_MCTRL_RUN_1 | PWMA_MCTRL_RUN_2;
The command to enable the PWM A and PWM B singals out to the pins will look like this:
PWMA_OUTEN |= (PWMA_OUTEN_PWMA_EN_0 | PWMA_OUTEN_PWMB_EN_0 | PWMA_OUTEN_PWMA_EN_1 |
PWMA_OUTEN_PWMB_EN_1 | PWMA_OUTEN_PWMA_EN_2 | PWMA_OUTEN_PWMB_EN_2);
PWMB_OUTEN |= (PWMB_OUTEN_PWMA_EN_3 | PWMB_OUTEN_PWMB_EN_3 | PWMB_OUTEN_PWMA_EN_1 |
PWMB_OUTEN_PWMB_EN_1 | PWMB_OUTEN_PWMA_EN_2 | PWMB_OUTEN_PWMB_EN_2);
Figure 3 shows the signals on the pins, that should be also observed on the scope.
6 PWM triggers for ADC
The FOC of PMSM requires analog signals which are used in the control algorithm to be measured. The required quantities
for such control are the motor phase currents and the DC bus voltage.
Typically the currents are measured on shunt resistors connected below the bottom MOSFET’s (or IGBT’s). See Figure 4. In
this constellation, the motor current is only visible when the particular bottom MOSFET is turned on. Therefore the ADC
must be synchronized to the PWM signals (see Figure 5). The current can be measured at the instant when the bottom
MOSFET is turned on, whereas measuring at the instant when the bottom MOSFET is turned off, will only give the offset on
the ADC channel. This point will be used to calibrate the ADC channel offset because a known value is expected.
The DC bus voltage does not have such requirements for the point where it is measured.
Figure 4. Three-phase inverter schematics
Use of PWM and ADC on MC56F84789 to Drive Dual PMS Motor FOC, Rev. 0, 10/2012
Freescale Semiconductor, Inc.
9
PWM triggers for ADC
Figure 5. Best time to measure motor current
Now putting it all into the context, the following quantities are to be measured:
• 2 current channels' offsets of Motor 1 (the 3rd current is calculated)
• 2 currents of Motor 1
• 2 current channels' offsets of Motor 2 (the 3rd current is calculated)
• 2 currents of Motor 2
• DC bus voltage
Figure 6. Current and offset measurement points
PWM triggers
Figure 6 indicates the points where the currents and their offsets will be measured. It can be seen that the current
measurement point is slightly delayed behind the INIT value and the offset point is slightly delayed behind the VAL0 value.
Use of PWM and ADC on MC56F84789 to Drive Dual PMS Motor FOC, Rev. 0, 10/2012
10
Freescale Semiconductor, Inc.
ADC configuration
As the PWM modules use the complementary switching mode, the VAL4 and VAL5 values are free to be used as the triggers
for the ADC. In this example, the deadtime of 2 µs is applied, and assuming a certain delay on hardware, the final delay to be
applied will be 3.25 µs.
So, the VAL4 value will be:
INIT + 3.25 µs / 100 MHz = –4675 (0xEDBD).
The VAL5 value will be:
VAL0 + 3.25 µs / 100 MHz = 325 (0x0145).
Submodule 0 will be used to generate these triggers. Programming of these PWM values will have the following code
statement:
Motor 1:
PWMA_SM0VAL4 = 0xEDBD;
PWMA_SM0VAL5 = 0x0145;
/* Current measurement value */
/* Offset measurement value */
Motor 2:
PWMB_SM0VAL4 = 0xEDBD;
PWMB_SM0VAL5 = 0x0145;
/* Current measurement value */
/* Offset measurement value */
The triggers will not be enabled at this moment. They must be enabled in a particular sequence described in Triggers startup
sequence.
7 ADC configuration
To sample the quantities, the fast 12-bit ADC A and ADC B will be used in the Simultaneous mode. The Simultaneous mode
is a great feature of the ADC and due to that, two current values can be captured at the same time. The following steps show
how to set up the ADC properly.
Clock for ADC
To habilitate the clock for the ADC, it is necessary to configure Peripheral Clock Register 2 (SIM_PCE2) from the System
Integration Module (SIM).
Syntax to enable the clock for ADC is this:
SIM_PCE2 |= SIM_PCE2_CYCADC;
Control Register 1
This register configures the ADC behavior. To configure this register:
• Set up the hardware synchronization (which is necessary to start the ADC by a signal from the PWM module).
• Enable the end-of-scan interrupt.
• Set up the ADC parallel mode scan.
• The stop mode is not active.
• All channels are single-ended.
• Additional interrupts as well as the DMA are turned off.
The statement is the following:
ADC12_CTRL1 = 0x1805;
Control Register 2
By this register, the ADC A and B converters will be configured to work simultaneously and the clock will be set up to run
the ADC on 20 MHz. The statement is this:
Use of PWM and ADC on MC56F84789 to Drive Dual PMS Motor FOC, Rev. 0, 10/2012
Freescale Semiconductor, Inc.
11
ADC configuration
ADC12_CTRL2 = ADC12_CTRL2_DIV0_2 | ADC12_CTRL2_SIMULT;
Power Control Register
This register serves to control the power options of the ADC. To configure this register:
• It is necessary to power up the ADC converters.
• The option "power-up delay" will remain default, 26 clocks.
The code line is this:
ADC12_PWR = 0x01A0;
Power Control Register 2
This register configures the clock for the ADC B converter and the speed of both the converters. So, the clock for the B
converter will be 20 MHz and the speed of both converters will be set up for 20 MHz. The statement is this:
ADC12_PWR2= ADC12_PWR2_SPEEDA | ADC12_PWR2_SPEEDB | ADC12_PWR2_DIV1_2;
Channel List Registers
Now, it is necessary to configure the channel list registers. Both ADC converters have 8 samples, that is, it can sample 8
channels at a time and save their results of ADC A and ADC B. If these two converters run in the Simultaneous mode, the A
converter samples only the ANAx channels, and the B converter, samples only the ANBx channels.
This example will sample the Motor 1 currents on ANA0 and ANB0 and the Motor 2 currents, on ANA2 and ANB2. The DC
bus voltage will be sampled by the ANB4 channel.
Figure 7 shows the configuration of the channels. To attach the channels to the particular samples, the four channel list
registers are used. Each configures four samples. So the code to set up the channels is the following:
ADC12_CLIST1
ADC12_CLIST2
ADC12_CLIST3
ADC12_CLIST4
=
=
=
=
0x0200;
0x0002;
0x8AC8;
0x888A;
Sample Disable Register
This example will use just 5 samples of each converter. The rest must be disabled. The ADC works the way that it generates
the end-of-scan interrupt when the last enabled sample is finished. To disable the unused samples according to Figure 7, the
register will be set up using the following code:
ADC12_SDIS = 0xE0E0;
Scan Control Register
Another very useful feature is the Scan Control Register. This feature allows synchronization of sampling on multiple events
and the end-of-scan interrupt is generated after the last enabled sample. This is visible in Figure 7 at the Sync line.
1. On the first sync signal (trigger from PWM), the current offsets of two phases of Motor 1 will be sampled and as the
following sync is set at sample 2, the sample 1 and 9 will be converted too and then the ADC will stop. So, the DC bus
voltage will be on sample 9.
2. When the next sync arrives, the offset of Motor 2 is sampled.
3. On the next sync, the current of Motor 1 will be sampled and the ADC will stop.
4. And on the next sync the current of Motor 2 will be sampled, the ADC will stop and generate the end-of-scan interrupt.
With the new sync signal, the cycle begins.
Use of PWM and ADC on MC56F84789 to Drive Dual PMS Motor FOC, Rev. 0, 10/2012
12
Freescale Semiconductor, Inc.
PWM and ADC signals interconnection
Figure 7. ADC samples and channels
To configure this sync feature, the Scan Control register is used. The sync will be attached to the samples 0, 2, 3 (bits 0, 2, 3)
and the sample 4 (bit 8). The code line looks like this:
ADC12_SCTRL = 0x010D;
Analog (AN) pins configuration
To read analog values from the pins, the GPIO A and GPIO B pins 0–7 must be configured as peripherals with the ADC
option. The clock for the GPIO modules must be enabled. The code is the following:
/* Enable GPIOA clock */
SIM_PCE0 |= SIM_PCE0_GPIOA;
/* ADCA */
GPIOA_PER |= (GPIOA_PER_PE_0 | GPIOA_PER_PE_1 | GPIOA_PER_PE_2 | GPIOA_PER_PE_3 |
GPIOA_PER_PE_4 | GPIOA_PER_PE_5 | GPIOA_PER_PE_6 | GPIOA_PER_PE_7);
SIM_GPSAL &= ~(SIM_GPSAL_A0);
/* Enable GPIOB clock */
SIM_PCE0 |= SIM_PCE0_GPIOB;
/* ADCB */
GPIOB_PER |= (GPIOB_PER_PE_0 | GPIOB_PER_PE_1 | GPIOB_PER_PE_2 | GPIOB_PER_PE_3 |
GPIOB_PER_PE_4 | GPIOB_PER_PE_5 | GPIOB_PER_PE_6 | GPIOB_PER_PE_7);
8 PWM and ADC signals interconnection
To summarize at this point, the following steps have been covered.
• The PWM modules have been configured and synchronized.
• The PWM points where to generate triggers have been set up
• The ADC module and channels have been configured.
• The sync bit has been properly set at the ADC samples.
The next step to make it work is to properly connect the triggers from the PWM A and PWM B module to the ADC
synchronization signal input. To do this, Inter-Peripheral Crossbar Switch A (XBAR A) is used.
XBAR A is capable of connecting one output of a peripheral to one input; but this system has four trigger signals from two
peripherals and one ADC input. Therefore, in this case, the logical OR of the triggers has to be made and the OR result signal
will be led to the ADC input. A module that has the ability to OR the signals is the And/Or/Invert (AOI) module. To get the
PWM triggers on the AOI inputs, another module will be used, Inter-Peripheral Crossbar Switch B (XBAR B). See Figure 8.
Use of PWM and ADC on MC56F84789 to Drive Dual PMS Motor FOC, Rev. 0, 10/2012
Freescale Semiconductor, Inc.
13
PWM and ADC signals interconnection
Figure 8. PWM and ADC interconnection
XBAR B configuration
XBAR B provides the connections of the peripheral outputs to the AOI module. Both PWM modules use the VAL4 and
VAL5 registers to generate triggers. These triggers are grouped into two groups: PWM_OUT_TRIG0 and
PWM_OUT_TRIG1. The former group is made of the VAL0, VAL2 and VAL4 triggers while the latter group is made of the
VAL1, VAL3 and VAL5 triggers. This means that two output signals will leave both PWM modules.
The first four inputs of XBAR B connect to product term 0 of the AOI, therefore the PWM signals will be connected to
XBAR B in the following manner:
• PWMA sub-module 0 triggers (PWMA0_TRG0 | PWMA0_TRG1) to AOI product term 0 input 0
• PWMB sub-module 0 triggers (PWMB0_TRG0 | PWMB0_TRG1) to AOI product term 0 input 1
So the XBAR_IN8 and XBAR_IN22 inputs will be assigned to the first two XBAR B outputs. The code will have this
syntax:
XBARB_SEL0 = 8 | (22 << 8);
AOI configuration
As the name suggests, this module is capable of performing logical AND/OR/INVERT operation. This application benefits
from the OR and AND operation. The inverter is not used. The way the AND/OR operators work is visible in Figure 8.
Only two input signals are used which lead to one input of two AND gates. The remaining three inputs of both AND gates
are forced to logical 1. The unused inputs of the two AND gates are forced to logical 0. This setup will only pass the two
PWM signals to the OR gate inputs. And the OR gate output goes out of the AOI.
The configuration codeline is the following:
AOI_BFCRT010 = AOI_BFCRT010_PT0_AC_0 | AOI_BFCRT010_PT0_BC | AOI_BFCRT010_PT0_CC |
AOI_BFCRT010_PT0_DC | AOI_BFCRT010_PT1_AC | AOI_BFCRT010_PT1_BC_0 | AOI_BFCRT010_PT1_CC |
AOI_BFCRT010_PT1_DC;
AOI_BFCRT230 = 0;
XBAR A configuration
Use of PWM and ADC on MC56F84789 to Drive Dual PMS Motor FOC, Rev. 0, 10/2012
14
Freescale Semiconductor, Inc.
Triggers startup sequence
The last signal path is to connect the output from the AOI to the ADC. This configuration is very easy; the inptut to XBAR A
AND_OR_INVERT_0 (AOI Output 0) is attached to the XBAR A output XBAR_OUT12 (ADC A trigger). The code looks
like this:
XBARA_SEL6 = 46;
9 Triggers startup sequence
All the peripherals have been properly configured to generate the trigger at the desired time. The signals are logically
processed and led toward the ADC synchronization pulse input. The final step is to start the triggers.
The configuration of ADC is done to perform the sampling operation in the following order:
• Offset of Motor 1
• Offset of Motor 2
• Current of Motor 1
• Current of Motor 2
It can be inferred from Figure 6, the PWM A VAL5 trigger must be the first in line, and the PWM B VAL4 must be the last
in line. Then the cycle is repeated.
To make sure the very first trigger which arrives to the ADC is from PWM A VAL5, the PWM B VAL4 compare event will
be programmed to generate an interrupt where all the triggers will be allowed. Then this compare event interrupt will be
disabled and the PWM and ADC synchronization will remain.
In the code, the PWM B submodule 0 VAL4 compare interrupt must be enabled and the interrupt controller has to be
programmed to enable this interrupt. The code lines are the following:
/* Compare interrupt of Value 4 */
PWMB_SM0INTEN = PWMB_SM0INTEN_CMPIE_4;
/* Interrupt for the SM0 CMP Level 2 */
INTC_IPR8 |= INTC_IPR8_PWMB_CMP0;
VAL4 Compare interrupt service routine
The PWM B submodule 0 VAL4 compare interrupt has been configured. Now the interrupt service routine (ISR) must be
created to enable the triggers.
The name of the ISR will be IsrPWM. A prototype for this routine must be created in the prototype section of the code.
void IsrPWM(void);
The name of this function must be copied into the vector table; in case the default CodeWarrior 10.2 project template is used,
it is in the file MC56F847xx_vector.asm (located in Project_Settings\Startup_Code). Thus at the address 0x98, the interrupt
no. 76 for the PWM B submodule 0 will contain the following statement:
JSR
>FIsrPWM
The body of the function itself contains the following actions:
• enabling the PWM A and B submodules 0 VAL4 and VAL5 triggers
• RUN command application on the PWM B module
• disabling the PWM B submodule 0 VAL4 Compare interrupt
• disabling the PWM B submodule 0 Compare interrupt in the interrupt controller
• clearing the PWM B submodule 0 VAL4 Compare flag
So putting all this into the code will look like this:
#pragma interrupt alignsp
void IsrPWM(void)
{
Use of PWM and ADC on MC56F84789 to Drive Dual PMS Motor FOC, Rev. 0, 10/2012
Freescale Semiconductor, Inc.
15
Reading ADC samples
/* Disable PWM B SM0 CMP VAL4 interrupt */
PWMB_SM0INTEN &= ~PWMB_SM0INTEN_CMPIE_4;
/* Enable triggers on VAL4 and VAL5*/
PWMA_SM0TCTRL |= PWMA_SM0TCTRL_OUT_TRIG_EN_4 | PWMA_SM0TCTRL_OUT_TRIG_EN_5;
PWMB_SM0TCTRL |= PWMB_SM0TCTRL_OUT_TRIG_EN_4 | PWMB_SM0TCTRL_OUT_TRIG_EN_5;
/* Disables the interrupt in the INTC */
INTC_IPR8 &= ~INTC_IPR8_PWMB_CMP0;
}
/* Clears compare flag */
PWMB_SM0STS |= PWMB_SM0STS_CMPF_4;
Now all the modules have been configured, synchronized, and started to work properly.
10 Reading ADC samples
At this point, all the peripherals are operating and the ADC samples the desired feedback at the defined points. The last job
which must be done is to read the sampled feedback values and use them in the control algorithm. If one motor is controlled,
the ADC end-of-scan interrupt is used to read the values and calculate the control algorithm. In this case, there are two
motors and it’s better to spread out the algorithms calculation across the time. Moreover, the first motor calculation does not
need to wait for the second motor ADC conversion because the feedback is ready 90 degrees before the second motor's
feedback. Finally, the PWM update must be made before the reload; otherwise the system gets one cycle delay and the
stability is worse.
Therefore, the control algorithms will be calculated at three points of time (see Figure 9):
• Motor 1 fast loop control right after its current feedback is sampled
• Motor 2 fast loop at the ADC end-of-scan interrupt
• Motor 1 and Motor 2 slow loop calculation and ADC current offset update at the PWM B half cycle
Motor 1 fast loop
As can be observed from Figure 9, the Motor 1 current feedback is ready long time before the end-of-scan interrupt. Thus the
feedback can be read from ADC when it is ready. The ADC conversion time is known, so setting up an interrupt 1 µs after
the ADC trigger, confirms that the current has already been sampled. An easy way to get an interrupt at this point is to use
one of the compare interrupts from PWM A. In this case, use the submodule 2 VAL4 Compare interrupt. The VAL4 value
will be set 1 µs after the submodule 0 VAL4 trigger, that is, to the value –4575 (0xEE21). The compare interrupt must also be
enabled; it is sufficient to enable it in the IsrPWM interrupt routine along with the triggers. The interrupt controller has to be
configured too.
So the code looks like this:
/* Fast loop calculation */
PWMA_SM2VAL4 = 0xEE21;
/* Interrupt for the SM2 CMP Level 1 */
INTC_IPR9 |= INTC_IPR9_PWMA_CMP2_1;
/* M1 fast loop calculation 1us after the ADC trigger 4 on SM2 */
PWMA_SM2INTEN |= PWMA_SM2INTEN_CMPIE_4;
Use of PWM and ADC on MC56F84789 to Drive Dual PMS Motor FOC, Rev. 0, 10/2012
16
Freescale Semiconductor, Inc.
Reading ADC samples
Figure 9. Reading ADC and control algorithms calculation
Motor 2 fast loop
The last sampled quantities are the Motor 2 currents. So, the ADC end-of-scan interrupt is used to calculate the Motor 2 fast
loop algorithm and the ADC has already been configured to generate the end-of-scan interrupt. Now, it is only required to
configure the interrupt controller. The code looks like this:
/* Interrupt ADC end of scan Level 1 */
INTC_IPR2 |= INTC_IPR2_ADC_CC0_1;
Motor 1 and Motor 2 slow loop
In case of one motor, the slow loop can be calculated in the same interrupt as the fast loop algorithm. But in this case, it
would prolong the time and the fast loop calculation of the other motor would be postponed. To avoid this collision, it is
calculated in another interrupt. The speed loop control is not as long as the fast loop algorithm, so both motors can be
calculated in the same interrupt.
For this purpose, the PWM B half cycle (VAL0) time has been chosen. At this point, the Motor 1 current offsets have been
sampled, so they can be filtered and updated for the next current measurement. And the Motor 1 slow loop can be calculated.
Additional application logics like state machine, temperature check, DC bus voltage filter and so on, can be applied at this
point.
The first block including the interrupt entry is expected to last at least until the moment where the Motor 2 currents are read.
If it is shorter, then the current offsets from the previous cycle are read; so the interrupt can’t use the VAL0 Compare event
source and has to be set up for a later point.
In the second block, the Motor 2 current offsets are read, filtered, and updated for the current measurement. Then the Motor 2
slow loop is calculated. Additional logics like state machine for Motor 2 or for the entire application, can be applied at this
point.
So in the code, the compare interrupt must be enabled; it is sufficient to enable it in the IsrPWM interrupt routine along with
the triggers. The interrupt controller has to be configured too. The code looks like this:
Use of PWM and ADC on MC56F84789 to Drive Dual PMS Motor FOC, Rev. 0, 10/2012
Freescale Semiconductor, Inc.
17
Reading ADC samples
/* M1 and M2 slow loop calculation on half cycle of PWM B */
PWMB_SM2INTEN |= PWMB_SM2INTEN_CMPIE_0;
/* Interrupt for the SM2 CMP Level 1*/
INTC_IPR7 |= INTC_IPR7_PWMB_CMP2_1;
Interrupt service routines
The interrupts have been configured; now the interrupt service routines have to be made.
The name of the ISRs will be IsrPWMAFastLoopCalc, IsrADC12Result, and IsrPWMBSlowLoopCalc. Prototypes for these
routines must be created in the prototype section of the code.
void IsrPWMAFastLoopCalc(void);
void IsrADC12Result(void);
void IsrPWMBSlowLoopCalc(void);
The names of these functions must be copied into the vector table; in case the default CodeWarrior 10.2 project template is
used, it is in the file MC56F847xx_vector.asm (located in Project_Settings\Startup_Code). Thus at the address 0xA6, the
interrupt no. 83 for the PWM A submodule 2 compare; at the address 0x3C, the interrupt no. 30 for the ADC result; and at
the address 0x8C, the interrupt no. 70 for the PWM B submodule 2 compare; the code will contain the following statement:
JSR
JSR
JSR
>FIsrPWMAFastLoopCalc
>FIsrADC12Result
>FIsrPWMBSlowLoopCalc
The bodies of the functions themselves contain the user control algorithm (including ADC reading and update, PWM update)
and at the end, the particular interrupt flag must be cleared in order not to reenter the interrupt.
So the function bodies could look like this:
#pragma interrupt saveall
void IsrPWMAFastLoopCalc(void)
{
...
}
/* Clears compare flag */
PWMA_SM2STS |= PWMA_SM2STS_CMPF_4;
#pragma interrupt saveall
void IsrADC12Result(void)
{
...
}
/* Clears the interrupt flag */
ADC12_STAT |= ADC12_STAT_EOSI0 | ADC12_STAT_EOSI1;
#pragma interrupt saveall
void IsrPWMBSlowLoopCalc(void)
{
...
}
/* Clears compare flag */
PWMB_SM2STS |= PWMB_SM2STS_CMPF_0;
Now, all the necessary steps have been accomplished to synchronize the PWM and ADC for dual motor PMSM FOC.
Use of PWM and ADC on MC56F84789 to Drive Dual PMS Motor FOC, Rev. 0, 10/2012
18
Freescale Semiconductor, Inc.
Complete code
11 Complete code
The PWM modules have been configured, synchronized, the triggers and interrupts programmed. The ADC has been
configured and its interrupt configured. The modules have been interconnected by the crossbar switches. All the code lines
used into the context in this application are given below.
Interrupt vector table
File MC56F847xx_vector.asm (located in Project_Settings\Startup_Code)
JSR
JSR
JSR
JSR
JSR
>FIsrADC12Result
>FIsrPWMBSlowLoopCalc
>FIsrPWM
>FIsrPWMAFastLoopCalc
>FIsrPWMSync
;/*
;/*
;/*
;/*
;/*
0x3c
0x8c
0x98
0xa6
0xaa
Interrupt
Interrupt
Interrupt
Interrupt
Interrupt
no.
no.
no.
no.
no.
30
70
76
83
85
*/
*/
*/
*/
*/
Prototypes
static
static
static
static
static
static
static
static
static
void
void
void
void
void
void
void
void
void
void
void
void
void
void
GPIOA_Init(void);
GPIOB_Init(void);
GPIOE_Init(void);
GPIOG_Init(void);
XBAR_Init(void);
PWMA_SM012_Init(void);
PWMB_SM012_Init(void);
PWMA_SM012_Run(void);
ADC12_Init(void);
IsrPWMSync(void);
IsrPWM(void);
IsrPWMAFastLoopCalc(void);
IsrADC12Result(void);
IsrPWMBSlowLoopCalc(void);
Functions
static void GPIOA_Init(void)
{
/* Enable GPIOA clock */
SIM_PCE0 |= SIM_PCE0_GPIOA;
/* ADCA */
GPIOA_PER |= (GPIOA_PER_PE_0 | GPIOA_PER_PE_1 | GPIOA_PER_PE_2 | GPIOA_PER_PE_3 |
GPIOA_PER_PE_4 | GPIOA_PER_PE_5 | GPIOA_PER_PE_6 |
GPIOA_PER_PE_7);
}
SIM_GPSAL &= ~(SIM_GPSAL_A0);
static void GPIOB_Init(void)
{
/* Enable GPIOB clock */
SIM_PCE0 |= SIM_PCE0_GPIOB;
/* ADCB */
GPIOB_PER |= (GPIOB_PER_PE_0 | GPIOB_PER_PE_1 | GPIOB_PER_PE_2 | GPIOB_PER_PE_3 |
GPIOB_PER_PE_4 | GPIOB_PER_PE_5 | GPIOB_PER_PE_6 |
GPIOB_PER_PE_7);
}
static void GPIOE_Init(void)
{
/* Enable GPIOE clock */
Use of PWM and ADC on MC56F84789 to Drive Dual PMS Motor FOC, Rev. 0, 10/2012
Freescale Semiconductor, Inc.
19
Complete code
SIM_PCE0 |= SIM_PCE0_GPIOE;
/* PWMA PWMB */
GPIOE_PER |= (GPIOE_PER_PE_0 | GPIOE_PER_PE_1 | GPIOE_PER_PE_2 | GPIOE_PER_PE_3 |
GPIOE_PER_PE_4 | GPIOE_PER_PE_5 | GPIOE_PER_PE_8 |
GPIOE_PER_PE_9);
SIM_GPSEL &= ~(SIM_GPSEL_E4 | SIM_GPSEL_E5);
SIM_GPSEH &= ~(SIM_GPSEH_E8 | SIM_GPSEH_E9);
}
static void GPIOG_Init(void)
{
/* Enable GPIOG clock */
SIM_PCE0 |= SIM_PCE0_GPIOG;
/* PWM B */
GPIOG_PER |= (GPIOG_PER_PE_0 | GPIOG_PER_PE_1 | GPIOG_PER_PE_2 | GPIOG_PER_PE_3);
SIM_GPSGL &= ~(SIM_GPSGL_G0 | SIM_GPSGL_G1 | SIM_GPSGL_G2 |
SIM_GPSGL_G3);
}
static void XBAR_Init(void)
{
/* PWM A & B trigger to XBAR B */
XBARB_SEL0 = 8 | (22 << 8);
/* AOI out = A | B, i.e. PWM A trigger or PWM B trigger */
AOI_BFCRT010 = AOI_BFCRT010_PT0_AC_0 | AOI_BFCRT010_PT0_BC | AOI_BFCRT010_PT0_CC |
AOI_BFCRT010_PT0_DC | AOI_BFCRT010_PT1_AC | AOI_BFCRT010_PT1_BC_0 |
AOI_BFCRT010_PT1_CC | AOI_BFCRT010_PT1_DC;
AOI_BFCRT230 = 0;
/* ADC A trigger from AOI */
XBARA_SEL6 = 46;
}
static void PWMA_SM012_Init(void)
{
/* Enable clock for PWM SM 0 - 2 */
SIM_PCE3 |= (SIM_PCE3_PWMACH0 | SIM_PCE3_PWMACH1 | SIM_PCE3_PWMACH2);
/* Half cycle reload */
PWMA_SM0CTRL = PWMA_SM0CTRL_HALF;
PWMA_SM1CTRL = PWMA_SM1CTRL_HALF;
PWMA_SM2CTRL = PWMA_SM2CTRL_HALF;
/* PWM setup for 3 phases */
PWMA_SM0CTRL2 = 0xC080;
PWMA_SM1CTRL2 = 0xC20E;
PWMA_SM2CTRL2 = 0xC20E;
/* setup for
PWMA_SM0INIT
PWMA_SM1INIT
PWMA_SM2INIT
pwm frequency of 10KHz */
= 0xEC78;
= 0xEC78;
= 0xEC78;
/* setup for
PWMA_SM0VAL1
PWMA_SM1VAL1
PWMA_SM2VAL1
pwm frequency of 10KHz */
= 0x1387;
= 0x1387;
= 0x1387;
PWMA_SM0VAL0 = 0x0000;
PWMA_SM1VAL0 = 0x0000;
PWMA_SM2VAL0 = 0x0000;
PWMA_SM0VAL2 = 0xF63C;
PWMA_SM1VAL2 = 0xF63C;
Use of PWM and ADC on MC56F84789 to Drive Dual PMS Motor FOC, Rev. 0, 10/2012
20
Freescale Semiconductor, Inc.
Complete code
PWMA_SM2VAL2 = 0xF63C;
PWMA_SM0VAL3 = 0x09C3;
PWMA_SM1VAL3 = 0x09C3;
PWMA_SM2VAL3 = 0x09C3;
PWMA_SM0VAL4
PWMA_SM1VAL4
PWMA_SM2VAL4
PWMA_SM0VAL5
PWMA_SM1VAL5
PWMA_SM2VAL5
=
=
=
=
=
=
0xEDBD;
0x0000;
0xEE21;
0x0145;
0xF63C;
0x0000;
/* Current measurement value */
/* Fast loop calculation */
/* Offset measurement value */
/* Sync for the other motor's PWM */
/* deadtime count register 0 and 1 = 2.0 us */
PWMA_SM0DTCNT0 = 0x00C8;
PWMA_SM1DTCNT0 = 0x00C8;
PWMA_SM2DTCNT0 = 0x00C8;
PWMA_SM0DTCNT1 = 0x00C8;
PWMA_SM1DTCNT1 = 0x00C8;
PWMA_SM2DTCNT1 = 0x00C8;
/* Fault A 0 - 3 inactive */
PWMA_SM0DISMAP0 = 0;
PWMA_SM1DISMAP0 = 0;
PWMA_SM2DISMAP0 = 0;
/* Fault A 4 - 7 inactive */
PWMA_SM0DISMAP1 = 0;
PWMA_SM1DISMAP1 = 0;
PWMA_SM2DISMAP1 = 0;
/* Compare interrupt of Value 5, used to sync PWM A and PWM B */
PWMA_SM1INTEN = PWMA_SM1INTEN_CMPIE_5;
/* Interrupt for the SM1 CMP L2 and SM2 CMP L1 */
INTC_IPR9 |= INTC_IPR9_PWMA_CMP1 | INTC_IPR9_PWMA_CMP2_1;
/* Enables PWM output */
PWMA_OUTEN |= (PWMA_OUTEN_PWMA_EN_0 | PWMA_OUTEN_PWMB_EN_0 | PWMA_OUTEN_PWMA_EN_1 |
PWMA_OUTEN_PWMB_EN_1 | PWMA_OUTEN_PWMA_EN_2 | PWMA_OUTEN_PWMB_EN_2);
}
/* Clear LDOK bit */
PWMA_MCTRL |= PWMA_MCTRL_CLDOK_0 | PWMA_MCTRL_CLDOK_1 | PWMA_MCTRL_CLDOK_2;
/* LDOK */
PWMA_MCTRL |= PWMA_MCTRL_LDOK_0 | PWMA_MCTRL_LDOK_1 | PWMA_MCTRL_LDOK_2;
static void PWMB_SM012_Init(void)
{
/* Enable clock for PWM SM 0 - 3 */
SIM_PCE3 |= (SIM_PCE3_PWMBCH0 | SIM_PCE3_PWMBCH1 | SIM_PCE3_PWMBCH2);
/* Half cycle reload */
PWMB_SM0CTRL = PWMB_SM0CTRL_HALF;
PWMB_SM1CTRL = PWMB_SM1CTRL_HALF;
PWMB_SM2CTRL = PWMB_SM2CTRL_HALF;
/* PWM setup for 3 phases, uses only SM 1 - 2 */
PWMB_SM0CTRL2 = 0xC080;
PWMB_SM1CTRL2 = 0xC20E;
PWMB_SM2CTRL2 = 0xC20E;
/* setup for
PWMB_SM0INIT
PWMB_SM1INIT
PWMB_SM2INIT
pwm frequency of 10KHz */
= 0xEC78;
= 0xEC78;
= 0xEC78;
/* setup for pwm frequency of 10KHz */
PWMB_SM0VAL1 = 0x1387;
Use of PWM and ADC on MC56F84789 to Drive Dual PMS Motor FOC, Rev. 0, 10/2012
Freescale Semiconductor, Inc.
21
Complete code
PWMB_SM1VAL1 = 0x1387;
PWMB_SM2VAL1 = 0x1387;
PWMB_SM0VAL0 = 0x0000;
PWMB_SM1VAL0 = 0x0000;
PWMB_SM2VAL0 = 0x0000;
PWMB_SM0VAL2 = 0xF63C;
PWMB_SM1VAL2 = 0xF63C;
PWMB_SM2VAL2 = 0xF63C;
PWMB_SM0VAL3 = 0x09C3;
PWMB_SM1VAL3 = 0x09C3;
PWMB_SM2VAL3 = 0x09C3;
PWMB_SM0VAL4 = 0xEDBD;
PWMB_SM1VAL4 = 0x0000;
PWMB_SM2VAL4 = 0x0000;
/* Current measurement value */
PWMB_SM0VAL5 = 0x0145;
PWMB_SM1VAL5 = 0x0000;
PWMB_SM2VAL5 = 0x0000;
/* Offset measurement value */
/* deadtime count register 0 and 1 = 2.0 us */
PWMB_SM0DTCNT0 = 0x00C8;
PWMB_SM1DTCNT0 = 0x00C8;
PWMB_SM2DTCNT0 = 0x00C8;
PWMB_SM0DTCNT1 = 0x00C8;
PWMB_SM1DTCNT1 = 0x00C8;
PWMB_SM2DTCNT1 = 0x00C8;
/* Fault B 0 – 3 inactive */
PWMB_SM0DISMAP0 = 0;
PWMB_SM1DISMAP0 = 0;
PWMB_SM2DISMAP0 = 0;
/* Fault B 4 - 7 inactive */
PWMB_SM0DISMAP1 = 0;
PWMB_SM1DISMAP1 = 0;
PWMB_SM2DISMAP1 = 0;
/* Compare interrupt of Value 4, enable triggers from PWM A and B to ADC */
PWMB_SM0INTEN = PWMB_SM0INTEN_CMPIE_4;
/* Interrupt for the SM0 CMP L2 */
INTC_IPR8 |= INTC_IPR8_PWMB_CMP0;
/* Interrupt for the SM2 CMP L1*/
INTC_IPR7 |= INTC_IPR7_PWMB_CMP2_1;
/* Clear LDOK bit */
PWMB_MCTRL |= PWMB_MCTRL_CLDOK_0 | PWMB_MCTRL_CLDOK_1 | PWMB_MCTRL_CLDOK_2;
/* LDOK */
PWMB_MCTRL |= PWMB_MCTRL_LDOK_0 | PWMB_MCTRL_LDOK_1 | PWMB_MCTRL_LDOK_2;
/* Enables PWM output */
PWMB_OUTEN |= (PWMB_OUTEN_PWMA_EN_3 | PWMB_OUTEN_PWMB_EN_3 | PWMB_OUTEN_PWMA_EN_1 |
PWMB_OUTEN_PWMB_EN_1 | PWMB_OUTEN_PWMA_EN_2 | PWMB_OUTEN_PWMB_EN_2);
}
static void PWMA_SM012_Run(void)
{
/* Enable clock */
PWMA_MCTRL |= PWMA_MCTRL_RUN_0 | PWMA_MCTRL_RUN_1 | PWMA_MCTRL_RUN_2;
}
static void ADC12_Init(void)
{
Use of PWM and ADC on MC56F84789 to Drive Dual PMS Motor FOC, Rev. 0, 10/2012
22
Freescale Semiconductor, Inc.
Complete code
/* enable clock to ADC modules */
SIM_PCE2 |= SIM_PCE2_CYCADC;
/* SMODE - triggered parallel, SYNC0 - enabled, End of scan interrupt */
ADC12_CTRL1 = 0x1805;
/* Simultaneous parallel mode; DIV0 = 5, 20MHz */
ADC12_CTRL2 = ADC12_CTRL2_DIV0_2 | ADC12_CTRL2_SIMULT;
/* Channel assignment */
/* S0 S1 S2 S3
S4 S5
/* A0 A0 A2 A0
A2 A0
ADC12_CLIST1 = 0x0200;
ADC12_CLIST2 = 0x0002;
/* S8 S9 S10
/* B0 B4 B2
ADC12_CLIST3 =
ADC12_CLIST4 =
S6
A0
S7 */
A0 */
S11 S12 S13 S14 S15 */
B0
B2 B0 B0 B0 */
0x8AC8;
0x888A;
/* Sample count 10 channels */
ADC12_SDIS = 0xE0E0;
/* Sync at */
/* S0 S1 S2 S3
S4
/* x
x
x
x
ADC12_SCTRL = 0x010D;
S5
S6
S7 */
*/
/* power-up delay set to 26 clocks */
ADC12_PWR = 0x01A0;
/* ADCA Speed <=20MHz; ADCB Speed<=20MHz; DIV1 = 5, 20 MHz */
ADC12_PWR2= ADC12_PWR2_SPEEDA | ADC12_PWR2_SPEEDB | ADC12_PWR2_DIV1_2;
}
/* Interrupt end of scan L1 */
INTC_IPR2 |= INTC_IPR2_ADC_CC0_1;
#pragma interrupt alignsp
void IsrPWMSync(void)
{
if ((PWMA_SM1STS & PWMA_SM1STS_CMPF_5) > 0 )
{
/* Starts PWM B */
PWMB_MCTRL |= PWMB_MCTRL_RUN_0 | PWMB_MCTRL_RUN_1 | PWMB_MCTRL_RUN_2 |
PWMB_MCTRL_RUN_3; /* Enable clock */
/* Disable PWM SM1 CMP interrupt from 5 */
PWMA_SM1INTEN &= ~PWMA_SM1INTEN_CMPIE_5;
/* Enables the PWM SM1 CMP interrupt from 4 */
PWMA_SM1INTEN |= PWMA_SM1INTEN_CMPIE_4;
}
/* Clears compare flag */
PWMA_SM1STS |= PWMA_SM1STS_CMPF_5;
}
#pragma interrupt alignsp
void IsrPWM(void)
{
/* Disable PWM SM0 CMP interrupt */
PWMA_SM0INTEN &= ~PWMA_SM0INTEN_CMPIE_4;
PWMB_SM0INTEN &= ~PWMB_SM0INTEN_CMPIE_4;
/* Enable triggers on VAL4 and VAL5 */
PWMA_SM0TCTRL |= PWMA_SM0TCTRL_OUT_TRIG_EN_4 | PWMA_SM0TCTRL_OUT_TRIG_EN_5;
PWMB_SM0TCTRL |= PWMB_SM0TCTRL_OUT_TRIG_EN_4 | PWMB_SM0TCTRL_OUT_TRIG_EN_5;
Use of PWM and ADC on MC56F84789 to Drive Dual PMS Motor FOC, Rev. 0, 10/2012
Freescale Semiconductor, Inc.
23
Definitions and acronyms
/* M1 fast loop calculation 1us after the ADC trigger 4 on SM2 */
PWMA_SM2INTEN |= PWMA_SM2INTEN_CMPIE_4;
/* M1 and M2 slow loop calculation on half cycle of PWM B */
PWMB_SM2INTEN |= PWMB_SM2INTEN_CMPIE_0;
/* Disables the interrupt in the INTC */
INTC_IPR8 &= ~INTC_IPR8_PWMB_CMP0;
}
/* Clears compare flag */
PWMB_SM0STS |= PWMB_SM0STS_CMPF_4;
#pragma interrupt saveall
void IsrPWMAFastLoopCalc(void)
{
...
}
/* Clears compare flag */
PWMA_SM2STS |= PWMA_SM2STS_CMPF_4;
#pragma interrupt saveall
void IsrADC12Result(void)
{
...
}
/* Clears the interrupt flag */
ADC12_STAT |= ADC12_STAT_EOSI0 | ADC12_STAT_EOSI1;
#pragma interrupt saveall
void IsrPWMBSlowLoopCalc(void)
{
...
}
/* Clears compare flag */
PWMB_SM2STS |= PWMB_SM2STS_CMPF_0;
Functions Call Order
The initialization of the application requires the functions to be called in the following order:
GPIOA_Init();
GPIOB_Init();
GPIOE_Init();
GPIOG_Init();
XBAR_Init();
PWMA_SM012_Init();
PWMB_SM012_Init();
PWMA_SM012_Run();
12 Definitions and acronyms
GPIO
General Port Input Output
ADC
Analog-to-Digital Converter
XBAR
Crossbar Switch
PWM
Pulse Width Modulation
ISR
Interrupt Service Routine
Table continues on the next page...
Use of PWM and ADC on MC56F84789 to Drive Dual PMS Motor FOC, Rev. 0, 10/2012
24
Freescale Semiconductor, Inc.
Definitions and acronyms
AOI
And/Or/Invert Module
SIM
System Integration Module
CW
CodeWarrior
FSLESL
Freescale Embedded Software Libraries, the software tool
which can be downloaded from freescale.com
GFLIB
General Functions Library
MCLIB
Motor Control Library
GDFLIB
General Digital Filters Library
ACLIB
Advanced Control Library
DSC
Digital Signal Controller
FOC
Field-Oriented Control
PMSM
Permanent Magnet Synchronous Motor
Motor control
In this application note, motor control means a process which
controls an electrical motor such as BLDC PMSM, ACinduction or other.
Use of PWM and ADC on MC56F84789 to Drive Dual PMS Motor FOC, Rev. 0, 10/2012
Freescale Semiconductor, Inc.
25
How to Reach Us:
Home Page:
www.freescale.com
Web Support:
http://www.freescale.com/support
USA/Europe or Locations Not Listed:
Freescale Semiconductor
Technical Information Center, EL516
2100 East Elliot Road
Tempe, Arizona 85284
+1-800-521-6274 or +1-480-768-2130
www.freescale.com/support
Europe, Middle East, and Africa:
Freescale Halbleiter Deutschland GmbH
Technical Information Center
Schatzbogen 7
81829 Muenchen, Germany
+44 1296 380 456 (English)
+46 8 52200080 (English)
+49 89 92103 559 (German)
+33 1 69 35 48 48 (French)
www.freescale.com/support
Japan:
Freescale Semiconductor Japan Ltd.
Headquarters
ARCO Tower 15F
1-8-1, Shimo-Meguro, Meguro-ku,
Tokyo 153-0064
Japan
0120 191014 or +81 3 5437 9125
[email protected]
Asia/Pacific:
Freescale Semiconductor China Ltd.
Exchange Building 23F
No. 118 Jianguo Road
Chaoyang District
Beijing 100022
China
+86 10 5879 8000
[email protected]
Document Number: AN4608
Rev. 0, 10/2012
Information in this document is provided solely to enable system and software
implementers to use Freescale Semiconductors products. There are no express or implied
copyright licenses granted hereunder to design or fabricate any integrated circuits or
integrated circuits based on the information in this document.
Freescale Semiconductor reserves the right to make changes without further notice to any
products herein. Freescale Semiconductor makes no warranty, representation, or
guarantee regarding the suitability of its products for any particular purpose, nor does
Freescale Semiconductor assume any liability arising out of the application or use of any
product or circuit, and specifically disclaims any liability, including without limitation
consequential or incidental damages. "Typical" parameters that may be provided in
Freescale Semiconductor data sheets and/or specifications can and do vary in different
applications and actual performance may vary over time. All operating parameters,
including "Typicals", must be validated for each customer application by customer's
technical experts. Freescale Semiconductor does not convey any license under its patent
rights nor the rights of others. Freescale Semiconductor products are not designed,
intended, or authorized for use as components in systems intended for surgical implant
into the body, or other applications intended to support or sustain life, or for any other
application in which failure of the Freescale Semiconductor product could create a
situation where personal injury or death may occur. Should Buyer purchase or use
Freescale Semiconductor products for any such unintended or unauthorized application,
Buyer shall indemnify Freescale Semiconductor and its officers, employees, subsidiaries,
affiliates, and distributors harmless against all claims, costs, damages, and expenses, and
reasonable attorney fees arising out of, directly or indirectly, any claim of personal injury
or death associated with such unintended or unauthorized use, even if such claims alleges
that Freescale Semiconductor was negligent regarding the design or manufacture of
the part.
RoHS-compliant and/or Pb-free versions of Freescale products have the functionality and
electrical characteristics as their non-RoHS-complaint and/or non-Pb-free counterparts.
For further information, see http://www.freescale.com or contact your Freescale
sales representative.
For information on Freescale's Environmental Products program, go to
http://www.freescale.com/epp.
Freescale™ and the Freescale logo are trademarks of Freescale Semiconductor, Inc.
All other product or service names are the property of their respective owners.
© 2012 Freescale Semiconductor, Inc.