Jake's Electronics

a place to document


4 Bit Binary to 7 Segment Hexadecimal Decoder

There are many Binary to 7 Segment Decoders out there, such as the CD4511, DM74LS47, SN7447 and the DM9368. All of which have attractive features, but none have all of them in one package. Another downside is many only display 0 - 9 with few displaying all Hexadecimal digits (0 - F). With many of these chips obsolete and hard to find, my 4 Bit Binary to 7 Segment Hexadecimal Decoder is a versatile substitute.

What Is It:

Although not a pin for pin replacement, this chip functions just like the DM9368 with a few added features. I have programmed a PIC16F628A to read a 4 Bit Binary Coded Decimal Number and display the Hexadecimal equivalent on a 7 Segment LED display.


4 Bit binary to 7 Segment Hexadecimal Decoder Breadboard


How it works:

The program begins at the SETUP routine where on power up it configures the microcontroller's inputs and outputs. The GETNUM routine reads the logic levels of PORTA (binary input) and ANDs this result with 0x0F (B'00001111) to mask the upper 4 bits. The result is the stored in a General Purpose Register called BINARYNUM.

Before moving on with processing the value in BINARYNUM, the TEST_DISP_SELECT routine calls the Lookup Table to obtain the 7 Segment Display configuration data. This is returned and stored in the General Purpose Register called DISPLAY_STORE. The second function of the TEST_DISP_SELECT routine is to established the type of display (Common Anode or Common Cathode) by reading the state of PORTB, 0. The data held in DISPLAY_STORE is for a Common Cathode display so if it is established that a Common Anode display is to be used the data within the DISPLAY_STORE register is inverted by using the COMF (Complement F) instruction.

The TEST_FOR_0 routine is used to establish if the binary value on the input lines is 0. If not, the program moves on to the NOT_ZERO_OR_NO_BLANK routine to send the digit to the display. After this the program moves onto the LATCH routine, but I'll come back to this.

If however the TEST_FOR_0 routine establishes the value on the input lines is 0, the program moves to the CHECK_BLANKING routine to accommodate for the Ripple Blanking function. When used in a multiple digit display these inputs and outputs can be linked in a chain with the left most digits Ripple Blanking Input being tied to ground. Effectively this function suppresses the display of leading 0's. For example 650 will be displayed as 650 instead of 0650 in a 4 digit display when the Ripple Blanking function is used. If Ripple Blanking is not required as determined by the CHECK_BLANKING routine the program moves to the NOT_ZERO_OR_NO_BLANK routine and sends the digit to the display. However if Ripple Blanking is enabled, the DISPLAY_STORE register that holds the 7 Segment Display configuration is overridden with a new configuration to blank the display. i.e., turn all segments of the 7 Segment LED Display off. Depending on which type of display is selected (Common Anode or Common Cathode) depends on whether the BLANK_IT routine sets or clears the display output lines.

The LATCH routine effectively puts the program into a small loop as long as the Latch input is held to ground. The routine also sets the Ripple Blanking Output for consistency with the DM9368 device.

And finally the TEST_LAMP routine. This routine loads the digit '8' into BINARYNUM and jumps straight to the TEST_DISP_SELECT to start the process of displaying a digit without reading the binary value on the input lines. Effectively lighting up every segment of the 7 Segment Display.

Depending on how the chip is configured and the digit on the input lines, the whole program takes roughly 50 instructions plus or minus a few. So if running at 4MHz, 1 loop of the program takes just 50uS, which is 20,000 times per second!

Source Code:

;                                                                                                  ;
;                        Program: 4 Bit Binary Coded Decimal to 7 Segment Hexadecimal Decoder                  ;
;                        Author: Jake Sutherland                                                   ;
;                        Start Date: Monday 19th April 2010                                        ;
;                        Finish Date:                                                              ;
;                        Comments: Revised March 2014                                              ;
;                                                                                                  ;
;                                                                                                  ;

        LIST            P=PIC16F628A
        INCLUDE         P16F628A.INC
        ERRORLEVEL      -302    ;Eliminate bank warning

;                                                                                                  ;
;                                   PIC16F628A Microcontroller                                     ;
;                                            ____ ____                                             ;
; Binary input Bit 2          VREF/AN2/RA2 -| 1  - 18 |- RA1/AN1                Binary input Bit 1 ;
; Binary input Bit 3    LED - CPM1/AN3/RA3 -| 2    17 |- RA0/AN0                Binary input Bit 0 ;
; Latch Enable              CMP2/T0CKI/RA4 -| 3    16 |- RA7/OSC1/CLKIN     Ripple Blanking Output ;
; Test Lamp Enable            VPP/MCLR/RA5 -| 4    15 |- RA6/OSC2/CLKOUT     Ripple Blanking Input ;
;                                      VSS -| 5    14 |- VDD                                       ;
; Common Anode/Common Cathode      INT/RB0 -| 6    13 |- RB7/T1OSC1/ICSPDAT              Segment B ;
; Segment C                      DT/RX/RB1 -| 7    12 |- RB6/T1OSCO/T1CLKI/ICSPCLK       Segment A ;
; Segment D                      CK/TX/RB2 -| 8    11 |- RB5                             Segment F ;
; Segment E                       CCP1/RB3 -|_9____10_|- RB4/PGM                         Segment G ;
;                                                                                                  ;
;                                                                                                  ;

BINARYNUM                               ; GPR used for storing Binary Input Digit
DISPLAY_STORE                           ; GPR used for Display Store 

        ORG     0x000                   ; Processor reset vector location. On power up, the program jumps here
        GOTO    SETUP                   ; 

        ORG     0x004                   ; Interrupt vector location. When an Interrupt occurs, the program jumps here
        GOTO    SETUP                   ; 

DISP_CONFIG ; This routine assigns on/off arrangement to the 7 Segment Display depending on the value in W register(common cathode) 
        ADDWF   PCL, F
        RETLW   B'11101110' ;0
        RETLW   B'10000010' ;1
        RETLW   B'11011100' ;2
        RETLW   B'11010110' ;3
        RETLW   B'10110010' ;4
        RETLW   B'01110110' ;5
        RETLW   B'01111110' ;6
        RETLW   B'11000010' ;7
        RETLW   B'11111110' ;8
        RETLW   B'11110110' ;9
        RETLW   B'11111010' ;A
        RETLW   B'00111110' ;B
        RETLW   B'01101100' ;C
        RETLW   B'10011110' ;D
        RETLW   B'01111100' ;E
        RETLW   B'01111000' ;F

SETUP  ; This routine sets up the chips Inputs and Outputs
        CLRF    PORTA                   ; Initialise PORT A by setting ouput data latches
        MOVLW   H'07'                   ; Turn Comparators off and enable pins for I/O functions
        MOVWF   CMCON                   ;
        BCF     STATUS, RP1             ; Bank 1
        BSF     STATUS, RP0             ; Bank 1
        MOVLW   B'01111111'             ; RA<7> Output, RA<6:0> Inputs.
        MOVWF   TRISA                   ;

        MOVLW   B'00000001'             ; RB<7:1> Outputs, RB<0> Input.
        MOVWF   TRISB                   ;

        BCF     STATUS, RP1             ; Bank 0
        BCF     STATUS, RP0             ; Bank 0

GETNUM  ; This routine is to obtain the binary number from PORTA  and store it in a general purpose register (temporary register)
        MOVF    PORTA, W                ; Move PORTA to W
        ANDLW   H'0F'                   ; Mask the upper nibble. This ensures upper nibble is always 0. Result stored back in W register.
        MOVWF   BINARYNUM               ; Move the value to General Purpose Register called BINARYNUM for use in future.

TEST_DISP_SELECT  ; This routine tests the Display Type Input pin (Common Cathode or Common Anode)
        CALL    DISP_CONFIG             ; Call DISP_CONFIG table to obtain 7 Segment Display settings.
        MOVWF   DISPLAY_STORE           ; Store 7 Segment Display settings in General Purpose Register called DISPLAY_STORE for use later.
        BTFSS   PORTB, 0                ; Test 'Display Type Input'
        COMF    DISPLAY_STORE, F        ; If input is 0, Common Anode Display required, therefore invert the 7 Segment Display settings for use with Common Anode Display.
        GOTO    TEST_FOR_0              ; If input is 1, Common Cathode Display required, leave DISPLAY_STORE as is and move on to the TEST_FOR_0 routine

TEST_FOR_0  ; This routine is to determine if a zero is displayed
        MOVF    BINARYNUM, W            ; Move the Binary Number to the working register
        XORLW   B'00000000'             ; Binary 00000000 is the number for '0'. By XOR'ing '00000000' with 'BINARYNUM', we can determine if 'BINARYNUM' is equal to zero by testing the 'zero' bit of the STATUS register
        BTFSS   STATUS, Z               ; Test 'zero' bit of STATUS register
        GOTO    NOT_ZERO_OR_NO_BLANK    ; Binary number in BINARYNUM is NOT '0', so we GOTO 'NOT_ZERO_OR_NO_BLANK' and display the number, as well as setting the Ripple Blanking Output (PORTA,7)

CHECK_BLANKING  ; If the input IS found to = '0', this routine checks the Ripple Blanking Input to determine whether to display the '0' or not (if not, it will clear the display)
        BTFSC   PORTA, 6                ; Test the 'Ripple Blanking Input'. Skip GOTO if clear
        GOTO    NOT_ZERO_OR_NO_BLANK    ; Ripple Blanking Input set so don't blank the number '0'

        BTFSC   PORTB, 0                ; Test 'Display Type Input'. If CC, execute next instruction. If CA skip next instruction
        MOVLW   H'00'                   ; 0x00 is to clear the display if a CC display is used
        BTFSS   PORTB, 0                ; ( Two 'BTFSC PORTB,0' statements prevents having to create another subroutine just to load 1 value with 1 instruction. It can be done like this)
        MOVLW   H'FF'                   ; 0xFF is to clear the display if a CA display is used
        MOVWF   PORTB                   ; 7 Segment display is connected to PORTB
        BCF     PORTA, 7                ; Clear Ripple Blanking Output
        GOTO    LATCH                   ; Test if Latch enabled

NOT_ZERO_OR_NO_BLANK  ; This routine is executed if the RBI is HIGH, therefore '0' is displayed
        MOVF    DISPLAY_STORE, W        ; Move the segment arrangement to the working register
        MOVWF   PORTB                   ; Move the W register to PORTB
        BSF     PORTA, 7                ; Set the Ripple Blanking Output
        GOTO    LATCH                   ; Test if Latch enabled

LATCH  ; This routine checks the LATCH. Active Low
        BTFSS   PORTA, 4                ; Test LATCH
        BSF     PORTA, 7                ; If LATCH enabled, set the Ripple Blanking Output. If LATCH disabled, skip
        BTFSS   PORTA, 4                ; Test LATCH
        GOTO    LATCH                   ; If LATCH enabled, GOTO LATCH and test again. If LATCH disabled, skip 

TEST_LAMP  ; This routine checks the TEST LAMP input
        BTFSC   PORTA, 5                ; Test input pin
        GOTO    GETNUM                  ; If set, Start again, test for Binary Number on PORTA
        MOVLW   H'08'                   ; If input clear, set all segments on LED display
        MOVWF   BINARYNUM               ; Move 11111111 to PORTB
        GOTO    TEST_DISP_SELECT        ; GOTO TEST_LAMP to check if pin state changed


.asm File Icon .hex File Icon


Digital Temperature Sensor Schematic

Parts List:

Part Quantity Schematic Designator
PIC16F628A Microcontroller 1 U1
LED 7 Segment (Common Cathode or Common Cathode) 1 D1
LED 1 D2
470Ω 7 R1 - R7
4.7KΩ 1 R15
10KΩ 8 R8 - R15
.1μF Multilayer Ceramic 1 C1
Breadboard 1  
Jumper Wire    
Switches SPST 4 S1 -S4
Power Requirements    
5 Volt DC Regulated, 100mAh