Sunday, June 24, 2012

Pull-up Resistors for Open Collector Outputs

As I mentioned in a previous post about twos complement conversion, I am trying to get an SD card to communicate with a micro-controller.  To do this I needed to interface the 5 V logic levels of the micro-controller with the 3.3 V used by the SD card.  My first thought was to swap out the 5 V regulator on the development board, drop in a 3.3 V version and directly connect the SD card to the micro-controller, but the LCD connected to the board needs 5 V to work.  So that just wasn't going to work.  Besides, the version of the ATmega128 I'm using needs at least 4.5 V.  So my only option was to buy or build a voltage level translator to let the 3.3 V SD card talk to the 5 V micro-controller over the SPI bus.  I wanted it done that day so I decided to roll my own.  I know that there are better ways to do this but I was constrained by what Jaycar, my local electronics store, had in stock.  Below I'll go into detail about a problem related to pull-up resistors that I encountered along the way.

Data logger Prototype

Above is an image of my data logger prototype.  It definitely wont pass any EMC tests.  Actually I'm surprised that its emissions aren't opening garage doors around the neighbourhood.  In the bottom left you can see the breakout board that contains the temperature sensor, the blue board is the ATMega128 development board, and the strip board contains the voltage translation circuitry and an SD breakout board from Sparkfun.  The LCD is connected to the dev board via 12 inches of ribbon cable followed by 12 inches of jumper cables.  Yeah, I'm surprised it works too.

Now on to the voltage translator.  Ignoring the power supply lines, the SPI bus requires 4 data lines, 3 controlled by the master, MOSI, CS, and SCLK, and 1 controlled by the slave, MISO.  To translate the 5 V outputs of the micro-controller to 3.3 V I used 3 buffers of the CD4050.  When powered by 3.3 V the CD40450 inputs tolerate 5 V and recognise them as logic high, a logic high based on the 3.3 V supply voltage of the chip then appears on the output.  Pretty basic stuff.

To convert the single 3.3 V output line of the SD Card to 5 V was a little harder as all that was available to me was the SN7407.  The SN7407 is a hex buffer with open collector outputs that allow it to control voltages up to 30 V.  As the outputs are open collectors, pull-up resistors are required for them to function.  I threw in a 10k resistor and hoped for the best.  It worked first go.  The card initialised and a text file was written to the SD card.  Technically I could directly connect the SD card output to the micro-controller as it only requries 3 V on an input to detect a logic high.  However that leaves a range of 3 V to 3.3 V to register a logic high, and that seems like it could be a little slim.  I'm pretty sure I could get away with it, but just to be safe I decided to translate the output voltage while testing.

When an SD card is first initialised, the SPI clock is set at a low frequency, in my case 250 kHz.  Once the card is initialised, the master is able to increase the clock rate based upon data received in the initial exchange.  For testing I chose to leave my clock rate at 250kHz after this exchange, but now things were working I changed my code so the clock would increase to a 1 MHz after the initialisation.  Once again it worked.  Now I decided to push my luck and increase the clock rate to 4 MHz after initialisation.  This time however my luck ran out.  I had seen a lot of other projects where the clock was higher than 4Mhz and there wasn't a problem, so why wasn't mine working?  As this is a data logger it didn't really matter.  I could leave the clock rate at the low frequency and it'd be fine.  However, curiosity got the better of me and decided to have a quick look at the problem to see if I could fix it, if not, I could move on and be content with the low clock rate.

I thought I knew exactly what was wrong and started to trouble shoot that part of the circuit.  My suspicion was that the 10k pull up resistor on the output of the SN7407 was too large and the MISO signal from the SD card was being distorted.  While probing the SN7407 output I set the clock rate at 250kHz, 1MHz, and finally 4MHz.  I was unable to detect any signal for the 4 MHz clock rate.  Screen shots of my scope are below.

SPI clock rate at 250 kHz, R pull-up 10k

SPI clock rate at 1 MHz, R pull-up 10k

After looking at the scope output it became obvious what the problem was.  The rise time on the output of the SN7407 was approximately 700 nS which was just enough for operation at 1 MHz, but it wasn't going to cut it at 4 MHz.  Notice that the fall time of both signals is comparatively non-existent.  All of these effects can be explained by taking a look at a simplified representation of a channel on the SN7407.

Simplified view of the SN7404 connected to a pull up resistor.

To understand what's happening we need to recognise that there's capacitance on the output, and it needs to be charged and discharged every time the output changes state.  Capacitance on the input of the next stage, along with inherent capacitance in the output transistor of the SN74074, and capacitance of the traces of wire connecting the two stages are all combined and represented by the capacitor Co.

First we assume that the device is fed a low input and has been in this state for some time.  This low input is inverted to give a high at Va.  This high turns on the output transistor and causes a current to flow through the pull-up resistor which drives the output voltage low. As the transistor has been in this state for some time, the capacitor is drained and has stabilised to the low output voltage.  If the input is now set to high, the voltage at Va becomes low and the transistor turns off.  This effectively disconnects the collector from the pull up resistor and output capacitance.   This leaves a simple RC circuit where the output capacitor is slowly charged to 5 V via the pull up resistor.  The time taken to reach 63% of the final output is equal to RC.  By looking at the scope output we can calculate that a capacitance of approximately 30pF is being charged via the 10k pull-up resistor.

After enough time passes and the voltage across the output has stabilised, the input is now driven low again.  This turns the transistor back on and causes current to flow through the collector and discharges the output capacitance.  Whereas the time to charge the capacitor was controlled by the high impedance pull-up resistor, the time to discharge the capacitor is controlled by the low impedance path through the transistor.  Because this occurs a lot faster, the fall time is small compared to the rise time.

To decrease the rise time the output capacitance needs to be charged faster, and the easiest way to do this is to drop the value of the pull up resistor.  By replacing the 10k resistor with a 1k resistor, the rise time should decrease by a factor of 10.  So that's exactly what I did.  Using clock rates of 250 kHz, 1 MHz, and 4 MHz I again tried to write to the SD card.  This time however the system worked using the 4 MHz clock rate, and if we once again probe the output signal we can see why.

SPI clock rate at 250 kHz, R pull-up 1k
SPI clock rate at 1 MHz, R pull-up 1k
SPI clock rate at 4 MHz, R pull-up 1k

Using the scope we can see that the rise time of the pulses is now around 70 nS, which is 10% of what it used to be.  Problem solved. There is a trade off to consider however.  Using a smaller pull-down resistor will use more power, but as I am powering this of plug pack I don't have a power budget to consider.  Don't get me wrong, I'm not going out of my way to waste power, but it's not my biggest concern.

By looking at this simple problem you can see how something as basic as a pull up resistor can effect the operation of a circuit, and although I have the SPI bus working with a clock rate of 4MHz I'll only run it at 250kHz.  If it works at 4MHz it should be rock steady at one sixteenth the speed.  It's only a data logger after all.

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.