PART 2 - Hardware Board Design
While browsing my lab materials I found several 7 segment displays that I bought years ago for another project that are the TR332S 10x19mm common cathode.
As general advice when using a component it is wise to have a look at the datasheet. Here we find the pinout and, most important, the supply current to switch on the segments which is 10 mA. A LED's voltage drop is usually about 1.6 Volts. So we should put a limiting resistor on each segment and then connect the cathode to ground. I'm sure you've seen this configuration many times, but in this case the power supply is about 3.3 volt and the display will be “on” only for 8 msec. I grabbed a “expendable sample” and tested it on a breadboard having the LEDs directly connected to a 125 Hz (8 msec) 3.3 v power square wave signal and cathode connected to ground.
The mean voltage value appeared to be around 1.6 volt as expected and the LED was on at full brightness. I left this configuration running for 5 hours to see if the display would die. Since everything was ok, I decided to get rid of any resistor and use the display directly connected to the bus on one end and with the common cathode to ground on the other. Actually if we lift the ground to 3.3 volt the current stops flowing into the LEDs and the display shuts off. Hence, to power on the LEDs it is enough to route the cathode pin toward a ground path. So the multiplexing is only a matter of driving both cathodes with a complementary signal, when HIGH to the display A it should be LOW to the display B.
The microcontroller to be selected can be any type ... it must only have at least one 8 bit port, an 8 bit timer and 4 spare pins, one for multiplex control and three lines for SCK, MISO and MOSI. Since I have many of these in my lab I chose one of the giants of the past: the PIC16F84A that has only 1K flash, 68 bytes of RAM and an EEPROM of 64 bytes.
This device comes in different versions and can reach 20 Mhz. I found that using the low speed 4 Mhz version this part can be powered either at 3.3 v so it accomplishes our first goal. Let's now see the hardware board schematic:
Here you can see that PORTB will be used as the data bus for the displays, while PORTA signals are as follows:
RA0 will be used as a multiplex signal. It is routed directly to display B and inverted to display A.
Actually when RA0 is 1, Q2 is saturated so the Vce drops to 0.2 Volt and display A's cathode is routed to ground. The display B cathode is lifted to 3.3 volt so the LED is off.
When RA0 is 0, Q2 shuts off and the collector floats. So the Vc level is rapidly pulled to Vcc though resistor R2. Hence display A shuts off and display B will go on.
We have to consider current limits. The PIC datasheet reports that each pin is capable of sourcing or sinking about 25 mA, so this current is enough to drive the display directly (10 mA max). Actually when RA0 is at logic 0, the measured voltage to that pin will be probably higher because the LED voltage drop cannot be higher than 1.6, so it would be better to put a resistor from the cathode of display B to the RA0 connection point to free the voltage swing of that pin. For the moment we left it this way ... just take a note about it to see what will happen when we test the circuit.
There is no special reason for selecting the 2N3904 transistor. I had more then 100 items available at my lab so I definitely will use one of them. Since Q2 works at low frequency (125 Hz) you can use any other general purpose NPN you like or, for example, a 2N7002 MOS transistor as a switch. Do not forget to check the footprints for insertion into the printed circuit board (PCB). Each transistor has a different switching time, so when RA0 switches from 1 to 0 you could expect the Vc voltage takes a short time to be raised to Vcc. In this time the display which is turning off will have a shadow image of the other display. Should this happen, experiment with the value of R2 from 100 to 470 Ohms. I found a good value to be 150 Ohms when testing the prototype.
Looking at the schematic I guess that a question which immediately comes up is why connect the PIC and the display pins in such a weird way?
The reason has to be found in the topology of both chips. Take into account that a simple connection on the schematic can be tricky when designing the PCB layout. So while you are drawing the schematic, you might have a look at the physical body of the components. Looking at both chip pin-outs it is obvious that choosing to put the PIC on top of the display makes it easier to connect as follows:
Using this strategy the PCB layout will be less complex and with fewer cross-points. This is a winning consideration every time you are designing something. Even if you have the best autorouting software and 4 layer PCB manufacturing technology available, nothing can substitute for the overall human broad vision. So be clever in your choices.
It is clear however that using this topology, we have to carefully design what segments can be switched on to show a digit and the corresponding PORTB pin arrangement. At this point it is handy to build this table which shows the segment map for each possible symbol:
Now we have to shuffle this table to map which PORTB pins to use, according our PCB connection arrangement, and then calculate the LED code to be output for each symbol we want to display. Here is the result:
The red column is the reference table we need to store inside the PIC to drive the 7 segment display. So when the host wants to display, for example, the character 'H', the PIC will retrieve the entry at the address 0x10 in the table (dec 16) which is the LED code 0x6E.
This value will be put on port B resulting in displaying the letter H.
Note that for switching off a display we only need to put a 0 byte on port B. We might store this constant table in a convenient manner inside the PIC either in a flash memory region or in the onboard EEPROM.
In this first version of the PIC16F84A firmware, I will not use the “decimal point” LED, but should you want to use it you only need to OR each retrieved bitcode value with 0x80 (0b1000000). You only need to decide what convention the host will use for transferring the need for turning the decimal point on.
Here you find the autorouted and refined version of the PCB design. Later on you will find an archive with PDF files ready to print for both sides of the work.
This completes our Hardware Design Part, so let's move to the next part which shows how implement our Java multithreaded Host-Device Protocol Simulation.