direct port writing: value changes but LED doesn't

I've made a simple modification to the blink program in order to verify operation by writing the port directly. I've printed the port byte and it changes, the the LED never comes on. Using DDRB & DDRD to set ports up had no effect. I'm missing something obvious. The digitalWrite() works. Suggestions appreciated.

// Blink, with direct port changing

int led = 13;      // Pin 13 has an LED connected on most Arduino boards.

// the setup routine runs once when you press reset:
void setup() {
  Serial.begin(9600);      // open the serial port at 9600 bps:    
  pinMode(led, OUTPUT);    // initialize the digital pin as an output. 
  Serial.println();        // get to a new line in the monitor
}

void loop() {
  //  digitalWrite(led, HIGH);   // turn the LED on   (THIS WORKS)
  PORTB |= B00100000 ;        //     (DOESN'T WORK)
  delay(300);  

  //  digitalWrite(led, LOW);   // turn the LED off 
  PORTB &= B11011111 ;  //  
  delay(700);
}

Works fine on my Arduino Duemilanove.

Which board are you using?

PORTD &= ~(1 << n); // Pin n goes low
PORTD |= (1 << n); // Pin n goes high

Worked for me OK.

(edit) On my Uno.

I'm using the Mega 2560. Thanks for the comments. I'll try a different output.

Better look up the schematic. It's probably not PORTD bit 5 then.

Why do you even want to do this?

Why?
This is a much larger project controlling multiple high-speed valves, ethernet data, etc, and I want to minimize latency and write ports simultaneously. This is extracted to the bare minimum. I tried adding another ext LED to another pin of PORTB. Still doesn't work unless I do the following:

PORTB = B11111111;
later
PORTB = 0;

works, and enables both LEDs as expected (pin 11, 13 in this instance).
Any other value to PORTB turns on neither. (B00111111 for instance).

Try looking up digitalwritefast:

http://code.google.com/p/digitalwritefast/

That has optimized code for fast outputting if you supply constants as the pin numbers.

As for the pins, look at:

Pin 13 (do you mean the chip or the Arduino Mega2560?) is not on PORTB.

On the Mega R3, the pin 13 LED is bit 7 of Port B.

(edit to add picture)

ninetreesdesign:
PORTB = B11111111;
later
PORTB = 0;

Off topic..... where did the "B01111111" notation come from? I've never seen this before in C programming. I do it as "0b01111111".

I also noticed that there is a header file specifically to translate all the possible "Bxxxxxxxx" patterns into "0bxxxxxxxx". Why not just do it right in the first place?

I finally sorted this out. The arduino Uno and the mega2560 define the "arduino Dxx" the same, but the boards do not control the same output pins with the same processor port pins; the Mega uses some of PORTB and some of PORTH to control D8-D13. Therefore controlling bits on PORTD would fail though digitalWrite() would work. See schematic snippets. Now that I know what's going on, I know what to do. Thanks for the comments. I learned several things from them.

atmega2560 D8-D9.JPG

uno D8-D13.jpg

ninetreesdesign:
I finally sorted this out. The arduino Uno and the mega2560 define the "arduino Dxx" the same, but the boards do not control the same output pins with the same processor port pins; the Mega uses some of PORTB and some of PORTH to control D8-D13. Therefore controlling bits on PORTD would fail though digitalWrite() would work. See schematic snippets. Now that I know what's going on, I know what to do. Thanks for the comments. I learned several things from them.

If you are going to do direct port manipulations on I/O pins and I/O port registers the below linked worksheet can be useful as an aid to show the pin mapping used for 168/328 based chips Vs 1280/2560 based chips. The first column shows the arduino software 'abstracted' pin number and the other columns will show the actual port/bit number it is associated with. Note that this worksheet does not attempt to show the physical package pin number for either chip family.

https://spreadsheets.google.com/pub?key=rtHw_R6eVL140KS9_G8GPkA&gid=0

Lefty