I know there are similar questions on the site, but I wanted to ask it from a somewhat different perspective.

  • I've got a 5V device (Device A) that can operate at 3.3V.
  • I've got a 3.3V device (Device B) that does not have 5V tolerant inputs.
  • I want to connect these two devices together to communicate over an SPI interface.
  • I want to be able to operate Device A selectively at 5V or 3.3V.
  • Device B is independently powered and always runs at 3.3V.

I know I can use (and have successfully used) a buffer (e.g. 74HCT125) powered by the same voltage as Device A to boost Device B's signals up to 5V. I'm not as sure of the best approach for the other direction though (i.e. dropping Device A's outputs to an appropriate level for Device B).

I've read the Sparkfun Tutorial on the subject. <-- 2022: The Sparfun tutorial link is dead.
It quite possibly reffered to this retired tutorial -
Using the logic level converter

Maybe see also the following Sparkfun guides:
Bi-Directional Logic Level Converter Hookup Guide
TXB0104 Level Shifter Hookup Guide a learn.sparkfun.com tutorial
Level Shifter - 8 Channel (TXS0108E) Hookup Guide
Single Supply Logic Level Converter Hookup Guide
Bi-Directional Logic Level Converter Hookup Guide {another one}

They offer a few ways to approach the "downward" level shifting. What is the preferred way of handling this aspect? Since I'm using SPI here, the classic MOSFET solution for I2C seems like overkill to me since I don't need bidirectionality. I like the Inline Resistor approach for its simplicity, but I am uncertain how to size the resistor. The CLK and MOSI pins of Device B are specified with V_IH_min = 0.7 * V_cc = 2.31V, V_IH_max = V_cc + 0.3 = 3.6V and with Input leakage current of max 0.5 uA.

By my math this means I need to drop between 1.4V and 2.6V in the case (1) where Device A is operating at 5V and no more than 1V in the case (2) where Device A is operating at 3.3V. If I assume the 0.5 uA leakage current is responsible for the voltage drop then case (1) calls for a resistor between a 1.4/0.5e-6 = 2.8 MegOhm and a 2.6 / 0.5e-6 = 5.2 MegOhm resistor(!). And case (2) calls for a resistor no smaller than 2 MegOhm. Therefore case (2) is dominated by case (1), and I should pick a resistor somewhere in between the calculated range, like 3.3 MegOhm for example.

That value seems ginormous to me (especially when the SF tutorial is showing values like 10 kOhm) ... and that is just for the max input leakage current (no min or typical is specified) is there a flaw in my reasoning or calculations, or is this not the preferred way to interface the devices (e.g. the Diode method)?

If it matters, one case of Device B I'm thinking of is a 23K256 SRAM, but I'm trying to account for a variety of devices.

  • \$\begingroup\$ The leakage current is the lowest current that you can get away with designing a divider to handle. You can and should take many times that as "load current". This will then swamp leakage current effects. \$\endgroup\$
    – Russell McMahon
    Oct 19, 2011 at 19:13

1 Answer 1


The leakage current is the lowest current that you can (notionally) get away with designing a divider to handle. You can and should take many times that as "load current". This will then swamp leakage current effects.

Ginormous resistor values will lead to long rise and fall time constants (when combined with the IC's input capacitance and stray capacitances) which you do not want.

If you want mono-directional driving and level reduction only then a resistor divider will work fine.

enter image description here

"All" that is required is to ensure that

  • Vout_high_max when divided down does not exceed Vin_high_max of the driven IC. (Better, input high and low worst case limits produce output voltages also in the required ranges.)

  • Overall time constants are small when compared to your signal switching speeds OR

    • If you can't make them small they must be acceptable. eg when writing data mono-directionally a significant delay may acceptably occur in delay and data lines as long as it is consistent and about equal in all relevant signal leads. Problems may occur when handling bidirectionally as eg a delayed outgoing clock may causes data to be returned long after the clock has sampled the data "successfully".

1 Megohm x 1 picoFarad gives a time constant of 1 uS.
You can scale from there as required.

eg if you had 20 pF of stray and input capacitance and were using a 100 kOhm divider resistance (which would be high) then time constant 20 pF x 0.1 Megohm =~~~2 uS.

Referring to your 23A256 RAM as an example only

Input capacitance = 7 pF.
Max clock rise and fall time = 2 uS
BUT max clock rate can be 20 MHz (difficult) or 50 Ns total cycle time.

If all up capacitance is taken as 10 pF (7 pF input + 3 stray) then
- 100k drive resistance gives you 1 uS time constant on the driven line(!),
- 10 k drive resistance gives 100 Ns and
- 1k gives 10 Ns.

To achieve a 1k equivalent resistance with a 3.3V to 5 divider you can have Rupper = 1.4k and Rlower = 2.7k. Parallel resistance. = 0.92K and series res = 4.1 K so current at 5V ~= 1.2 mA.

The 10 nS time constant with resistors i the 2k range translates to rise and fall times of several tine constants - so these approach the times involved per half cycle at maximum speed. As these delays will be included in all down converted lines the differences in delays should be much smaller. If using bidirectional transfer this may cause a problem with eg data setup or hold times. Looking at the data sheet in each specific case is essential.

ie I'd expect a simple low value resistive divider to work in many mono-directional cases but care will be needed at higher clock speeds. Referring to diagram above.

  • Reffective for tim contant calculations = R1//R2

  • RseriesDC drive mA chck is R1 + R2.

  • Vout = Vin x R2 / (r1+r2)

  • -
  • \$\begingroup\$ This answer is quite thorough, thanks! I get the concept for the voltage divider. Could you possibly expand on your answer to address what's going on with the series resistors on MOSI and SCK in the Sparkfun tutorial? Is there an implied divider inside the 3.3V device in that case? \$\endgroup\$
    – vicatcu
    Oct 20, 2011 at 17:12
  • \$\begingroup\$ Unfortunately the original article references in the question is now a 404. But IIUC it would need 3 voltage dividers from the master to the slave on CS, SCLK, MOSI. Is that correct? \$\endgroup\$
    – tcurdt
    Feb 25, 2023 at 14:41
  • \$\begingroup\$ @tcurdt That link still works for me. It gives a security alert, but as it is Microchip, continuing to site is safe. And, yes, 3 dividers. Rereading the original question, this would work for 5V to 3V3 interface but not if both were 3V3 or 3V - shorting the top divider resistor would work if the lower value was not so low that it loaded the source driver excessively. \$\endgroup\$
    – Russell McMahon
    Feb 26, 2023 at 0:47
  • \$\begingroup\$ Thanks for confirming! Sorry for not being specific enough. I was referring to the sparkfun tutorial at sparkfun.com/tutorials/65 which is a 404 (for me). \$\endgroup\$
    – tcurdt
    Feb 26, 2023 at 11:46
  • 1
    \$\begingroup\$ @tcurdt If I'd read your comment properly I'd realise what you meant :-) - you were clear enough. || I've added what MAY be the correct link in the question, plus a few more somewhat related. Have fun. || 2 resistors per line will work if voltage is lower in target. \$\endgroup\$
    – Russell McMahon
    Feb 27, 2023 at 11:12

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.