I have a PCB in front of me now, with the following circuit on it:

enter image description here

Despite looking fairly easy, this doesn't work as it should. After delving into some info about 8051 ports, I started to suspect that, despite measuring 4.9 Volts on the outputs, ports are actually not sourcing current, they are sinking. Then I saw this (page 138):

8051 Microcontrollers: Hardware, Software and Applications

Image from book: . M. Calcutt,Frederick J. Cowan,G. Hassan Parchizadeh

Here, the author claims he is doing what I am trying to do. Is he right or wrong? Could this be done with the right choice of resistors? Or can this only be done with an PNP?

  • 5
    \$\begingroup\$ I did a quick Google search, and the 8051 seems to be able to source 60 μA (Edit: Seems to differ between different versions.). If your NPN gets only 60 μA on the base, and has a gain of 100, that's only 6 mA on the collector. Enough to make a LED glow, but hardly enough to drive a motor. So my guess is that you need more gain. You can start out by looking into Darlington transistors and/or MOSFETs. \$\endgroup\$ – Dampmaskin Mar 13 '17 at 11:58
  • 1
    \$\begingroup\$ Although 8051 ports cannot source much current, they can usually sink a few milliamps. So, the trick with 8051's is to use a pull-up resistor to 5V on the output pin of the processor. Try 1k. \$\endgroup\$ – Steve G Mar 13 '17 at 12:05
  • 1
    \$\begingroup\$ Yes I think your problem come from your Res, they are too big ! \$\endgroup\$ – Tagadac Mar 13 '17 at 14:37
  • 1
    \$\begingroup\$ If you just want to light an LED, you can probably get rid of the transistor entirely. 1.6k series resistor from +5V to LED to port pin. Drive pin low to light LED, which will put about 1.6 mA through it which should be clearly visible on almost any LED, and even reasonably bright if a high-efficiency red LED is used. \$\endgroup\$ – pericynthion Mar 13 '17 at 22:38
  • 1
    \$\begingroup\$ ...alternatively, use a microcontroller that's not the best part of four decades old! \$\endgroup\$ – pericynthion Mar 13 '17 at 22:39

I quickly looked at the datasheet for the AT89C51CC03 (page 7 and 8 of this). It reveals port 3 has indeed a sinking output, and there is a weak pull-up which explains your voltage reading. If you want to wire that as you have it, use port 0, which has a push-pull output.

  • \$\begingroup\$ Thanks for your answer, while not being an expert of this field, it says that Port 2 also has internal pull-ups, are we sure they can be considered as push pull outputs? \$\endgroup\$ – C K Mar 13 '17 at 12:15
  • \$\begingroup\$ No sorry, I meant port 0 only. I didn't notice on page 9 that port 2 is similar to ports 1,3,4. \$\endgroup\$ – AngeloQ Mar 13 '17 at 12:20
  • \$\begingroup\$ If you want to keep it wired to port 3, I suggest you change the transistor to a PNP arrangement. \$\endgroup\$ – AngeloQ Mar 13 '17 at 15:22
  • \$\begingroup\$ The high-side drivers on port 0 of a "classic" 8051 are only usable under certain conditions such as during a MOVX instruction--not a scenario that is likely to offer much benefit. \$\endgroup\$ – supercat Mar 13 '17 at 21:01
suspect ... not sourcing current, they are sinking

Don't guess or go by heresay, READ THE DATASHEET. That will tell you outright how much current particular port pins can source.

Most likely, most port pins can source some current. It doesn't take much current to be amplified by a transistor to drive a LED, so even for a rather weak current source capability, the circuit you show should work.

We can even work backwards and find what the port has to source to turn on the LED fully. Let's say the up arrow goes to 5 V. The LED is red, so figure it drops 1.8 V or so. Account another 200 mV for the saturated transistor, and that leaves 3 V across the 2 kΩ resistor. That means the LED current is (3 V)/(2 kΩ) = 1.5 mA. Let's say the transistor can be counted on to have a gain of 50. That means 30 µA of base current would be needed to turn on the LED.

With the 5 kΩ resistor there, the circuit will actually draw 520 µA when the digital output is at 3.3 V. Most digital outputs can do that if they are set up to source current at all, but again, read the datasheet (do you see the recurring theme here?).

Your second schematic shows a motor, which likely needs much more current than the LED. A single transistor may not have enough gain to take the small digital output source current and allow enough current to drive the motor with. There are various options to deal with this, like using a low-voltage FET, or a second bipolar transistor. However, that would be the topic of a different question.


Here is a way to use low state current sink capability of a digital output instead of its high state current source capability. This also shows how to use two transistors to get lots of current amplification to be able to drive higher current loads:

In this example, the digital output only has to sink about a milliamp. When the digital output goes low, it drives about 1 mA thru the base of Q1. With the part values shown, that drives about 24 mA thru the base of Q2. This means Q1 needs to have a gain of at least 24, which is easily found in many small signal PNP transistors. The gain of Q2 allows it to switch load currents up to around 700 mA, which is enough to drive small motors.

Note also that the load doesn't have to be powered from the 3.3 V supply. The TIP41 transistor shown can handle up to 40 V. If the load is even partially inductive, there should be a reverse diode across it to give the inductive kickback current a path to flow that doesn't require frying the transistor.

  • \$\begingroup\$ Thank you for your answer, Olin. My suspicions actually arose when I checked the datasheet, and it says that the port's output current on logic 1 is "-10 microamperes to -60 microamperes". Since this is the first time I have seen such a thing, I could not be straight sure. So, does your answer still apply for these negative currents? \$\endgroup\$ – C K Mar 13 '17 at 12:26
  • \$\begingroup\$ @Cetin: Check what direction negative actually means in that context. In any case, you care about the sourcing capability (current going out of the pin) when the pin is high. Perhaps you saw a spec related to the protection clamp circuit. Only a few 10s of uA would be very weak for a digital output, assuming it has a active high state (not open drain or a passive pullup). \$\endgroup\$ – Olin Lathrop Mar 13 '17 at 13:16
  • \$\begingroup\$ Not being so much knowledgeable about output types, if what you mean as "passive pullup output" is the output between a pullup resistor and drain, the schematics from the datasheet looks like it: atmel.com/Images/doc4182.pdf If that is the case, is there something I could do to switch the transistor on? \$\endgroup\$ – C K Mar 13 '17 at 13:42
  • \$\begingroup\$ @Cetin: That link was for a whole microcontroller, not something about digital outputs. Some micros have or allow you to configure digital outputs to be open drain. Some have resistive pullups that can be enabled. You could always invert the logic in the micro and have driving the port low turn on a PNP transistor. Than can turn on a NPN for even more current capability, at may be required to run a motor. \$\endgroup\$ – Olin Lathrop Mar 13 '17 at 15:04
  • \$\begingroup\$ I sent you the datasheet for you to confirm if the port 3 output is a "passive pullup" type. \$\endgroup\$ – C K Mar 13 '17 at 15:11

Original 8051 port pins are pseudo-bidirectional- they can't source hardly any current steady-state- only briefly at switching. Apparently the various authors of a book on 8051s (and anyone they might have sent their manuscript for review) knows very little about 8051 hardware. Sad! See this answer for the gory details.

You can use a 2N7000 instead of the BJT and leave out the 'base' resistor.


I will give a practical answer. I made a circuit similar to yours, where I used bd139 bjt transistor(I have this one) and measured the current drawn from the base. If I use a 470 ohm resistor, it draws 2-2.5 mA, which is too much for your 8051 if it cannot provide more than 500-600uA. To make it draw less, I connected a higher value resistor to the base, like 20-30K, and then the current drawn is around 50-100 uA which should be fine. I even connected 1 Mohm where it reduced the base current to 2 uA but then it ruined the current of emitter-collecter side, so I used a higher value resistor around 20-30k or higher until it worked.

But also it is strange I did project with 8051 at89 (don't remember the rest) and connected 8 LEDs with a resistor directly to GPIO pins and it was working.


This could work if a very high gain transistor or a darlington transistor was used. Using a port pin that has strong internal pullups or push-pull stages (might need explicit software configuration in some models of 8051), OR using an external pullup, is the more sound solution here.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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