Category Archives: Bin to Hex 7 Segment Decoder

Binary to 7 Dual segment Display

Following on from the previous project, I have been asked to look at updating this project to drive two 7 seven segment displays instead of one seven segment display. So, instead of taking av4 bit binary input (0000 to 1111) and driving a single 7 Segment LED display with values from 0 to 9 and A to F; the plan is now to read 8 bit of binary data (00000000 to 11111111) and output corresponding hex value (00 to FF).

This is now makes this project and ideal tool that can be used on the retro computer build. As one of these circuits could be used to read the data bus while two could be used to read the address bus.

It does mean that we need to change the way the existing project is wired. The PIC controller only has 16 inputs/output pins. If we are to read the 8 bit binary data this leaves only 8 pins for driving the output and reading the control lines. As the 7 segment LED displays need 7 lines (8 if we include the decimal point) we need to look at an alternative way to drive the LED displays.

If we use a serial to parallel shift register we could drive 8 lines from just a clock and data line, by using a third pin we can enable/disable the shift register. This will let us drive all seven segments plus the decimal point. This solves the first issue of driving more lines from less pins on the PIC micro controller.

The next issue, is how do we drive two 7 segment displays. This can be achieved by multiplexing the display. By this I mean we light up one display with the segments required, then we switch on the other display and light up the segments on that display. By switching on the segments on the two LED alternating, we can give the appearance that both displays are on at the same time.

In the above circuit we can see we added a busy line to the circuit to let external circuits know when the decoder is busy updating the display.

The external circuit only needs to place the 8 bit data on the data bus, bring the enable pin low and then bring the write line low. The resistors on port A provide pull up logic, to ensure the data lines are not floating and are in a known state. The PIC micro controller has internal weak pull up resistors, so the resistor network RN1 may not be required, we will only know when we start testing.

Lets look at how this is going to work…

As this circuit will be used to drive LED displays which tend to be consume power, we don’t need to worry too much about power consumption, but lets not just ignore it, we still want to be as efficient as possible. With this in mind, the PIC micro controller will be using its internal oscillator of 4MHz. We could use an external 20MHz crystal / resonator, to allow for faster speeds. As we want to keep the costs down, there is no need to add parts that are not required. As the LED displays are used to display the result to us humans, we don’t need a fast refresh rate for the HEX display. So if the refresh rate is set to 100Hz it should provide a good display results. When the display is not getting updated the PIC should power down into standby more.

First we need to read the input and the control lines, when both the WR (Write) and EN (Enable) go LOW, the micro controller will set the BUSY pin active (LOW) and then read the 8 bit input. When the controller had saved the value to displayed, it will then set the BUSY pin inactive (HIGH).

A timer interrupt will activate every 10ms, the BUSY pin will go active (LOW) to indicate to any external circuit that the controller is refreshing the displays. Once the controller has finished refreshing the display it will the BUSY pin as inactive (HIGH).

When the PIC has the 8 bit data word, it will be broken into two 4 bit nibbles. Each 4 bit nibble will then be converted to a hex value. As the conversion for each nibble is the same, we can simplify the process by converting the first 4 bits from the right to our HEX value, then we shift right the word by 4 bits and cover the first 4 bits from the right to our HEX value. This means we can keep the routine from the previous project for converting our input to HEX.

Once we have the HEX output we can send it one bit at a time into the serial to parallel shift register. The 74HC164 IC the devices that we are using in this circuit, as it is low cost and simple to use. The A & B inputs will be tied together to ensure that we are sending the same data to the into the shift register.

The active low clear pin will be used to reset the IC while the CLK pin will be used to clock data into the shift register. Once we have clocked the data in, we then switch on the relevant 7 Segment LED display, to show the result.

7 Segment Display Lookup Table with BCD Data

The above table shows what segments of the LED display should be switch on to display the various values from 0 to F.

Binary to 7 Segment Hex Decoder

While working on the Retro Computer Project, I was looking to build a small interface that would let me connect to the address and data bus of the Micro to provide a method to manually program the micro as well as read/write  data into memory.

Back in the last century there was a logic IC that provided this function, but I couldn’t find it anywhere. There were plenty of the BCD to 7 segment decoders, but nothing that would give values above 9 such as A, B, C, D, E & F.

Time for a quick project and to quickly put something together! So I looked at what I had available and had a boot load of PIC 16F628 Micro controllers. So if you can’t find what you are looking for, build it!

As my goal was to get something to put together in a couple of hours that I could use quickly, I was not thinking about how efficent the code would be, so there may be better ways of doing this. Please feel free to take the code and schematic for this Binary to Hex 7 Segment decoder and use it for your own projects. All I ask is that you link or reference back to me and this project.

With this project, the first step was to define my requirements, my outputs and inputs. Obviously I needed to drive a 7 Segment LED display (common cathode). I needed an input to latch data into the decoder and wanted to have a test function as well as a blanking input.

The Hardware

I used the internal oscillator on the PIC as the clock, set to 4MHz. The main loop in the code checked to see if any of the control lines were active. If any of these control lines were active (low) the PIC microcontroller would perform the necessary action. The data for the decoder was latched into the buffer prior to decoding.

Bin2Hex_Schematic (PDF)

Hex27Seg (KiCAD Project)

You can ignore the switches to the left of the PIC in the schematic, as there were just used to simulate the control lines and the data input. The resistors to the right of the PIC were just current limiting resistors for each of the 7 segments in the LED display.

The Code

The code was fairly simple and can be broken down it to a few sections. The first being the port setup code. As the PIC has many multi-function pins, its very important to set these correctly at the start. One mistake that I made was to forget to turn off the analogue comparators on PORT A, ended up wasting an hour looking at this, until the penny dropped.

In the main loop of the program, I started by reading the data on PORT_A and then performed a test to see if any of the control lines had gone active low.

You will notice in the code, that the first test performed is for the Blanking Input – if this was not active then the code would check for the Test Display Input. As this was nested inside the if-else statement for the Blanking Input, the Blanking Input had priority over the Test Display. This was one simple way to implement such logic.

When the control lines were active, I wanted to ignore any update from the Latch line, so a simple flag was used to achieve this.

The code for then managing the  control lines was very simple. It could well have been included in the main. I have found by experience, it is always better to have separate function code block for every action. This makes the main code loop easier to read and when you’re troubleshooting, you’re not finding yourself going back over blocks of code again.

In this screen shot you can see the first few lines of the code for the section that converted the binary data into values for the 7 Segment display. In the first line of code I was performing a logical AND to clear out the upper bits of the data, as these bits were the control lines on PORT_A.

Next I compared the data with values from 0 to F inclusive. Based on the value I switched on the different segments of the LED display. I left the formatting of this in binary as I thought this might make it easier for other to read.

You will notice in the code segment above, there is a line that is commented out. This was my debug function, which was used to flash the LED decimal point x number of times, to indicate the value of the data input. This is a good point to bring up. When building any system large or small, it’s always handy to have some form of debugging build in. Just having a simple LED to flash, can save a engineers time, as there is nothing better than a visual indicator to let the person know that they have reached that point in the code.

The source code for the project which was developed in MPLABX is included below. Please feel free to copy and modify the code as you need for your project. I’m just going to program 6 of these for the Retro Computer Project and build the interface board next.

Project C Source Code (Zipped)