From the bench

MCP4728: What It Is, How to Wire It, and What Goes Wrong — Engineer Q&A

August 17, 2026 · AI-generated from the datasheet, fact-checked by two independent LLM critics

The MCP4728 is a quad-channel, 12-bit, buffered voltage-output DAC from Microchip with an I²C interface and onboard nonvolatile EEPROM. It's a resistor-string architecture intended for applications that need a precise, low-power DAC with moderate bandwidth — set-point and offset trimming, sensor calibration, portable battery-powered instrumentation, and motor speed control. Its differentiator is persistence: DAC codes, the I²C address bits, reference selection, gain, and power-down bits all live in EEPROM, so outputs return to their last stored values on power-up with no host re-programming. Supply range is 2.7–5.5 V, the output buffer is rail-to-rail with roughly 6 µs settling, and all four channels together draw 800 µA typ at VDD = 5.5 V with all channels in Normal mode — dropping to 40 nA standby when fully powered down with the external (VDD) reference.

Next step
Start building with MCP4728 → This guide comes from the same grounded, cited datasheet answers — ask the assistant your own MCP4728 questions.

What is the MCP4728 actually for? (What is this part and what's it for?)

The datasheet positions it as a general-purpose resistor-string DAC "intended to be used in applications where a precise and low power DAC, with moderate bandwidth, is required." The manufacturer's applications list includes set point or offset adjustment, sensor calibration, closed-loop servo control, low-power portable instrumentation, programmable voltage and current sources, industrial process control, and bias voltage adjustment for power amplifiers. The applications section narrows this to set-point/offset trimming, sensor calibration, battery-powered portable instrumentation, and motor speed control.

The worked example in the datasheet is a DC set-point application: four channels generating four different trip voltages for calibrating a sensor offset or bias point, programmed via Sequential and Fast Write commands.

Equally important is what it's not for. The datasheet never frames it for high-speed or waveform-generation work — it's explicitly low-power, moderate-bandwidth, DC-set-point oriented, which is consistent with its settling and stability profile. If you need fast arbitrary waveform output, this isn't your part.

How do I wire it up? (Integration and surrounding components)

Power and decoupling. Run VDD in the 2.7–5.5 V operating range and never exceed 6.5 V absolute max — size your input rail so supply transients stay well below that. Bypass VDD with a 0.1 µF ceramic and a 10 µF tantalum in parallel, placed within 4 mm of the pin. This matters more than usual: when VREF = VDD, the supply is the DAC reference, so supply noise degrades DAC performance directly. If you have separate digital and analog planes, keep the MCP4728's VDD/VSS on the analog plane.

I²C bus. SCL and SDA are open-drain N-channel drivers, so pull-ups to VDD are mandatory. Size them for 5–10 kΩ at 100–400 kHz, roughly 700 Ω for 3.4 MHz High-Speed mode, and go smaller if bus capacitance is high. The part's own input capacitance is ≤3 pF with ±1 µA leakage, so the pull-up is driven mainly by total bus capacitance and bus speed — Fast mode (400 kHz) allows an SCL rise time up to 300 ns. The part is slave-only; SCL accepts external clocks only. Digital inputs are Schmitt-triggered with VIL = 0.3·VDD and VIH = 0.7·VDD, so your pull-up rail or level translation must actually reach ≥0.7·VDD for a clean high.

LDAC. Two valid choices: tie it permanently low so every channel's input register transfers to the output at the last acknowledge pulse (a zero-external-component option), or drive it from an MCU GPIO to update all four outputs simultaneously on the high→low edge. It's a high-impedance digital input — drive it actively rather than leaving it floating. One more reason to give LDAC its own GPIO per device: if you ever put multiple MCP4728s on one bus, LDAC is the only mechanism for isolating a factory-default part during address programming (more below).

RDY/BSY. This is a real open-drain pin, not just a register flag. Give it a ~100 kΩ pull-up from VDD, or leave it floating if you don't use it.

Protection. All pins carry ≥4 kV HBM / ≥400 V MM ESD protection built in. For pins exposed at board edges, remember the absolute-max pin range is −0.3 V to VDD+0.3 V with input current limited to ±2 mA — a series resistor on the I²C lines provides over-voltage/current limiting.

What are the traps specific to this part? (What should I watch out for?)

The address is in EEPROM, not on pins. The A2/A1/A0 device address bits live in EEPROM with factory default "000" — there are no address straps. You reprogram them over the bus with the Write I²C Address Bits command (C2=0, C1=1, C0=1, max 400 kHz). The command requires the current address, and LDAC must be pulled High→Low at the low time of the 8th clock of the second byte and held low through the end of the third byte; the update occurs after the Stop bit. If multiple factory-default (000) parts share a bus, all of them respond simultaneously — the only per-device selector is LDAC, so each device needs its own LDAC line. Program one device at a time: hold all other LDAC lines high, run the command, wait out the EEPROM write, power-cycle (or send General Call Reset 0x06), then move to the next device.

The gain bit only works with the internal reference. Per-channel gain of ×1 or ×2 is applicable only when the internal VREF is selected. If VREF = VDD, the device uses gain 1 regardless of the gain bit — setting gain 2 on a VDD-referenced channel silently does nothing.

Factory defaults use the internal reference. All four channels power up with VREF bit = 1 (internal 2.048 V bandgap). Design your scale factor around that on first boot. With the internal reference and gain ×1, LSB = 0.5 mV and full-scale is 2.048 V; gain ×2 gives 1 mV LSB and 4.096 V full scale. If you feed 3.3 V expecting a 0–3.3 V swing, you won't get it. Conversely, the internal reference self-disables when all channels select VREF = VDD, so going all-external draws no bandgap current.

EEPROM writes block the device. EEPROM write time is 25 ms typ / 50 ms max, and any command received during an EEPROM write is silently ignored. RDY/BSY goes low only while programming is in progress. Poll RDY/BSY (at the pin or via the read-command flag) or time out before sending the next command after any EEPROM-writing transaction.

Pick the right write command. Whether a write touches EEPROM depends entirely on the command code: Fast Write (C2=0, C0=X) updates input registers A–D only; Multi-Write updates one input register at a time, no EEPROM; the Write DAC Register and EEPROM commands (Sequential/Single Write) are the slow path that triggers RDY/BSY and the command-ignore window. Use Fast/Multi-Write for live updates; reserve EEPROM writes for persistence events. Note the datasheet publishes data retention (200 years typ @ +25 °C) but no write-cycle endurance rating — so don't treat EEPROM writes as free.

Power-down states and sleep math. Each channel's PD1/PD0 bits choose Normal, or VOUT terminated to ground through 1 kΩ, 100 kΩ, or 500 kΩ — pick per your leakage-vs-impedance trade. Full power-down with external reference draws 40 nA typ; with the internal reference kept on it's 45 µA typ / 60 µA max — a 1000× difference if you forget to switch to VDD reference before sleeping.

Reference switching has its own settle delay. 26 µs typ external→internal, 44 µs internal→external. If firmware toggles the VREF bit at runtime, wait these out before trusting the output.

Known limitation: the datasheet publishes no numeric POR/startup-ready time (time from VDD crossing the ~2.0–2.2 V POR threshold to ACKing on I²C) and no EEPROM write-cycle endurance rating. Poll the POR status bit via the I²C read command after power-up rather than relying on a fixed delay, and treat endurance as an unknown.

How do I test it? (Verification procedure)

With the internal reference at gain 1, 1 LSB = 0.5 mV, so the ½-LSB settling target is 0.25 mV — you need a DMM with sub-millivolt resolution and noise floor to verify settling and the 20 mV offset bound. A concise bench run-list:

Step What to do Pass criteria (datasheet)
1 Ramp VDD slowly, probe for POR ramp ≥1 V/s; operable above ~2.2 V
2 I²C ACK + read-back at target speed ACK at ≤400 kHz (2.7–5.5 V)
3 Output @ code 000h ≤20 mV offset
4 Output @ code FFFh within ±1.25% FSR gain error
5 Linearity sweep 100–4000 INL ≤±13 LSB, DNL within ±0.75 LSB
6 Step ¼→¾ FS, scope settling settles to ½ LSB within 6 µs typ
7 Write to EEPROM, power-cycle value persists; wait ≥50 ms / poll RDY/BSY
8 Measure standby ~40 nA (ext ref) vs 45 µA (int ref)

The pass criteria come straight from the datasheet's electrical-characteristics and timing tables; the DMM-resolution guidance is engineering practice.

Use the read command to verify configuration, not just DAC values. Each channel returns a 24-bit frame: bit 23 is the RDY/BSY flag (1 = no EEPROM write in progress), bits 22–20 echo A2/A1/A0, bit 19 is VREF, bits 17–16 the channel ID (DAC1/DAC0), bits 15–14 PD1/PD0, bit 13 Gx, and bits 11–0 the DAC code. A solid firmware pattern after any write: read, confirm RDY/BSY = 1, confirm the channel ID matches, then compare VREF/Gx/PD bits and the code against what you wrote. For an authoritative address read, use the General Call Read Address Bits command (address 0x00, second byte 0x0C) instead of the per-channel echo.

Why isn't it behaving? (Troubleshooting)

Output stuck low or "missing." First check the power-up ramp — it needs ≥1 V/s for POR/EEPROM readiness, with the POR threshold around 2.2 V typ. Then check your full-scale math: FSR is VDD (VREF=VDD), VREF (internal, gain 1), or 2×VREF (internal, gain 2). An output that only swings 0–2.048 V isn't a fault — it's the internal reference at gain 1, which is the factory default.

Wrong output level / scale error. The internal reference is 2.048 V typ but ranges 2.007–2.089 V, so a unit measuring slightly off nominal is within tolerance. And remember gain ×2 is ignored when VREF = VDD.

Output slow after a code change. Settling is 6 µs typ (¼→¾ FS step), but add 26 µs (ext→int) or 44 µs (int→ext) if you switched the reference at runtime, and 4.5 µs typ to wake from power-down.

Output oscillates. Capacitive load must stay ≤1000 pF at RL = 5 kΩ for stability — an oversized bypass on VOUT is the usual culprit. Keep RL > 5 kΩ for best accuracy.

Commands appear ignored. If the previous command wrote EEPROM, the device ignores everything for 25–50 ms — poll RDY/BSY. If you're using an LDAC pulse to latch, it must be low ≥210 ns; shorter pulses don't update.

No I²C response. Check bus speed vs. voltage: 400 kHz Fast mode needs ≥2.7 V with ≤400 pF bus cap; 3.4 MHz High-Speed requires ≥4.5 V and only ≤100 pF. Scope SDA/SCL — the rise time must be ≤300 ns in Fast mode, and weak/too-large pull-ups stretching it cause missed ACKs. Verify levels actually cross VIH ≥ 0.7·VDD / VIL ≤ 0.3·VDD.

Bus won't idle high. SDA and RDY/BSY are open-drain and must pull to ≤0.4 V at 3 mA sink. A line sitting half-pulled usually means a missing or open pull-up.

Standby current is microamps, not nanoamps. The internal reference is still enabled — switch channels to VREF = VDD before powering down to hit the 40 nA figure.

Small glitch on mid-scale transition. Major-carry glitch is 45 nV·s typ (7FFh→800h) with crosstalk <10 nV·s — that's normal, not a fault.

Part page: MCP4728.