What is the correct way to connect resistors to a seven-segment common-anode display with a microcontroller? Where should I connect a resistor?

Here I am connecting a common anode display (common = +5 V). My circuit is shown below:

enter image description here

We have a 8052 variant AT89S52 connected to three seven-segment common-anode displays in multiplexed as shown.

  • Transistors Q1, Q2, and Q3 are used to connect +5 V to the seven segment display when they are switched ON.
  • Resistors R8, R10, and R12 are used to limit the current to the display.

Port 0 is used as a sink for the current into the microcontroller.

I have found another circuit for connecting seven-segment common-anode displays to a microcontroller (PIC) shown below.

In that one the seven resistors are connected to the seven-segment display after the display and the multiplexing transistors' collector are connected to the +5 V directly.

enter image description here

What is the best way to connect the seven segment display?

I wanted to reduce the components so I am connecting a single resistor between the transistor and +5 V to reduce the current.

Should I go to the second option where seven resistor are connected between the display and the microcontroller?

  • 2
    \$\begingroup\$ How would you connect 7 series resistors to 7 LEDs? Because that's basically what a 7 seg display is. \$\endgroup\$
    – Lundin
    Jan 2 at 14:16
  • 1
    \$\begingroup\$ As a side note, 100R from 5V sounds like much too high current, most board-mounted LEDs are rated for 20mA max. R = (5V - Vfwd) / 5mA is usually sufficient. \$\endgroup\$
    – Lundin
    Jan 2 at 14:18
  • \$\begingroup\$ So, it's been decades since I've played with 7-segment displays. Could OP's original schematic, (with a single common-anode series resistor) work sufficiently if the microcontroller only lit one segment at a time, with a high refresh rate (assuming the transistor switching is proper)? Wasn't that the strategy during days of yore? \$\endgroup\$ Jan 2 at 15:07
  • 1
    \$\begingroup\$ @ChrisKnudsen Yes, it's common practice to strobe between them, as it saves a lot of pins and resistors. But it limits how many digits you can use - if you have too many or are too slow, you'll see a flicker. Also, if the micro stops, then the display stops too. \$\endgroup\$
    – Smith
    Jan 2 at 15:25
  • \$\begingroup\$ Am I seeing things, or is the OP incorrect on common anode vs cathode? They say they are doing a common anode display, but their schematic has CC pins. \$\endgroup\$
    – Smith
    Jan 2 at 15:28

2 Answers 2


TLDR: Circuit #2 is correct.

It is incorrect to use current-limiting at the LED anode terminal as circuit #1 does, via R8, R10, R12. If you display a digit with many segments lit (like "8") then segments will be much dimmer, compared with a digit like "1" where only two segments are active - or even worse, where "." is displayed. Current limited by R8 is divided between many? of the seven segments.

Although the 7 x 100 resistors of circuit #2 add extra parts, these current-limiting resistors ensure that each of seven segments gets similar current, regardless of how many are active.

Be aware that the PNP transistors of circuit #2 are saturated switches.

Considering AT89S52 feeble output drive, one might wish to specify high-efficieny common-anode 7-segment LEDs. When digits are multiplexed, peak current escalates when more digits are added...even with high-efficiency LEDs, microcontroller current limits also limits number of digits that can be multiplexed, especially if the expected ambient lighting is bright.

Static current limit for this chip mean that PORT_0 is preferred for pulling LED digit cathodes to Vss:

  • PORT_0 static current limit: 26mA total (all 8 active)
  • PORT_1 static current limit: 15mA total (all 8 active)
  • PORT_2 static current limit: 15mA total (all 8 active)

Feeble drive current makes me reconsider Circuit #1 using EdC's suggestion in a good answer where pulse-width-modulates the ANODE drive transistors (Q1, Q2, Q3). By allowing more on-time for digits where more LEDs are active, current is limited (as per data sheet specs) while apparent digit brightness does not depend on which of 10 digits is displayed:

  • digit 0 drives 6 LEDs (3.29mA per LED)
  • digit 1 drives 2 LEDs (7.44mA per LED)
  • digit 2 drives 5 LEDs (3.81mA per LED)
  • digit 3 drives 5 LEDs (3.81mA per LED)
  • digit 4 drives 4 LEDs (4.54mA per LED)
  • digit 5 drives 5 LEDs (3.81mA per LED)
  • digit 6 drives 5 (or 6) LEDs (3.81mA or 3.29mA per LED)
  • digit 7 drives 3 LEDs (5.64mA per LED)
  • digit 8 drives 7 LEDs (2.58mA per LED)
  • digit 9 drives 5 (or 6) LEDs (3.81mA or 3.29mA per LED)
  • decimal point alone drives 1 LED (10.99mA)

A LTspice simulation of circuit #1 yielded LED current shown above. It was assumed that equivalent resistance of PORT_? drive was 75 ohms...data sheet suggested a maximum value of 140 ohms: Circuit #1 LTspice simulation schematic

It is assumed that each LED is exactly matched with the other 7 in each digit. The significant ON resistance of PORT_? drive makes LED matching less significant. Maximum port current is more in-line than Circuit #2. But the big question is: are digits bright enough?

One would assume that keeping current x time product constant should be the goal to maintain digit brightness constant...that's an extra lookup table. In this way, peak current required of microcontroller port outputs can be limited.
The LTspice run of circuit #1 suggests that when all eight LEDs are active (to display digit "8." ), you'd want to dally about three times longer than when two LEDs are active (to display digit "1").

Such wide variance in MUX display times wants slow display periods for each of three digits, yet fast enough to prevent flicker. For three digits, slowest MUXing rates would apply for a display of 8.88 or 88.8. If all three digits are refreshed 50 times-per-second, you'd want each of those 8's to be fully ON for about 6.66ms.
But a display of 111 would shorten the period while each digit is lit - 2.22ms for each of three digits. These three digits would be still be refreshed 50 times-per-second: each digit 2.22ms ON, and 4.44ms OFF. At least one microcontroller timer might be used to control ON/OFF times.

  • \$\begingroup\$ Note that Circuit 2 is using the micro to sink the current for 7 LEDs. With 100R resistors, that's a maximum of more than 200 mA. This is more than ten times what a single AT89S52 GPIO port can sink. \$\endgroup\$
    – Matt S
    Jan 2 at 16:33
  • 1
    \$\begingroup\$ @MattS Yes, AT89S52 has feeble drive. PORT_0 would be best to pull LED cathodes down to Vss. Under static conditions, PORT_0 is allowed maximum of 26mA. Multiplexed among three digits, more current might be allowed (not specified in the data sheet). PORT_1 and PORT_2 are even more feeble. An edit pending... \$\endgroup\$
    – glen_geek
    Jan 2 at 17:24
  • \$\begingroup\$ FWIW the drive is so feeble that even a single LED driven at 30 mA (or two LEDs at a more-typical 10 mA into ports 1 or 2) will exceed the ratings. And as an example of a "static condition" (in quotes because it's technically not static, but static-enough), displaying on a 7-seg using circuit 2 would require a limit current of less than 2 mA per segment. Even something more likely to occur in a real system, like 0000, will be pushing the limits of the chip at 2 mA. \$\endgroup\$
    – Matt S
    Jan 2 at 17:32
  • 1
    \$\begingroup\$ @MattS I agree that MUXing 4 digits (within I/O port current limits) would result in a very dim display. 3 digits might work for modern high-efficiency LED displays where 1mA (100% duty-cycle) is plenty bright. Meeting current-limit restrictions makes Circuit #1 (with PWM) more attractive but adds software complexity, and consumes a timer for PWM \$\endgroup\$
    – glen_geek
    Jan 2 at 18:55

Circuit 1 will result in equal segment intensities if you use pulse width modulation to ensure the average current through each segment remains the same. This requires less hardware but more software.

  • \$\begingroup\$ Would that also limit the maximum brightness of each segment to 1/8 of an individual segment's maximum brightness? \$\endgroup\$ Jan 2 at 16:36
  • \$\begingroup\$ @AndrewMorton You could use a smaller current limiting resistor and a fast PWM, which would provide an equivalent average current that provides a similar brightness. Just watch out for the possibility that your uC might lock up with one segment on (i.e. make sure your highest-priority interrupt has code to disable the display.) \$\endgroup\$
    – Matt S
    Jan 2 at 16:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.