Using the HC12 Pulse Width Modulation Subsystem

1.
Determine the PWM period in P-clock cycles:
NC = Period/(0.125 $\mu$s) = 8 $\times 10^6$ cycles/second / Frequency

For example, to get a 500 Hz PWM signal:

NC = $8 \times 10^6 / 500 = 16000$

2.
Try to find N and PWPER such that


\begin{displaymath}2^N \times {{\rm {PWPER}} + 1} = NC\end{displaymath}

where $0 \le N \le 7$ and $199 \le $ PWPER $\le 255$

For 500 Hz PWM,


\begin{displaymath}2^N = \frac{16000}{{\rm PWPER} + 1}\end{displaymath}

For PWPER = 249, you get 2N = 64, N = 6.

3.
If no value of N works in the above, try to find N and M such that


\begin{displaymath}2^(N+1) \times (M+1) \times {{\rm {PWPER}} + 1} = NC\end{displaymath}

where $0 \le N \le 7$, $0 \le M \le 255$ and $199 \le $ PWPER $\le 255$

For 500 Hz PWM,


\begin{displaymath}2^N = \frac{16000}{(M+1)({\rm PWPER} + 1)}\end{displaymath}

For PWPER = 199,


\begin{displaymath}2^N = \frac{80}{(M+1)}\end{displaymath}

There are several values which will work: N = 1, M = 39; N = 2, M = 19 and N = 3, M = 9

4.
Once you find N and M, program the following registers (assuming 8-bit mode, left-aligned, high polarity). Note that if you are using both channel 0 and 1, they both must have the same N. If you use M for both channel 0 and 1, they both must have the same M.

If using N only:

Action Register Channel 0 Channel 1 Channel 2 Channel 3
8-bit mode PWCLK Bit 6 = 0 Bit 6 = 0 Bit 7 = 0 Bit 7 = 0
High Polarity PWPOL Bit 0 = 1 Bit 1 = 1 Bit 2 = 1 Bit 3 = 1
Left Aligned PWCTL Bit 3 = 0 Bit 3 = 0 Bit 3 = 0 Bit 3 = 0
Clock Select PWPOL Bit 4 = 0 Bit 5 = 0 Bit 6 = 0 Bit 7 = 0
N PWCLK Bits 5:3 = N Bits 5:3 = N Bits 2:0 = N Bits 2:0 = N
Enable PWM PWEN Bit 0 = 1 Bit 1 = 1 Bit 2 = 1 Bit 3 = 1

If using N and M:

Action Register Channel 0 Channel 1 Channel 2 Channel 3
8-bit mode PWCLK Bit 6 = 0 Bit 6 = 0 Bit 7 = 0 Bit 7 = 0
High Polarity PWPOL Bit 0 = 1 Bit 1 = 1 Bit 2 = 1 Bit 3 = 1
Left Aligned PWCTL Bit 3 = 0 Bit 3 = 0 Bit 3 = 0 Bit 3 = 0
Clock Select PWPOL Bit 4 = 1 Bit 5 = 1 Bit 6 = 1 Bit 7 = 1
N PWCLK Bits 5:3 = N Bits 5:3 = N Bits 2:0 = N Bits 2:0 = N
M PWSCALx PWSCAL0 = M PWSCAL0 = M PWSCAL1 = M PWSCAL1 = M
Enable PWM PWEN Bit 0 = 1 Bit 1 = 1 Bit 2 = 1 Bit 3 = 1

5.
Now program the PWPERx register for the used channel(s) with the value calculated in Part 2 or 3.

6.
Set the duty cycle by programming the PWPDTYx for the used channel(s) using the formula:

PWDTYx = (duty cycle $\times$ (PWPERx + 1)) - 1

For example, with PWPERx = 199, and a duty cycle of 25%,

PWDTYx = (0.25 $\times$ (199 + 1)) - 1 = 49

To progam Channel 0 for 500 Hz PWM with a 25% duty cycle (using N = 3, M = 9, and PWPER = 199 from Part 3):

 
    /* Choose 8-bit mode */
    PWCLK = PWCLK & ~0x40;
    /* Choose high polarity */
    PWPOL = PWPOL | 0x01;
    /* Choose left-aligned */
    PWCTL = PWCTL & ~0x08;
    /* Select clock mode 1 (use N and M) for Channel 0 */
    PWPOL = PWPOL | 0x10;
    /* Select N = 2 and M = 2 for Channels 1 and 0 */
    PWCLK = (PWCLK | 0x18) & ~0x20;   /* PWCLK = X X 0 1 1 X X X */
    /* Select and M = 9 for Channels 1 and 0 */
    PWSCAL0 = 9; 
    /* Select period of 199 for Channels 1 and 0 */
    PWPER0 = 199;
    /* Enable PWM on Channels 1 and 0 */
    PWEN = PWEN | 0x03;
    /* 25 % duty cycle on Channel 0 */
    PWDTY0 = 49;



Bill Rison
2000-03-08