user38271: I am new to Arduino and I have recently started off by trying to turn on an LED connected to pin 13 on my Arduino Uno using pointers. 
I opted to do this with pointers because this would give me a better understanding on what really goes behind when I use predefined Arduino functions.
My simple code looks like this,
uint8_t *data = (uint8_t *) 0x05; //PortB data register ptr (Since pin 13 is PB6) 
uint8_t *dir = (uint8_t *) 0x04;  //PortB dir register ptr (Since pin 13 is PB6)

void setup() {
    *dir = 0x40;  //PB6 direction set to O/P
    *data = 0x40; //PB6 data set to 1 to turn on the LED
}

void loop() {
  *data = 0x40;
}

I tried the same program using   pinMode(13, OUTPUT) and digitalWrite(13, LOW) functions and it works fine. But I do not understand what could be wrong with my pointers. If you find anything wrong, kindly let me know.

user368: Port definitions in AVR-Libc are done via black magic. Don't attempt to replicate them as a beginner. That being said...
"How do I pass an IO port as a parameter to a function?"
volatile uint8_t *data = &PORTB;
volatile uint8_t *dir = &DDRB;


user7508: You made two small mistakes:

The addresses of the I/O registers are 0x24 for DDRB and 0x25
for PORTB. The numbers you used are I/O port numbers, but since
pointers are supposed to point to memory, you have to use the
memory-mapped addresses instead.
Pin 13 is PB5, not PB6.

With these two mistakes fixed, your code works as expected. There are
still two issues however:

Under some circumstances, the compiler can optimize away some writes
to these registers. You have to qualify the pointers as “pointer to
volatile data” in order to avoid this. Even if your simple example
does not show this problem, it is always safer to use the qualifier.
The compiler generates inefficient code. Not as inefficient as
digitalWrite(), but still... It knows how to optimize, but it is
prevented to do so by the fact that your pointers are modifiable. You
should qualify them as const if you want to benefit from compiler
optimizations.

With those fixes, your pointer definitions would look like:
volatile uint8_t * const data = (uint8_t *) 0x25;
volatile uint8_t * const dir  = (uint8_t *) 0x24;

and access to them gets compiled into efficient in ans out assembly
instructions.
That being said, if you want to do direct port access, I would recommend
doing it the avr-libc way:
void setup() {
    DDRB  = _BV(PB5);
    PORTB = _BV(PB5);
}

void loop() {
    PORTB = _BV(PB5);
}

The way the AVR-libc defines the I/O registers is roughly equivalent to
#define PORTB (* (volatile uint8_t *) 0x25)


38271: <p>I am new to Arduino and I have recently started off by trying to turn on an LED connected to pin 13 on my Arduino Uno using pointers. </p>

<p>I opted to do this with pointers because this would give me a better understanding on what really goes behind when I use predefined Arduino functions.</p>

<p>My simple code looks like this,</p>

<pre class="lang-c++ prettyprint-override"><code>uint8_t *data = (uint8_t *) 0x05; //PortB data register ptr (Since pin 13 is PB6) 
uint8_t *dir = (uint8_t *) 0x04;  //PortB dir register ptr (Since pin 13 is PB6)

void setup() {
    *dir = 0x40;  //PB6 direction set to O/P
    *data = 0x40; //PB6 data set to 1 to turn on the LED
}

void loop() {
  *data = 0x40;
}
</code></pre>

<p>I tried the same program using   pinMode(13, OUTPUT) and digitalWrite(13, LOW) functions and it works fine. But I do not understand what could be wrong with my pointers. If you find anything wrong, kindly let me know.</p>
 368: <p>Port definitions in AVR-Libc are done via <a href="http://www.nongnu.org/avr-libc/user-manual/group__avr__sfr__notes.html" rel="nofollow noreferrer">black magic</a>. Don't attempt to replicate them as a beginner. That being said...</p>

<p><a href="http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_port_pass" rel="nofollow noreferrer">"How do I pass an IO port as a parameter to a function?"</a></p>

<pre><code>volatile uint8_t *data = &amp;PORTB;
volatile uint8_t *dir = &amp;DDRB;
</code></pre>
 7508: <p>You made two small mistakes:</p>

<ol>
<li>The addresses of the I/O registers are <code>0x24</code> for <code>DDRB</code> and <code>0x25</code>
for <code>PORTB</code>. The numbers you used are I/O port numbers, but since
pointers are supposed to point to memory, you have to use the
memory-mapped addresses instead.</li>
<li>Pin 13 is <code>PB5</code>, not <code>PB6</code>.</li>
</ol>

<p>With these two mistakes fixed, your code works as expected. There are
still two issues however:</p>

<ol>
<li>Under some circumstances, the compiler can optimize away some writes
to these registers. You have to qualify the pointers as “pointer to
<code>volatile</code> data” in order to avoid this. Even if your simple example
does not show this problem, it is always safer to use the qualifier.</li>
<li>The compiler generates inefficient code. Not as inefficient as
<code>digitalWrite()</code>, but still... It knows how to optimize, but it is
prevented to do so by the fact that your pointers are modifiable. You
should qualify them as <code>const</code> if you want to benefit from compiler
optimizations.</li>
</ol>

<p>With those fixes, your pointer definitions would look like:</p>

<pre><code>volatile uint8_t * const data = (uint8_t *) 0x25;
volatile uint8_t * const dir  = (uint8_t *) 0x24;
</code></pre>

<p>and access to them gets compiled into efficient <code>in</code> ans <code>out</code> assembly
instructions.</p>

<p>That being said, if you want to do direct port access, I would recommend
doing it the avr-libc way:</p>

<pre><code>void setup() {
    DDRB  = _BV(PB5);
    PORTB = _BV(PB5);
}

void loop() {
    PORTB = _BV(PB5);
}
</code></pre>

<p>The way the AVR-libc defines the I/O registers is roughly equivalent to</p>

<pre><code>#define PORTB (* (volatile uint8_t *) 0x25)
</code></pre>
