Menu

Seven Segment LED multiplexing

mkstevo
2016-05-28
2016-05-28
  • mkstevo

    mkstevo - 2016-05-28

    I recently had a need for creating a four digit, seven segment LED display. Whilst I found a few examples of single digit displays I couldn't find anything that used multiple segments. I wrote two versions and thought I'd share them. They are almost certainly a long way from perfect, but should be useable and may offer a starting point for something better.

     
  • mkstevo

    mkstevo - 2016-05-28

    This version uses the LED seven segment library, the segments of all five of the displays are connected in parallel, with the anodes being connected to separate ports on the PIC device through a series resistor. As the displays are multiplexed rapidly in sequence the brightness of the displays is reduced, to compensate, I fitted a low value of series resistor, just 47R. The brightness could be increased by increasing the constant 'DisplayTime' or removing any displays which might not be needed. If the DisplayTime is increased too much, the display may start to flicker objectionally.

    '''A demonstration program for GCGB and GCB.
    '''--------------------------------------------------------------------------------------------------------------------------------
    '''This program will display a message using 5 x 7 Segment displays.
    '''The 7 Segment displays are connected to PortC.0-6 for segments A-G respectively.
    '''@author  EvanV plus works of HughC
    '''@licence GPL
    '''@version 1.0a
    '''@date    31.01.2015
    '''********************************************************************************
    
    '''Multiplexing demonstration by mkstevo 28th May 2016
    
    'Pic 16F1829 5 way 7 Segment LED Display
    
    #Chip 16F1829, 8
    
    '###########################################################################
    #Config CP=On
    'Read protected
    '###########################################################################
    
    ; ----- Define Hardware settings
      ; All port settings, like in and out, are handled within the Seven Segment driver.
    
    ; ----- Constants
      ; You need to specify the port settings 
    
      #Define 7Seg_CommonAnode   'Pic   Disp
      #define DISP_SEG_A PORTc.3 '7     7
      #define DISP_SEG_B PORTc.4 '6     6
      #define DISP_SEG_C PORTc.5 '5     4
      #define DISP_SEG_D PORTa.4 '3     2
      #define DISP_SEG_E PORTa.5 '2     1
      #define DISP_SEG_F PORTc.6 '8     9
      #define DISP_SEG_G PORTc.7 '9     10
    
      #define Disp1Pwr PORTa.0   '19    3,8 use series 47R resistor
      #define Disp2Pwr PORTa.1   '18    3,8 use series 47R resistor
      #define Disp3Pwr PORTa.2   '17    3,8 use series 47R resistor
      #define Disp4Pwr PORTc.0   '16    3,8 use series 47R resistor
      #define Disp5Pwr PORTc.1   '15    3,8 use series 47R resistor
      #Define DispOff 0
      #Define DispOn  1
      #Define DisplayTime 3500 'uS increasing this improves brightness but may cause flicker
    
      #Define LoopTime 15
      Dir Disp1Pwr Out
      Dir Disp2Pwr Out
      Dir Disp3Pwr Out
      Dir Disp4Pwr Out  
      Dir Disp5Pwr Out
    
    ; ----- Variables
      Dim Message(30)                             'defines a string
      Message() = "Seven segment display V1a     'End with five spaces 
      '            1234567890123456789012345678901234567890
    
      Dim MessageLen As Byte 
      Dim LoopCnt As Word
      Let MessageLen = 30 'Length of message + 1
      Let DispMessage = 1
      Let Disp1Pwr=DispOff
      Let Disp2Pwr=DispOff
      Let Disp3Pwr=DispOff
      Let Disp4Pwr=DispOff  
      Let Disp5Pwr=DispOff
    
    ; ----- Main body of program commences here
    
      Main:
        For LoopCnt = 0 to LoopTime
          Let Disp1Pwr=DispOff
          Let Disp2Pwr=DispOff
          Let Disp3Pwr=DispOff
          Let Disp4Pwr=DispOff
          Let Disp5Pwr=DispOn
          If DispMessage < MessageLen Then
             DisplayChar 1, Message(DispMessage)
          Else 
             DisplayChar 1," "
          End If 
          Wait DisplayTime uS
          Let Disp1Pwr=DispOff
          Let Disp2Pwr=DispOff
          Let Disp3Pwr=DispOff
          Let Disp4Pwr=DispOn
          Let Disp5Pwr=DispOff
          If DispMessage > 1 Then
             DisplayChar 1, Message(DispMessage-1)
          Else 
             DisplayChar 1," "    
          End If 
          Wait DisplayTime uS 
          Let Disp1Pwr=DispOff
          Let Disp2Pwr=DispOff
          Let Disp3Pwr=DispOn
          Let Disp4Pwr=DispOff
          Let Disp5Pwr=DispOff
          If DispMessage > 2 Then
             DisplayChar 1, Message(DispMessage-2)
          Else 
             DisplayChar 1," "    
          End If 
          Wait DisplayTime uS
          Let Disp1Pwr=DispOff
          Let Disp2Pwr=DispOn
          Let Disp3Pwr=DispOff
          Let Disp4Pwr=DispOff
          Let Disp5Pwr=DispOff
          If DispMessage > 3 Then
             DisplayChar 1, Message(DispMessage-3)
          Else 
             DisplayChar 1," "    
          End If 
          Wait DisplayTime uS
          Let Disp1Pwr=DispOn
          Let Disp2Pwr=DispOff
          Let Disp3Pwr=DispOff
          Let Disp4Pwr=DispOff
          Let Disp5Pwr=DispOff
          If DispMessage > 4 Then
             DisplayChar 1, Message(DispMessage-4)
          Else 
             DisplayChar 1," "    
          End If 
          Wait DisplayTime uS
        Next
        Let DispMessage = DispMessage + 1
        If DispMessage > MessageLen Then
           Let DispMessage = 1
        End If
      Goto Main
    
     

    Last edit: mkstevo 2016-05-28
  • mkstevo

    mkstevo - 2016-05-28

    This version gives much better and brighter displays, but requires the use of one 74HC595 for each display. The displays are 'static' in as much as once the displays have been updated the displays continue to display the information on them, without needing continual refreshment as the multiplexed example above does. This was my primary reason for moving away from the multiplexed version. This example has the 'Enable' and 'Reset' pins of the 74HC595 connected to the PIC. If this isn't needed, these can be tied to 0V (Gnd for the Enable pin) and 5V (Supply for the Reset pin). The 'D_Clk' and 'D_Lat' (and if used 'D_Ena' and 'D_Reset') are all connected in parallel, the 'D_Data' (pin 14) of the right-most display 74HC595 is connected to the PIC pin 2, with pin 9 of this connecting to the next 74HC595 to the left pin 14 and so on down the line.

    'Pic 16F1829 4 way 7 Segment LED Display Using 4x74HC595 Example
    'Prints all numerals 0-9 then alphabet A-Z - mkstevo 28th May 2016
    #Chip 16F1829, 8
    'I've had this running at 32MHz perfectly well, with no delays in the ShiftOut Subroutine either
    
    '###########################################################################
    #Config CP=On
    'Read protected
    '###########################################################################
    
    'This uses common Anode seven segment displays the Anode is
    'connected to 5V with a 470R resistor, the decimal point
    'is connected to the 74HC595 with a 470R resistor.
    
    'The segments are connected to the 74HC595 with the display
    'pin ‘a’ being connected to 74HC595 pin ‘a’, ‘b’ - ‘b’ etc.
    
    '  aaa
    ' f    b
    ' f    b
    '  ggg
    ' e   c
    ' e   c
    '  ddd
    '      p
    
    '0=Element On
    'pgfedcba
    '11000000 '0
    '11111001 '1
    '10100100 '2
    '10110000 '3
    '10011001 '4
    '10010010 '5
    '10000010 '6
    '11111000 '7
    '10000000 '8
    '10010000 '9
    '
    
    'To display a decimal point by a character, deduct 128 from value shown.
    
    Table Numerals as Byte
        192   '0
        249   '1
        164   '2
        176   '3
        153   '4
        146   '5
        130   '6
        248   '7 
        128   '8 
        144   '9 
    End Table
    
    'To display a decimal point by a character, deduct 128 from value shown.
    
    Table Alphabet As Byte
        136 'A
        131 'b
        167 'c
        161 'd
        134 'E
        142 'F
        194 'G
        139 'h
        207 'I
        241 'j
        137 'K
        199 'L
        200 'M
        171 'n
        163 'o
        140 'p
        152 'q
        175 'r
        146 'S
        135 't
        227 'u
        193 'V
        193 'W
        137 'X
        145 'y
        164 'Z
    End Table
    
                                                                'Pic   74HC595 
      #define D_Data  PORTa.5    '2     14 (of right-most display,viewed from display front)
      #define D_Clk   PORTa.4    '3     11
                                 '4 In Only
      #define D_Lat   PORTc.5    '5     12
    
      #define D_Ena   PORTc.4    '6     13 Low to Enable
      #Define D_Reset PORTc.3    '7     10 High to Reset
    
    'Connect Pin 9 of right-most 74HC595 to pin 14 of next left 74HC595
    'then 9 - 14 to the next left, 9 - 14 to the next left etc.
    
      Dir D_Reset Out
      Dir D_Ena   Out
      Dir D_Lat   Out
      Dir D_Clk   Out  
      Dir D_Data  Out
    
      Dim Dat As Byte
      Dim Digit As Byte
      Dim TableLen As Byte
      Let D_Reset = 0  'Hold in reset
      Let D_Ena   = 1  'Hold with enable OFF
      Let D_Lat   = 0
      Let D_Clk   = 0  
      Let D_Data  = 0
    
    Main:
      PrintNumerals
      PrintAlphabet
    Goto Main
    
    Sub PrintAlphabet
      Let D_Reset = 1                 'Release reset
      Let D_Ena  = 0                  'Enable On
      ReadTable Alphabet, 0, TableLen
      For Dat = 1 To TableLen 
        ReadTable Alphabet, Dat, Digit 
        Let D_Lat  = 0                'Start output data latch  
        ShiftOut(Digit)
        Let D_Lat  = 1                'End output data latch
        Wait 500 mS
      Next Dat
      Let D_Reset = 0                 'Hold in reset
      Let D_Ena   = 1                 'Hold with enable OFF 
      Wait 1000 mS
    End Sub
    
    Sub PrintNumerals
      Let D_Reset = 1                 'Release reset
      Let D_Ena  = 0                  'Enable On
      ReadTable Numerals, 0, TableLen
      For Dat = 1 To TableLen
        ReadTable Numerals, Dat, Digit 
        Let D_Lat  = 0                'Start output data latch  
        ShiftOut(Digit)
        Let D_Lat  = 1                'End output data latch
        Wait 500 mS
      Next Dat
      Let D_Reset = 0                 'Hold in reset
      Let D_Ena   = 1                 'Hold with enable OFF 
      Wait 1000 mS
    End Sub
    
    Sub ShiftOut (DataOut as Byte)
        For Clocks = 1 to 8
          Let D_Clk = 0            'Shift register clocked
          Wait 10 uS               'These delays are only here to allow me to see them on the oscilloscope.
          Let D_Data = DataOut.7
          Let D_Clk = 1
          Wait 10 uS               'These delays are only here to allow me to see them on the oscilloscope.
          Rotate DataOut Left Simple
        Next Clocks                          
    End Sub
    
     

    Last edit: mkstevo 2016-05-28

Log in to post a comment.