Digitally Controlled Potentiometers

Including exercises in using shift registers and counters


A digitally controlled potentiometer (DCP) is a resistance chain realized in CMOS with a number of equally-spaced taps where the tap connected to the "wiper" terminal is selected digitally. It may be used just like a potentiometer with a physical wiper, so long as the potential of any terminal is between ground and the power supply voltage, usually +5 V, and the currents are limited, usually to 1 mA.

The digital control is by means of a serial data interface or by up/down incrementation. Up/down incrementation, the simplest control, uses an U/D direction control and an increment input, generally for 64 or fewer taps. The serial data interface may be the 3-wire SPI (Serial Peripheral Interface) or the 2-wire I2C (Inter-Integrated Circuit) interface. A parallel interface does not seem to be used with DCP's, though it would be convenient and easy to use.

A DCP is clearly most conveniently controlled by a microprocessor, using 3 output bits in most cases. It can also be controlled without a processor, though with some inconvenience. Using a manual control, as we shall do here, is an excellent way to gain the familiarity necessary for writing programs to control a DCP.

DCP's are manufactured by Microchip, Maxim Semiconductor and Intersil Corporation, and perhaps by others.

The Microchip MCP41010 DCP

The MCP14010 is a 10K DCP with 256 taps. It comes in an 8-pin PDIP package. Pin 4 is ground and pin 8 is +5 V. Pins 1, 2 and 3 are the SPI serial interface, while pins 5, 6 and 7 are the potentiometer. Pin 7 is the B end of the potentiometer, while pin 5 is the A end, and pin 6 is the wiper, W. Pin 1, denoted /CS, starts the programming when it is brought low. Pin 2 is the shift clock, SCK, which shifts in the data at pin 3, SI, on a positive-going transition. 16 bits are shifted in, consisting of a command byte followed by a data byte specifying the tap selected, from 0 to 255. Finally, when /CS is brought high, the tap assumes the programmed position. Any deviation from the proper protocol generally results in a no operation command.

When the data is zero, the wiper is connected to the B end of the resistance string, and when it is 255 the wiper is connected to the A end. On power-up the tap assumes the central positon, corresponding to data 128 = 10000000.

The command byte, in the order in which it is shifted in, is X X C1 C0 X X P1 P0, where X is don't care, which we shall take as 0. The Write command is C1 = 0, C0 = 1. P1 and P0 select the potentiometer where two are provided. Here, we have only one potentiometer, so P1 = 0 and P0 = 1. Therefore, our command byte will be 00010001. This is followed by the data byte, high bit first.

A circuit for testing the 14010 manually is shown at the right, where the potentiometer is connected as a rheostat. The pullup resistors on /CS and SI give high (1) values unless they are connected to ground. A debounced pushbutton is used as the SCK. Pressing the pushbutton should give a low to high transition, shifting in the data at SI. It is very necessary that a debounced pushbutton be used here. To program the DCP, start by grounding /CS and SI. Press the pushbutton three times to shift in 000. Now let SI go high and press the button once. Make SI = 0 again and press the pushbutton three times. Finally, let SI go high and press the button. Now shift in the data byte the same way, setting SI and then pressing the button eight times. Try, for example, the data 64 = 01000000. Finally, let /CS go high again, and the new resistance value should be read on the DMM. Repeat with data 192 = 11000000.

When power was applied, my DMM read 4.34kΩ, so the full RAB = 8.68kΩ, although the DCP was nominally 10kΩ. The specifications give a range of 8 to 12 kΩ. Then, if D is the value of the data byte, the resistance should be R = (D/256)8.68kΩ. For the data values given above, I measured 2.2 and 6.5 kΩ, just as expected.

One important use of a DCP is a variable-gain op-amp circuit, as shown at the left. The inverting input is v1 and the noninverting input is v2. For this application, it would probably be better to use a DCP of greater resistance, such as the 50kΩ MCP41050 or the 100kΩ MCP41100.

The other serial interface, the I2C interface, is used in much the same way, except that there is no /CS signal, and the serial data line, SDA, is bidirectional. Instead, changes in SDA while the clock is high are used to signal the Start and Stop. A low to high transition of SDA with the clock high is interpreted as Start, while a high to low transition is interpreted as Stop. These are equivalent to lowering and raising the /CS input in the SPI interface. After a byte has been transferred, on the ninth clock the receiver pulls SDA low as an acknowledge signal.

The Up/Down interface also uses three signals. When /CS is low, a pulse on the INC pin moves the tap one step up or down, depending on the level of the U/D' pin. When /CS is high, INC has no effect. Some chips with this interface have /CS internally grounded, so that the INC is always active. The MAX5160 is an example of this interface, available in 50k, 100k and 200k. Unfortunately, it is only available in a surface-mount miniature package. The Intersil X9511, which is available in an 8-pin PDIP, is a pushbutton-controlled 10KΩ DCP with 32 taps.

It is an interesting exercise to construct an easier way to write to the MCP14010 manually. Two 74LS165 parallel to serial shift registers can shift preset data into the DCP, using the circuit shown at the right. The data is clocked in by using a debounced pushbutton (dbpb). The command byte is hard-wired in the lower LS165, while the data byte is shown determined by the setting of a hex logic switch in the upper LS165. The clock signal used to shift the data in the shift register is inverted to serve as the SCK for the 14010. On the leading edge of a clock pulse, one bit is shifted out of the shift register and appears at SI. On the trailing edge, the bit is shifted into the DCP. To use this circuit, first the shift registers are loaded by bringing /LD momentarily low. Next, /CS on the 14010 is brought low. The debounced pushbutton is pressed 16 times, and then /CS is allowed to go high again, when the new wiper position becomes effective.

To complete our circuit for loading the DCP, we need a circuit that will produce exactly 16 clock pulses. A circuit that will do this is shown at the left. The principle is that the lowest-order bit of a binary counter counting down from 32 to 0 will make 16 clock pulses. The 74LS169 binary up-down synchronous counter is suited to this task. When pin 9 is pulled low, the data applied to the P inputs of the counter are loaded into the counter on the first positive edge of the clock signal CK. To count down, pin 1 is tied low. When the /CEP and /CET count enable pins (7 and 10, respectively) are held low, the counter decrements on the positive edge of the clock input CK. When the count reaches 0000, the terminal count pin /TC goes low. To cascade two counters as an 8-bit binary counter, the /TC of the low-order counter is connected to the /CET enable of the high-order counter. This makes the high-order counter decrement once every time the low-order counter reaches 0000. Clearly, any number of counters can be cascaded in this way.

In this circuit, 0010 0000 = 32 is loaded when /LD is pulled low for long enough that CK will go high at least once. The CK signal is supplied by a function generator that provides a continuous clock signal to the counters. A low frequency will allow one to watch the counting if LED's are connected to the counter outputs and check the operation, but it will also operate at a higher clock frequency. To begin counting, a debounced pushbutton is used to provide a positive clock edge to the 74LS74 D latch. The input data 1 then appears as 0 at the inverted output of the latch, and this level is used to enable the counters. It can also be used to control the /CS input of the DCP. When the counters reach 0000 0000, both /TC outputs are zero and the latch is cleared, which terminates the counting and raises /CS. The output from the lowest bit of the counter is used as the clock pulse for the shift register that loads the DCP, and inverted provides the SCK signal. Therefore, to load the DCP it is only necessary to set up the data byte, pull /LD low (which can load both the counter and the shift register), and finally trigger the latch. The DCP should assume the new resistance as soon as the counter stops.

Microprocessor Control

The 14-pin PIC16F630, for example, can be programmed to control a DCP by emulating the SPI interface. Eight pins are used for the input byte, three pins for the inteerface to the 14010, one pin for the MCU reset, and two pins for power. An eight-position DIP switch can select the input byte, which is then written to the DCP when the reset button is pressed and released. There must be exactly 16 positive clock transitions while the chip select /CS is low, or the command is neglected. It is convenient to have a sending routine that sends one byte. Starting with the high bit, each bit is presented on DI, the clock SCK is raised and then lowered. When 8 bits have been sent, the routine returns. The program must lower /CS, send the command byte 11, then the data byte, and finally raise /CS again. The details of how to do this will be presented in the article on the PIC microcontrollers.


Intersil Corporation, Application Note AN3140, "SPI Protocol and Bus Configuration of Multiple DCPs"

Maxim, Application Note AN1118, "Manually Operated Digital Potentiometer Doesn't Need a Microprocessor"

Microchip, Data Sheet for MCP41010 DCP (SPI Interface).

Maxim, Data Sheet for MAX5402 DCP (SPI Interface).

Maxim, Data Sheet for MAX5460 DCP (Up/Down Interface).

Intersil, Data Sheet for ISL23711 DCP (I2C Interface).

Return to Electronics Index

Composed by J. B. Calvert
Created 19 March 2010
Last revised 21 April 2010