I'm planning an exp-ramp generator with the following characteristics:
- Implemented on the PIC16F1773, an 8-bit device with somewhat complex capture/compare/PWM hardware.
- PWM module clock of 500 kHz * 32 = 16 MHz
- System clock (Fosc) of 16 MHz / 2 * 4 = 32 MHz
- Fixed PWM frequency of 233 Hz
- Duty cycle starting at 0%, ending at 100% after 4.82 s
- Approximating the exponential curve \$ y = 1 - 0.1^{t/2} \$, which has an equivalent time constant of \$ \tau \approx 0.8686 \$.
The strategy to modify the duty cycle is:
- always increment the high byte of the duty cycle register
PWMxDCH
by 1, ignoring the low byte for simplicity - only perform a DC increment after a post-scaled counter rolls over whose input clock is the period match event of the PWM
- the post-scale factor starts at 1, ends at 128, and is multiplied by 2 every ~140 PWM cycles
In a basic numerical simulation of this strategy, the approximation is quite good:
The bumps are where the post-scale factor is changed.
I have a little bit of decision paralysis around how best to implement the post-scaler. I could use a 16-bit PWM module:
interrupt on PRIF
, maintain a software post-scale count variable, and on overflow of this count, increment the duty cycle. Or I could use the simpler 10-bit PWM module:
which does not support period interrupt; short the PWM output pin to the clock input pin TMRx_clk
of a timer like this:
Where PRx
is the post-scale value, the actual timer pre- and post-scale are not needed, and on TMR2IF
, increment PWMxDCH
.
I kind of prefer the secondary-timer approach because it means (1) easier external scope debugging, and (2) fewer runtime instructions required. Is there a way to make better use of the 1773's hardware to accomplish this thing?