# [volt-nuts] PWM voltage divider

John Devereux john at devereux.me.uk
Wed Jan 8 08:53:02 EST 2014

```Jan Fredriksson <jan at 41hz.com> writes:

> I'm thinking of using a PWM divider for voltage generation of adjustable DC
> voltages from a voltage reference.
>
> Does anyone have any pointers to circuits, solutions, topologies, error
> analysis etc. for such solutions?

Hi Jan,

There were interesting ideas in there if you browse through the thread.

Some highlights quoted below, all due to James Arthur I think:

======================================================================

Here's the basic PWM:

.........................
:
Vref >----/\/\/-----O    :
R1        \   :     R3
\  :     1M
O-----/\/\/---+-----> Vout
:           |
R2            :          --- Cf
0 >----/\/\/-----O    :          ---
:           |
........................:           |
===
Fig. 1

To me, 16 bits on the cheap is plenty cool.  But if the bar is doing
something extraordinary, like 1ppm, then it seems fair to use fancier
parts.

So, let's assume an FPGA and 100MHz clock rate, driving the switch.
The switch can either be the FPGA output, or an extra gate (or
paralleled gates).

We can get 1ppm modulating 100Hz in 10nS chunks.  Or 40Hz in 25nS
chunks, etc.  Whatever works out with our switch-speed.

Switch mis-match (R1-R2) produces a code-related error, maximized at
mid-scale.  With R3=1M, my algebra says <0.5ppm non-linearity from
switch mis-match requires |R1-R2| <= 1 ohm.  Y(A)MV.

Paralled gates, analog switches, or a BSS138 buffer stage could do
that.  I measured (characterized) some 74ACxx parts a ways back for
this.

Another, liberating possibility is to bootstrap the switches,
canceling most of their effective resistance:

Vcomp >-------------.
|
|
......................... .-.
: | | R4
Vref >----/\/\/-----O    : | |
R1        \   : '-'
\  :  |    R3
O----+--/\/\/---+-----> Vout
:             |
R2            :            --- Cf
0 >----/\/\/-----O    :            ---
:             |
........................:             |
===
Fig. 2

If Vcomp is such that i(R4) = i(R3), the voltage drops (errors) across
R1 and R2 disappear.  This next version does that.

C1
Vpwm >-----+----||----.
.-.  .-.           |          |
_| |__| |_ =2Vrefp-p|          |
|         .-.
.....................V...      | |  R4
:   .  :      | | 100K, 1%
Vref >----/\/\/-----O .  :      '-'
R1     :  \   :       |     R3
:   \  :       |    100K, 1%
:    O---------+---/\/\/---+-----> Vout
:      :                   |
R2     :      :                  --- Cf
0V >----/\/\/-----O    :   R4=R3          ---
:      :                   |
.................:......:                   |
===
Fig. 3

C1-R4 re-create the same currents as flow in R3.  Effective switch
resistance (R1, R2) is lowered by about two orders of magnitude,
allowing us to reduce R3 and lower the output impedance.

Filtering the 100Hz PWM to 1ppm takes 14 time-constants = 140mS.

So, Fig. 3 is a working solution.  It's linear and accurate, but needs
a hi-z buffer amp and it's slow. A 16-bit version could be faster,
with lower-z output.  Or, splitting the DAC up into two sections
improves both those properties too.

C1
Vpwm(hi) >------------+---||---.
.-.  .-.           |        |
_| |__| |_ =2Vrefp-p|        |
|        |
.....................V...    .-.
:   .  :    | | R4
Vref >----/\/\/-----O .  :    | |
R1     :  \   :    '-'
:   \  :     |    R3, 0.05%
:    O-------+--/\/\/---+---/\/\/--+-----> Vout
:      :                |    Rf    |
R2     :      :                |         --- Cf
0V >----/\/\/-----O    :   R4=R3        |         ---
:      :                |          |
.................:......:                |          |
|         ===
|
|
Vpwm(lo) >------------.                   |
|                   |
|                   |
.....................V...               .-.
:   .  :               | | R7
Vref >----/\/\/-----O .  :               | | = 1000 x R3, 0.05%
R5     :  \   :               '-'
:   \  :                |
:    O------------------'
:      :
R6     :      :
0V >----/\/\/-----O    :
:      :
.................:......:

Fig. 4

If the upper and lower DACS cover 1,000:1 each, we could lower the
clock frequency to, say, 10MHz, pump it with a uC, and still have a
10kHz composite waveform that one-pole-filters to 1ppm in 14 * 100uS =
1.4mS.

The R7-R3 ratio is critical to absolute accuracy and monotonicity.
The top DAC divides Vref accurately into 1,000 parts, so a 1% error in
the R7-R3 divider ratio represents an error of 1 part in 100 of
1/1,000th, or 1 part in 100,000 overall.  0.05% ensures 0.5ppm.

Likewise, to ensure monotonicity to 1ppm, the lower DAC's contribution
of 1,000 lsb's cannot be off by >1 part (lsb) in those 1,000 lsb's, or
0.1%

The low DAC represents a small, code-related d.c. load on R1, R2 via
R7.  That needs to be either kept small, or compensated.

Back to the topic of this thread, the effect of T/C errors in the
divider resistors is reduced by the divider ratio, a factor of 1,000.

So, there's a stable, accurate, 1ppm PWM DAC made with non-critical
parts.

(more...)

>
>     |<--- t(code) ---->|
>
>       tr         h        tf
>     |<--->|____________|<--->|           _ Vh
>     |    /|            |\    |          /
>     |   / |            | \   |         /
>     |  /  |            |  \  |        /
>     | /   |            |   \ |  l    /
> ....|/                      \|______/ ____ Vl
>
>     |<-----------t(pwm)------------>|
>
>
> Where
>   t(code) is the commanded high time
>   t(pwm) is the pwm period
>
>
>              Vh * (t(code) + (tf-tr)/2)
>   V(code) =  --------------------------
>                        t(pwm)
>
> A difference in propagation delay tpd(H->L) - tpd(L->H) has the same
> effect.

>
> Bootstrapping the output almost eliminates the load on Vref, which
> effectively kills the Vref ripple current error too.  The high DAC
> timing error effect is still annoying.
>

--

John Devereux
```