The MCHP_OC_HW block provides hardware-based output generation using the Output Compare (OC) peripheral. It generates PWM signals, toggles outputs, or creates precise timing events based on timer comparisons with no CPU overhead during normal operation.
| Device Family | OC Channels | PPS Support | Notes |
|---|---|---|---|
| dsPIC30F | 1-2 | Fixed pins | Basic OC functionality |
| dsPIC33F, PIC24H | 1-8 | Fixed pins | Standard OC peripheral |
| dsPIC33E, PIC24E | 1-9 | PPS remappable | Enhanced features, flexible routing |
| dsPIC33C/CH/CK | 1-9 | PPS remappable | High-speed timers available |
| dsPIC33A | 1-9 | PPS remappable | Use PWM_HS_FEP for advanced PWM |
| PIC32MX/MZ/MK | 1-9 | PPS (32MK/MZ) | 32-bit timer support |
| Parameter | Description | Values |
|---|---|---|
| Channel | OC channel numbers to use | 1-9 (device dependent) |
| Mode | Operating mode per channel | See OC Modes table below |
| Timer Assignment | Which timer drives each OC channel | Timer 2, 3, 4, 5 (device dependent) |
| PIN_OCx | Output pin mapping (PPS devices) | Remappable pin selection |
| Mode | OCM Bits | Description | Compare Registers Used |
|---|---|---|---|
| 0 | 000 | OC disabled | - |
| 3 | 011 | Toggle output on compare match | OCxR |
| 5 | 101 | Set output high on compare, PR clears | OCxR |
| 6 | 110 | Set output low on compare, PR clears | OCxR |
| 7 | 111 | Dual compare (PWM mode) | OCxR (rising), OCxRS (falling) |
The block supports 1 input datatype representation:
| Input Type | Range | Description |
|---|---|---|
| uint16 | 0 to Timer PR | Raw timer counts for compare registers |
Integer values transfer directly to OCxR/OCxRS registers—no runtime computation. Users handle scaling from physical units to timer counts.
Scaling formula: Compare_counts = Time_seconds × (FCY / Prescaler)
Hardware Considerations: dsPIC30F/33F/33E/33C lack hardware FPU—use fixed-point arithmetic in time-critical loops. dsPIC33A has hardware FPU. PIC32 devices have hardware FPU.
// OCxCON1 register - Control register 1
OCxCON1bits.OCM = mode; // 0-7 (operating mode)
OCxCON1bits.OCTSEL = timer_sel; // Timer source selection (0-3)
OCxCON1bits.OCSIDL = 0; // Continue in idle mode
// Compare registers
OCxR = rising_edge_count; // Primary compare (rising edge in PWM)
OCxRS = falling_edge_count; // Secondary compare (duty cycle in PWM)
// Timer selection encoding
// 0: Timer2, 1: Timer3, 2: Timer4, 3: Timer5
In PWM mode (Mode 7), the OC peripheral operates as follows:
// PWM Mode 7 timing diagram
Timer Count: 0 -----> OCxR -----> OCxRS -----> PR -----> 0
Output: | ↑ ↓ |
LOW HIGH LOW LOW
Duty Cycle = (OCxRS - OCxR) / PR
Frequency = FCY / (Prescaler × PR)
For remappable (PPS) devices:
// Example PPS configuration for OC1 on RP6 (dsPIC33E)
_RP6R = 0b010010; // Route OC1 to RP6
// Block handles PPS automatically based on PIN_OCx parameter
For fixed-pin devices:
Application: Generate 20 kHz PWM with 50% duty cycle
% Block parameters
Channel: 1
Mode: 7 % PWM mode
Timer: Timer2 configured for 20 kHz period
% Timer configuration (assuming 60 MHz FCY)
% PR2 = 60,000,000 / (1 × 20,000) - 1 = 2999
% OCxR = 0 (PWM starts at timer reset)
% OCxRS = 1500 (50% duty cycle)
% Simulink model
[20kHz Clock] → [MCHP_TIMER_Config: Timer2, PR=2999]
[Duty Cycle Input: 1500] → [MCHP_OC_HW: Channel 1, Mode 7]
Application: Three-phase inverter control with 120° phase shifts
% Block parameters
Channel: [1 2 3]
Mode: [3 3 3] % Toggle mode for all channels
Timer: [2 2 2] % All use Timer2 for synchronization
% Timer configuration for 60 Hz output
% PR2 configured for 60 Hz base frequency
% OCxR values set for 120° phase offsets:
OC1R = 0 % Phase A at 0°
OC2R = PR2/3 % Phase B at 120°
OC3R = 2*PR2/3 % Phase C at 240°
% This creates 3 square waves with 120° spacing
Application: Generate a 10 µs pulse for trigger signal
% Block parameters
Channel: 1
Mode: 5 % Set high on compare, PR clears
Timer: Timer3 with 1:1 prescaler (16.67 ns resolution @ 60 MHz)
% For 10 µs pulse:
% OCxR = 600 (10 µs / 16.67 ns)
% PR3 = 1200 (20 µs period, allowing for 10 µs high + 10 µs low)
% Connect enable signal to start/stop pulse generation
Application: Motor speed control with duty cycle input
% Block setup
Channel: 1
Mode: 7 % Dual compare PWM
Timer: Timer2 @ 20 kHz
% Simulink model structure
[Speed Command 0-100%] → [Gain: PR2/100] → [Data Type: uint16]
→ [MCHP_OC_HW Channel 1 RS input]
% OCxR = 0 (fixed rising edge)
% OCxRS = dynamic (0 to PR2 based on speed command)
% This creates 0-100% duty cycle PWM
| Timer Prescaler | Resolution @ 60 MHz | Max Frequency | Typical Use Case |
|---|---|---|---|
| 1:1 | 16.67 ns | 30 MHz | High-speed PWM, precise timing |
| 1:8 | 133.3 ns | 3.75 MHz | Standard PWM (10-100 kHz) |
| 1:64 | 1.067 µs | 468 kHz | Low-frequency PWM, servo control |
| 1:256 | 4.267 µs | 117 kHz | Very low frequency applications |
Phase-shifted waveforms use same timer with different OCxR values
Complementary outputs for bridge drivers
Coordinated multi-axis motion control