SPRUIZ1B July 2023 – August 2024 TMS320F28P650DH , TMS320F28P650DK , TMS320F28P650SH , TMS320F28P650SK , TMS320F28P659DH-Q1 , TMS320F28P659DK-Q1 , TMS320F28P659SH-Q1
The mechanics of how to position an edge precisely in time has been demonstrated using the resources of the standard CMPA and MEP (CMPAHR) registers. In a practical application, however, it is necessary to seamlessly provide the CPU a mapping function from a per-unit (fractional) duty cycle to a final integer (non-fractional) representation that is written to the [CMPA:CMPAHR] register combination.
To do this, first examine the scaling or mapping steps involved. It is common in control software to express duty cycle in a per-unit or percentage basis. This has the advantage of performing all needed math calculations without concern for the final absolute duty cycle, expressed in clock counts or high time in nanoseconds (ns). Furthermore, it makes the code more transportable across multiple converter types running different PWM frequencies.
To implement the mapping scheme, a two-step scaling procedure is required.
Assumptions for this example:
TBCLK | = | 10ns (100MHz) |
PWM frequency | = | 1.25MHz (1/800ns) |
Required PWM duty cycle, PWMDuty | = | 0.405 (40.5%) |
PWM period in terms of coarse steps, PWMPeriod (800ns/10ns) |
= | 80 |
Number of MEP steps per coarse step at 180ps (10ns/180ps), MEP_ScaleFactor |
= | 55 |
Value to keep CMPAHR within the range of 1-255 and fractional rounding constant (default value) | = | 0.5 (0080h in Q8 format) |
Step 1: Percentage Integer Duty value conversion for CMPA register
CMPA register value | = | int(PWMDuty*PWMPeriod); int means integer part |
= | int(0.405 * 80) | |
= | int(32.4) | |
CMPA register value | = | 32 (20h) |
Step 2: Fractional value conversion for CMPAHR register
CMPAHR | = | (frac(PWMDuty*PWMPeriod)*MEP_ScaleFactor + 0.5) <<8); frac means fractional part |
= | (frac(32.4) * 55 + 0.5) <<8; Shifting is to move the value to the high byte of CMPAHR. | |
= | (0.4 * 55 + 0.5) <<8 | |
= | (22 + 0.5) <<8 | |
= | 22.5 * 256; Shifting left by 8 is the same as multiplying by 256. | |
= | 5760 (1680h) | |
CMPAHR | = | 1680h CMPAHR value = 1600h (lower 8 bits are ignored by hardware). |
If the AUTOCONV bit (HRCNFG.6) is set and the MEP_ScaleFactor is in the HRMSTEP register, then CMPAHR / CMPBHR register value = frac (PWMDuty*PWMperiod<<8). The rest of the conversion calculations are performed automatically in hardware, and the correct MEP-scaled signal edge appears on the ePWM channel output. If AUTOCONV is not set, the above calculations must be performed by software.
The MEP scale factor (MEP_ScaleFactor) varies with the system clock and DSP operating conditions. TI provides an MEP scale factor optimizing (SFO) software C function, which uses the built in diagnostics in each HRPWM and returns the best scale factor for a given operating point.
The scale factor varies slowly over a limited range so the optimizing C function can be run very slowly in a background loop.
The CMPA, CMPB, CMPAHR and CMPBHR registers are configured in memory so that the 32-bit data capability of the CPU can write this as a single concatenated value, that is, [CMPA:CMPAHR], [CMPB:CMPBHR], and so on.
The mapping scheme has been implemented in both C and assembly, as shown in Section 22.18.1.8. The actual implementation takes advantage of the 32-bit CPU architecture and is somewhat different from the steps shown in Section 22.18.1.5.2.
For time-critical control loops where every cycle counts, the assembly version is recommended. This is a cycle optimized function (11 EPWMCLK cycles) that takes a Q15 duty value as input and writes a single [CMPA:CMPAHR] value.