Low level Port Manipulation is not working

I am trying to make this work. I expect to turn pin number 4 high. I am using ATMEga 2560. I intend to use low level programming not digital write. I can upload the sketch but the output is OFF. Can you help me. Please and Thanks

void setup() {

DDRD |= (1 << 4);

}

void loop() {

PORTD |= (1 << 4);

}

You need to study the datasheet and a pinout diagram more closely. In principle what you're trying to do is just fine except pins 4, 5 and 6 on PORTD are not exposed on the mega2560.

D4 is in port PG

There is the digitalWriteFast libray that gets speed near the speed of direct port manipulation with the more familiar digitalWrite syntax.

Thank you. The pinout diagram helped. I am thinking of trying to use digitalWriteFast. Which is faster? PORTD |= (1 << PG5) or digitalWriteFast(4, HIGH)?

They should be exactly the same speed in the example you asked about. The library contains some macros which translate the digitalWriteFast() functions into port manipulation commands, where this can be done, as the sketch is compiled.

But not all digitalWriteFast() functions can be converted into port manipulation functions so easilly. For example

digitalWriteFast(myPinArray[i], myValue);

probably cannot be converted and will revert to digitalWrite().

Why not try the Arduino "bit" macros, you could write:

bitSet(DDRD,4); // pin 4 is OUTPUT
bitSet(PORTD,4); // pin 4 is HIGH 
bitClear(PORTD,4); // pin 4 is LOW

The 'bit' macros get transcribed by the pre-processor into the same shift operation.

So, bitSet(PORTG, 5); is the same as PORTG |= (1 << PG5) and takes 2 clks. You don't get faster than that.

Please note, mega pin D4 is PORTG pin5 (or PG5), not PORTD pin PG5.

DKWatson:
So, bitSet(PORTG, 5); is the same as PORTG |= (1 << PG5) and takes 2 clks.

So setting bit 5 takes two clock cycles? That's interesting. Does the ATmega CPU have a barrel shifter, or something similar?

PaulRB:
So setting bit 5 takes two clock cycles? That's interesting. Does the ATmega CPU have a barrel shifter, or something similar?

Don't know. Just get my data from timing functions and an analysis of the compiled code. GCC is remarkably efficient in some aspects.

Is it possible to write macros for rotates and arithmetic shifts? I'm not familiar enough with the AVR instruction set.

PaulRB:
So setting bit 5 takes two clock cycles? That's interesting. Does the ATmega CPU have a barrel shifter, or something similar?

The shift is by a constant amount so it can be calculated at compile time.

oqibidipo:
The shift is by a constant amount so it can be calculated at compile time.

I agree. My question is how that is achieved at run time in 2 cycles instead of 5+ cycles.

1. The following codes are compiled, uploaded, and provide expected result (blink L) in MEGA Board.

void setup()
{
  DDRB = (1<<7); // or DDRB |= (1 << 7); PB7 = DPin-13 in MEGA Board 
}

void loop() {

  PORTB = (1 << 7);
  delay(2000);
  PORTB = (0 << 7);
  delay(2000);
}

2. The following are compiled, uploaded; but, does not provide expected result (L does not blink) in MEGA Board.

void setup()
{
  DDRB |= (1 << 7); //or DDRB = (1<<7) PB7 = DPin-13 in MEGA 
}

void loop() {

  PORTB |= (1 << 7);
  delay(2000);
  PORTB |= (0 << 7);
  delay(2000);
}

3. Reference Example from ATmega2560 data sheets in favor of Step-1.
mega.png

Remarks: OP and Post#7 have referenced the codes of Step-2. Are they correct when compared with data sheet codes of Step-3?

mega.png

outsider:
Is it possible to write macros for rotates and arithmetic shifts? I'm not familiar enough with the AVR instruction set.

Byte rotates
#define ROR(x) ((x >> 1) | ((x & 1) << 7))
#define ROL(x) (!!(x & 128) | (x << 1))

I'll look into the arithmetic shift.

So setting bit 5 takes two clock cycles? That's interesting. Does the ATmega CPU have a barrel shifter, or something similar
My question is how that is achieved at run time in 2 cycles instead of 5+ cycles.

There is no barrel shifter (and in fact something like "var << shiftcount" creates a painfully slow loop.)

PORTB |= (1<<5);

is compiled into a singleinstruction:

   sbi PORTB, 5

(compiler optimization essentially "un-shifts" the argument in the C statement.)
Converting a binary number to a single-bit bitmask is much easier than barrel shifting - a job for a "decoder" circuit. Here's the internal logic diagram for a 7442, which does 4 bits to 10 outputs:


(but you can do it with just a bunch of diodes...)

Can somebody tell me why this doesn't seem to move lsb into carry?

#define ROR(x)  __asm__ __volatile__ (" ror %0 \n\t" :"=r" (x) : "0" (x));

When looped with x starting at 128, output is,

128
64
32
16
8
4
2
1
0
0
.
.
.

Answered by westfw in AVRfreaks,

Carry isn't defined in C, and thus not guaranteed to survive between iterations of a loop (and certainly not if there is a "print" in there!)...

For verification, I just ran

prt(x);
ROR(x);
ROR(x);
prt(x);

with x starting at 1 and got

1

128

So the macro does work.

For those reading this with question marks in their eyes, I get tired typing Serial.println(x) all the time so a simple macro,
#define prt(x)  Serial.println(x)solves that.