Step 23 of 56
MCPWM: PWM that can shut itself down
Complementary outputs with dead-time so a half-bridge is never shorted, a chopper carrier, and a fault input that forces the pins safe in hardware — without waiting for your code.
What makes it different from LEDC
Two units, each with three independent generator channels and three capture channels. A generator channel is one timer plus one operator producing an edge-aligned PWM on output A: high at the start of each period, low when the up-counting timer reaches the duty comparator.
type MCPWM_Unit is (MCPWM0, MCPWM1);
type Channel_Index is (Ch0, Ch1, Ch2);
procedure Claim (C : in out Channel; Unit : MCPWM_Unit; Index : Channel_Index);
procedure Configure_Channel (...; Freq : ...; Complement_Pin : ... ); -- ~10 Hz .. 10 MHz
procedure Start (C : Channel);
procedure Stop (C : Channel);
procedure Set_Duty (C : Channel; Percent : Duty_Percent);
Set_Duty is a single atomic register write. Stop
halts the timer and the output stays in its current state — which
is not necessarily the safe state, so think about which level your hardware wants
before stopping a running bridge.
Complementary output and dead-time
Pass Complement_Pin and the channel drives a half-bridge or
H-bridge pair: the A output plus an inverted B output from the same PWM, with
programmable dead-time inserted between their edges so the two
are never high together.
That dead-time is the whole reason this peripheral exists. In a half-bridge, both transistors conducting at once is a direct short across the supply — "shoot-through" — which destroys the bridge in microseconds. Software cannot be trusted to sequence the edges; the hardware inserts the gap.
Carrier modulation
subtype Carrier_Prescale is Natural range 0 .. 15;
subtype Carrier_Duty is Natural range 1 .. 7;
subtype Carrier_Pulse is Natural range 0 .. 15;
procedure Set_Carrier (...);
Chops the PWM output with a high-frequency carrier. This is what drives a gate-drive transformer (which cannot pass DC) or an IR emitter that expects a modulated burst.
Fault inputs: the safety feature
type Fault_Input is (Fault0, Fault1, Fault2);
type Fault_Mode is (One_Shot, Cycle_By_Cycle);
type Trip_Action is (No_Change, Force_Low, Force_High);
procedure Configure_Fault (Input : ...; Pin : ...; Active_High : ...);
procedure Protect_Channel (C : ...; Input : Fault_Input; Action : Trip_Action);
A fault pin — an over-current comparator, a driver's fault flag — forces the channel's A and B outputs to a chosen state in hardware. No interrupt latency, no scheduler, no chance that your task was busy elsewhere.
| Mode | Behaviour |
|---|---|
Cycle_By_Cycle |
The output is forced while the fault is asserted and resumes on its own once it clears. For recoverable conditions such as a current limit. |
One_Shot |
The trip latches. The outputs stay forced until you explicitly clear it, and clearing only re-enables them if the fault has actually gone. For conditions that should require a deliberate decision to restart. |
Set Trip_Action to the level that is safe for your
hardware — Force_Low is right for a low-side switch, but not
universally.