Summary:
Why does the LMV358P act as a pullup resistor on e.g. an Uno board?
Description:
I'm trying to understand the behaviour of the onboard led on an Uno. On a real Uno, the onboard led is on by default when the sketch starts running; on a SparkFun Redboard (and possibly a number of clones without the opamp) it's off.
I wrote a little test sketch to read the relevant registers using direct port manipulation to check what is happening.
void setup()
{
Serial.begin(57600);
delay(500);
Serial.println("after bootloader");
printPort(DDRB, PORTB, PINB);
}
void loop()
{
}
void printPort(byte dir, byte port, byte pin)
{
Serial.print("DDRB = "); Serial.println(dir, HEX);
Serial.print("PORTB = "); Serial.println(port, HEX);
Serial.print("PINB = "); Serial.println(pin, HEX);
Serial.print("Pin 13 = "); Serial.println((pin & 0x20) == 0x20 ? "HIGH" : "LOW");
Serial.println();
}
The result (below) clearly indicates that pin 13 is input, no internal pullup and reading the pin results in a HIGH.
after bootloader
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
To check for noise (on a floating input), I modified the above sketch to pick up any changes on PINB in loop()
void setup()
{
Serial.begin(57600);
delay(500);
Serial.println("after bootloader");
printPort(DDRB, PORTB, PINB);
Serial.println("starting loop()");
}
void loop()
{
static byte oldPinValue;
static bool firstRun = true;
byte dir = DDRB;
byte port = PORTB;
byte pin = PINB;
if (firstRun == true || oldPinValue != pin)
{
firstRun = false;
oldPinValue = pin;
printPort(dir, port, pin);
}
}
void printPort(byte dir, byte port, byte pin)
{
Serial.print("DDRB = "); Serial.println(dir, HEX);
Serial.print("PORTB = "); Serial.println(port, HEX);
Serial.print("PINB = "); Serial.println(pin, HEX);
Serial.print("Pin 13 = "); Serial.println((pin & 0x20) == 0x20 ? "HIGH" : "LOW");
Serial.println();
}
The sketch works as expected showing changes on pins when I touch the pins on the Uno board; the exception is pin 13 which is consistently high.
after bootloader
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
starting loop()
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 28
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 21
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 23
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 3F
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 3B
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 22
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 3F
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 3E
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 30
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 3F
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 22
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 26
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 24
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 22
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 24
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 24
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 24
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 24
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 2F
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 2F
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 2F
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 2F
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 2A
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 27
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 22
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 27
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 23
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 23
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 25
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 23
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 22
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 22
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 22
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 27
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 24
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 3F
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 3F
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 3F
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 3F
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 3E
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 3C
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 38
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 30
Pin 13 = HIGH
DDRB = 0
PORTB = 0
PINB = 20
Pin 13 = HIGH
So it looks like the LMV356 acts as a pullup resistor and the question is why? I looked at the schematic of the Uno as well as LMV358 datasheet but I have no idea which parameters and / or images will give this information in the datasheet; the block diagram in the datasheet is not much help (to me).
Any insight appreciated.
Note:
I'm not looking for a workaround; just understanding.