are you kidding, i broke a lot of basic design conventions. the way the mosfets drive the common anode of the 7 segment displays is probibly incorrect. every electronics tutorial i read likes to put the load above the drain. but in my case the load is drawn from below the source. this probibly is not a good idea, and i probibly need some resistance somewhere to balance things out. it would have been better to use common cathode displays and put the mosfet downstream.
the line decoder selects which of the 8 mosfet gates to open, and 2 other transistors go right to the mcu, its purpose is really to toggle 8 gates with 4 pins (3 bits + chip enable to bring one of the 8 channels high, or ~chip enable turns all of them off), and i still need 2 other pins for the last 2 mosfets, since there are 10 displays to drive and a mosfet for each. the job of the chip is essentially to reduce my pin count for controlling the driver circuitry from 10 to 6. i could have used a bigger mcu, and drive the gates directly, but considering the low performance application in this case, it would be a waste. the mosfets allow the displays to draw more current than the mcu/decoder, which are limited to around 20ma. an led segment in the display can draw that on its own, and if you wanted to draw a zero and decimal place, the display would draw 160ma. and the mosfet can supply up to 400ma. only one display will be powered at any time. and thats it for the driver side.
the shift register in this case provides a sink source. for unpowered displays a value of either 0 or 1 has no meaning. in case of 1, the diode will be reverse biased, and will prevent flow, and in case of 0 there will not be any (meaningful) voltage differential to cause current flow. for a powered display, a 0 will allow power to flow, current here will only be about 20 ma, and the pins on the shift register will tolerate that. if its a 1, again no (meaningful) voltage differential, as there will be 5v at each end. all the displace have their cathodes on a common bus, which connects to the shift register through the 8 current limiting resistors (i tested it with 120 ohms, but i might use higher or lower depending on display brightness). the shift register is a serial device, so it only takes 3 pins to control it.
only one display is powered at any time. to output to it, you first power one of the driver channels. then you shift out a byte to the bus. each bit corresponds to a particular segment in the display, and its active low so a 0 turns it on and a 1 turns it off. let it stay on for a small amount of time, then switch to the next driver channel and shift out the value for the next digit. update all the displays thusly. at any given time only one display is on, so for every 10 seconds, each display is on for only one second. but if you do this fast enough, like keep each display on for about a ms, then every 10 ms, they come back on, and thanks to persistance of vision, it looks like its always on.
you can talk to it over i2c, serial, or spi over the icsp port, and i had a pin left over, so i figured id use it for an external interrupt/or a slave select for the spi interface. could probibly also do a one wire serial protocal with it as well. given the limited amount of resources on the microcontroller you probibly wont be able to change interfaces without a reflash, but thats ok, il probibly just use the 12c port.