Hello all. I have been working with PIC microcontrollers for over 2
years now and I am familiar with and like them. However, recently I
have started dabbling with Atmel AVR microcontrollers to see what they
have to offer. Especially, since they seem quite popular these days and
are showing up in more open-source products. I have done some simple
flashing LED circuits with the ATmega8 and 48, and the ATtiny2313. I
have been using the demo version of BASCOM and have just been doing
simple one and two LED flashing circuits with very simple programs. The
programs all seem to work fine on each of the chips. I have noticed,
though, that the LEDs do not flash nearly as brightly with the AVR
chips as they do with the PIC chips. Is that something unique to AVR
chips, or is there some sort of pull-up resistor or other switch that
needs to be set to allow for more current to pass through the LED?
I don't know anything about the AVR vs PIC in this regard, but if the LED
is not as bright, it is because the AVR is not delivering as much current
as the PIC. The amount of current the outputs can source or sink can be
found in the spec sheets. A typical red or yellow LED is designed for
about 20 ma of current. But they will light up with much less (maybe 1 ma
- and it's common to drive them with 10 ma or less), and can draw a lot
more, maybe up to 1000 ma (1 A) before burning out. The more current you
push through it, the brighter it will get.
If you hook an LED straight to the output with no resistor, then the LED is
likely to draw as much current as the chip will produce. Whether this is
source current or sink current, is a function of whether the other side of
the LED is connected to ground (source current) or V+ (sink current). If
you check the electrical specs on the processor output you will find what
their current limits are and you will probably find the PIC controllers
have higher current limits (since you said the LED is brighter with the
I happen to have a spec sheet for a PIC18F6520/8520/8620/6720/8720. In
section 26.0 (electrical characteristics - page 309) which is the first
page of of the electrical specs, it lists the maximum output current sunk
by by any I/O pin as 25 ma, and the maximum output current sourced by any
I/O pin as 25 ma. It also lists 200 ma as the max of what all ports can
deliver at once (so don't hook up 10 LEDs and expect to draw 25 ma for each
at the same time).
Now, I don't know if this maximum is what the chip will typically do if you
short the output with an LED, or if it's simply the number you should
design around and be sure you never expect the chip to deliver more current
than this - but you can assume the chip will deliver at least that much.
If you connect the LED to the chip without a resistor to regulate the
current, there's a good chance you are pushing the chip past it's design
limits and it is likely to draw more.
What you should be doing is putting a resistor in series with the LED to
regulate the current so that it does exceed what the chip is designed to
deliver. You should calculate the resistor value to make it draw about 10
to 20 ma of current (assuming the AVR chips can deliver that). If you use
the correct resistor value for each processor, so it's drawing the correct
20 ma, then both processors should make the LED light up at the same level.
A typical resistor connected in series with an LED driven from a 5V signal
source would be 470 ohm resistor which will limit the current to below 10
ma, or 150 ohm which will limit it to around 20 ma.
If you are not currently using a resistor and just connecting the the LED
directly to the output pin, then you are simply forcing the the pin to
deliver as much current is it can at the forward voltage of the LED (about
2V) and it's quite likely that one chip will allow you to draw more current
than the other. This might in fact be quite safe with these processors (I
have no idea - don't blame me if you blow out a processor), but the safe
thing to do is use the resistor to make sure you limit the current to what
the processor is designed to deliver. And if the processor can't produce
the current you need, you must add driver circuits of some type.
Now, if you are using a development board, it's possible there might be a
resistor in series with the I/O pins to prevent a short from drawing too
much current. If the board(s) you are using does anything like that, then
that will certainly effect how bright an LED you connect to it will be.
If you have a meter, just connect it in series with the LED and see how
much current it is drawing when it's on. If the bright LED is drawing more
then 20 ma, you are probably pushing the LED past what it was designed to
do in the first place and risking harming your processor chip.
Now, another possibility, is that you have simply written your code wrong,
and the output pin is not being held constantly on for one reason or
another. It could just be flashing very quickly - which would make it look
dimer. If your code was constantly changing the mode of the pin from input
to output then something like that could happen. If you scan your eyes
from left to right quickly past the LED, you can sometimes see an after
trace of the image that looks like a dashed line instead of a sold line if
it's blinking. That trick won't work if it's blinking too fast however. I
noticed this effect in a LED car tail light on the road recently. It would
form the blinking light pattern for the dim mode, and go solid when the
brakes were on.
Of course there are three basic reasons why this could be happening.
1) you are sourcing current when you should be sinking it thru the AVR.
2) you are running a program that is blinking the LED at a rate that gives
the appearance of a dim light source.
3) you were using a PIC eval board that used a different sized resistor
and now your AVR eval kit us using a larger resistor to blink the onboard
Be sure and enable the I/O line as an "output". By default all I/O
lines are high impedance inputs and if you write a "1" bit to the I/O
line's position, that enables an internal pull-up resistor in the
chip. Thus if the LED lights at all it will be dim. To enable the
pin as an output, write a "1" to the pin's bit position in the DDR
register. For example if you are using PORTB and your LED is on
PORTB0, use (in C):
DDRB |= 0x01; /* I/O pin is output */
PORTB |= 0x01; /* turn on LED */
Another thing you might not be used to is when you want to sense the
pin's level, always read the PIN register, not the PORT register. The
AVR uses a seperate latch for input vs output so you can read what the
chip is driving the pin's output vs what is actually happening to the
pin in the case that it miht be driven to a different value by a
stronger current source. So so see what is actually on PORTB0 above,
you'd do this:
value = PINB & 0x01;
That may or may not match what you read if you read PORTB since the
pin could be being driven low even though you are trying to drive it
high with the 2nd statement above.