On Sunday, March 11, 2012 11:21:33 PM UTC-4, Shawn McCombs wrote:
Is there a way to make a pin turn to ground, instead of 5 volts?
Microcontroller I/O pins typically have 3 states:
HIGH - A pull-up transistor in the uC connects the pin directly to Vcc. To cause this state, you set the appropriate bit in the port control register to "output" and then write a "1" to the pin itself.
LOW - A pull-down transistor in the uC connnects the pin directly to Gnd. To cause this state, you set the appropriate bit in the port control register to "output" and then write a "0" to the pin itself.
HI-Z - Nothing in the uC is attempting to pull the pin high or low, so it just floats at whatever level the rest of the circuit pushes it to. To cause this state, set the appropriate bit in the port control register to "input". (On some chips, I think it's also necessary to write a "0" to the pin itself.) Performing a read from the pin itself, while in the input state, will return a 1 or a 0 depending on what voltage level the pin is floating at. Most chips set all I/O pins to this state at power-on (that is, the port control register initializes to "all-inputs"), until the program makes them do something else. The name is from the letter Z's use to denote "impedance"; in this state, the pin has a high impedance.
If you want to stretch your brain a bit, read up on Charlieplexing; it's a fascinating technique that uses all three states.
AVRs, and perhaps other microcontrollers, also implement a fourth state: INPUT WITH WEAK PULL-UP. In this state, a *different* pull-up transistor in the uC connects the pin to Vcc with a high-value resistor in series. Because switches are usually read by pulling them up with a resistor, then letting the switch yank the line to ground, building this pull-up into the chip saves on external parts-count. I'm not quite certain how to cause this state; I think it might involve setting the pin to "input" and then writing a "1" to it. Corrections welcome!
Shift registers will call themselves "tri-state" if they implement a Hi-Z state. But because this means each pin has more than one bit worth of state information, this means the shift register (or whatever other component is implementing it) must also have an extra register of bits to control the state. (Think of it like alpha-channel transparency in video.)
Incidentally, Aaron is right, in that the AVR (as well as most other chips) can sink more current than it can source. Which is to say, if you want to direct-drive a bunch of LEDs, you could wire the cathodes to ground and use the uC to bring the anodes high, but you'd only light a handful before the chip was over its specified current. Alternately, you could wire the anodes to Vcc and use the uC to bring the cathodes down, and you'd be able to control more LEDs without overloading anything.
In all cases, RTFM before putting a lot of load on the chip! Even if you don't smoke anything, heavily loading the I/O pins can tax the Vcc and Gnd nets, which may throw your analog reference off, mess with reset or brownout detection logic, and other pains.