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.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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#Chip16F1829,8'############################################################################ConfigCP=On'Read protected'###########################################################################;-----DefineHardwaresettings;Allportsettings,likeinandout,arehandledwithintheSevenSegmentdriver.;-----Constants;Youneedtospecifytheportsettings#Define7Seg_CommonAnode'Pic Disp#defineDISP_SEG_APORTc.3'7 7#defineDISP_SEG_BPORTc.4'6 6#defineDISP_SEG_CPORTc.5'5 4#defineDISP_SEG_DPORTa.4'3 2#defineDISP_SEG_EPORTa.5'2 1#defineDISP_SEG_FPORTc.6'8 9#defineDISP_SEG_GPORTc.7'9 10#defineDisp1PwrPORTa.0'19 3,8 use series 47R resistor#defineDisp2PwrPORTa.1'18 3,8 use series 47R resistor#defineDisp3PwrPORTa.2'17 3,8 use series 47R resistor#defineDisp4PwrPORTc.0'16 3,8 use series 47R resistor#defineDisp5PwrPORTc.1'15 3,8 use series 47R resistor#DefineDispOff0#DefineDispOn1#DefineDisplayTime3500'uS increasing this improves brightness but may cause flicker#DefineLoopTime15DirDisp1PwrOutDirDisp2PwrOutDirDisp3PwrOutDirDisp4PwrOutDirDisp5PwrOut;-----VariablesDimMessage(30)'defines a stringMessage()="SevensegmentdisplayV1a“'End with five spaces ' 1234567890123456789012345678901234567890DimMessageLenAsByteDimLoopCntAsWordLetMessageLen=30'Length of message + 1LetDispMessage=1LetDisp1Pwr=DispOffLetDisp2Pwr=DispOffLetDisp3Pwr=DispOffLetDisp4Pwr=DispOffLetDisp5Pwr=DispOff;-----MainbodyofprogramcommenceshereMain:ForLoopCnt=0toLoopTimeLetDisp1Pwr=DispOffLetDisp2Pwr=DispOffLetDisp3Pwr=DispOffLetDisp4Pwr=DispOffLetDisp5Pwr=DispOnIfDispMessage<MessageLenThenDisplayChar1,Message(DispMessage)ElseDisplayChar1," "EndIfWaitDisplayTimeuSLetDisp1Pwr=DispOffLetDisp2Pwr=DispOffLetDisp3Pwr=DispOffLetDisp4Pwr=DispOnLetDisp5Pwr=DispOffIfDispMessage>1ThenDisplayChar1,Message(DispMessage-1)ElseDisplayChar1," "EndIfWaitDisplayTimeuSLetDisp1Pwr=DispOffLetDisp2Pwr=DispOffLetDisp3Pwr=DispOnLetDisp4Pwr=DispOffLetDisp5Pwr=DispOffIfDispMessage>2ThenDisplayChar1,Message(DispMessage-2)ElseDisplayChar1," "EndIfWaitDisplayTimeuSLetDisp1Pwr=DispOffLetDisp2Pwr=DispOnLetDisp3Pwr=DispOffLetDisp4Pwr=DispOffLetDisp5Pwr=DispOffIfDispMessage>3ThenDisplayChar1,Message(DispMessage-3)ElseDisplayChar1," "EndIfWaitDisplayTimeuSLetDisp1Pwr=DispOnLetDisp2Pwr=DispOffLetDisp3Pwr=DispOffLetDisp4Pwr=DispOffLetDisp5Pwr=DispOffIfDispMessage>4ThenDisplayChar1,Message(DispMessage-4)ElseDisplayChar1," "EndIfWaitDisplayTimeuSNextLetDispMessage=DispMessage+1IfDispMessage>MessageLenThenLetDispMessage=1EndIfGotoMain
Last edit: mkstevo 2016-05-28
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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#Chip16F1829,8'I've had this running at 32MHz perfectly well, with no delays in the ShiftOut Subroutine either'############################################################################ConfigCP=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.TableNumeralsasByte192'0249'1164'2176'3153'4146'5130'6248'7 128'8 144'9 EndTable'To display a decimal point by a character, deduct 128 from value shown.TableAlphabetAsByte136'A131'b167'c161'd134'E142'F194'G139'h207'I241'j137'K199'L200'M171'n163'o140'p152'q175'r146'S135't227'u193'V193'W137'X145'y164'ZEndTable'Pic 74HC595 #defineD_DataPORTa.5'2 14 (of right-most display,viewed from display front)#defineD_ClkPORTa.4'3 11'4 In Only#defineD_LatPORTc.5'5 12#defineD_EnaPORTc.4'6 13 Low to Enable#DefineD_ResetPORTc.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.DirD_ResetOutDirD_EnaOutDirD_LatOutDirD_ClkOutDirD_DataOutDimDatAsByteDimDigitAsByteDimTableLenAsByteLetD_Reset=0'Hold in resetLetD_Ena=1'Hold with enable OFFLetD_Lat=0LetD_Clk=0LetD_Data=0Main:PrintNumeralsPrintAlphabetGotoMainSubPrintAlphabetLetD_Reset=1'Release resetLetD_Ena=0'Enable OnReadTableAlphabet,0,TableLenForDat=1ToTableLenReadTableAlphabet,Dat,DigitLetD_Lat=0'Start output data latch ShiftOut(Digit)LetD_Lat=1'End output data latchWait500mSNextDatLetD_Reset=0'Hold in resetLetD_Ena=1'Hold with enable OFF Wait1000mSEndSubSubPrintNumeralsLetD_Reset=1'Release resetLetD_Ena=0'Enable OnReadTableNumerals,0,TableLenForDat=1ToTableLenReadTableNumerals,Dat,DigitLetD_Lat=0'Start output data latch ShiftOut(Digit)LetD_Lat=1'End output data latchWait500mSNextDatLetD_Reset=0'Hold in resetLetD_Ena=1'Hold with enable OFF Wait1000mSEndSubSubShiftOut(DataOutasByte)ForClocks=1to8LetD_Clk=0'Shift register clockedWait10uS'These delays are only here to allow me to see them on the oscilloscope.LetD_Data=DataOut.7LetD_Clk=1Wait10uS'These delays are only here to allow me to see them on the oscilloscope.RotateDataOutLeftSimpleNextClocksEndSub
Last edit: mkstevo 2016-05-28
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
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.
Last edit: 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.
Last edit: mkstevo 2016-05-28