NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Microcontroller Programming » Weak PORTC output on Atmega168

March 14, 2012
by Mujda
Mujda's Avatar

I am using an Atmega168 at 3.3V & 4MHz ext XTAL. I am using some C Port pins as outputs, but for some strange reason, some of the pins are functioning as very weak drivers - so weak that they cannot overcome an external 10k pulldown resistor.

PC3 is working fine and is providing a high or low when requested into a 10k or 2.2k pull up/down resistor. Pins PC2 and PC5 provide a high/low when requested if nothing is connected, but as soon any load is taken the voltage drops at high state drops enormously e.g. 2.2k resistor to 0V pulls the high output to 0.2V. It's behaving like there's a v.large series resistance at the port pin. There are no short circuits at the output pin.

The ports are configured identically by:

// Setup Port C                  DDR PORTC
//   6 - Reset, input             0    0
//   5 - SHT15_1, SDA, output     1    0 (only initially output)
//   4 - SHT15_1, SCK, output     1    0 (no pullup needed)
//   3 - SHT15_0, SDA, output     1    0 (only initially output)
//   2 - SHT15_0, SCK, output     1    0 (no pullup needed)
//   1 - ANALOG1, input           0    0
//   0 - ANALOG0, input           0    0
//
DDRC  = 0b00111100;
PORTC = 0b00000000;

Any thoughts why PC3 behaves but PC2 & 5 might not?

March 14, 2012
by hevans
(NerdKits Staff)

hevans's Avatar

Hi Mujda,

It is possible to damage the output stage on your chip, did you at some point connect something backwards or short something on your setup?

It is also possible there is a short in your breadboard. Try moving it up to a different spot and see if that changes things.

Humberto

March 14, 2012
by Mujda
Mujda's Avatar

Like you suggest, I was wondering if it was damaged in some way, although I've found the Atmega168 extremely resilient to accidental abuse. It has it's own internal protection against overload, and even then the datasheet says it can source up to 40mA. The m/c is sitting in a chip socket on prototype board, and if I remove it I get infinite resistance to all adjacent pins, 0V & Vdd (no shorts) and a good connection to the external connection terminal. This terminal feeds to breadboard which has nothing on it apart from a resistor to Vdd or 0V on no connections at all.

I had another thought. Could the pins in question somehow be remaining as inputs, and by writing to PORTC it will turn on and off the internal pullup resistor (instead of the pin itself) so it will give a v.weak high/low?

There is a whole stack of code (almost 14k's worth when uploaded), but this new bit of code is v.near the top. Could enabling ADC flip the ADC0-5 ports to input? or could SPI enabling cause the pins to flip to input?

March 15, 2012
by hevans
(NerdKits Staff)

hevans's Avatar

Hi Mujda,

Have you tried isolating the problem. Upload a small piece of code that does nothing else except turn these pins high, and see if they can do it against a load.

Humberto

February 24, 2013
by Blackwatch42nd
Blackwatch42nd's Avatar

Humberto,

I'm having a similar problem. I've set PC3 pin to input and PC4 to output (drives a single LED depending on the state of PC3).

Here's the set up

    DDRC |= (1<<PC4);   // configure PC4 to be output
    DDRC &= ~(1<<PC3);  // configure PC3 to be input (default bu makeing sure)
    PORTC |= (1<<PC3);  // configure PC3 pull-up resistor to high
//  PORTC &= ~(1<<PC3); // configure PC3 pull-up resistor to low

If I set PC3 pull up high, with nothing attached to PC3 (floating), the LED lights as designed. If PC3 is grounded the light goes out. fine right? Well if I set PC3 pull down resistor (as in the commented line above ( I do comment out the "high" command line above it)) the LED cycles on and off about once a second when PC3 is allowed to float. If grounded the LED goes out, if 5v applied it stays on.

Basicly, I'm trying to detect a logic high at the pin with no other logic involved. Am I doing something wrong (maybe screwed up the chip)? let me if you need more info.

John

February 24, 2013
by Noter
Noter's Avatar

Not sure what you are talking about, there is no pulldown resistor, only a pullup and only when the pin is configured for input. Also the pin is not floating if the pullup is enabled, it's at VCC via the pullup. If configured for input and no pullup then the pin can float. If you haven't read the chapter on I/O pins in the ATmega168/328 datasheet now would be a good time.

February 24, 2013
by Blackwatch42nd
Blackwatch42nd's Avatar

I've read the Atmega maunal till I'm blue in the face, it's like reading Gaelic. Must have read into it what I wanted. And when i said "floating" I mean nothing externally connected to it. So it appears I've read the manual wrong and the pin can only be held at a high state or an uncertain state if not set to high. Is there any way to detect a logic high as an input without first inverting the input signal?

February 24, 2013
by Noter
Noter's Avatar

That's correct, when configured for input the pin is either pulled high by the internal pullup resistor which reads as a 1 or it is floating and could be either a 1 or 0. So if you want the pin to be a 0 and then go to 1 by some external switch you will have to leave the pullup disabled and put an external resistor from the pin to GND (1K to 10K) to hold it at 0 (the pulldown) until a switch or some other source puts enough voltage on the pin pulling it up so it will read as a 1. It's easier just to use the pullup and have your switch go to GND which would read 1 as off or open and 0 as on and write your software accordingly.

February 25, 2013
by Blackwatch42nd
Blackwatch42nd's Avatar

Thanx Noter,

Got it now. I was confused by the phrase "tri-state" thinking it could be set to high, low or float internally. If we let it float (PORTxn &= ~(1<<Pxn)), can we then use an external pull up resistor as well? In other words, if I don't want it set high internally, then Pxn can be set high using an external pull up or if I want it low use a external pull down?

BTW: I'm trying to understand the difference between the PUD(MCUCR) and the DDxn ways of setting the pull-ups. It looks like the PUD is all pins of all ports pulled up or all floating and then this can be over-riden by individual DDxn. Correct?

Thanx again

John

February 25, 2013
by Noter
Noter's Avatar

Tri-state consists of the two output states, high and low, and the input state also called the high impedance state. Pullups don't change the input state from high impedance, they are just there for convenience. You don't have to use them, you can add external pullups if you wish.

The PUD bit overrides the DDXn settings and disables all of the pullups if it is set. I have never used it and can't think of a good reason to use it. Normally when a pin is unused I set it to input with the pullup enabled just so it won't float because when an input port floats it will consume more power as it crosses back and fourth over the threshold voltage that switches the state between 0 an 1. It's not a lot of power but if you're on batteries every little bit counts. The only exception is unused ADC or AIN inputs because digital input can be completely disabled on them using the DIDRn registers.

Post a Reply

Please log in to post a reply.

Did you know that the printf format string "%.3f" will show three digits after the decimal point? Learn more...