user45082: I have an ADC that have sampling rate up to 40 MSPS, but i use 8 MHz clock so it will be 8 MSPS. The board used is arduino nano. The problem is i have to sampling it just 2 MHz (because the capacity of array variable in arduino Nano, which is around 10.000 elements in array variable). I know that using direct port reading will increase the speed of the digital read, but how can i set the direct port reading to just read every 0.5 us? Micros function cannot do the job of course
Thank you

user7508: Note: this is an attempt to answer the question as asked. This
answer is unlikely to be of any use to the original poster, who
presumably asked the wrong question. I am writing this only as a way to
explore the limits on how fast a modest AVR can sample a port. For an
answer that genuinely attempts to address the OP’s problem, see
Majenko’s answer.
I read the question as follows: can we sample a digital port at
2 MHz on an Arduino Nano clocked at 8 MHz? Can we do so while
storing the values in a RAM-based buffer?
The answer is yes, but it is non trivial, and it requires some assembly.
To see the problem, let’s start by trying to do it in C++:
uint8_t buffer[1024];

void fill_buffer()
{
    cli();
    for (size_t i = 0; i < sizeof buffer; i++)
        buffer[i] = PINB;
    sei();
}

Note that the loop runs with interrupts disabled, otherwise the timer
interrupt would wreak havoc with the loop timing. This is translated by
gcc into an assembly equivalent to this:
    cli
    ldi  r30, lo8(buffer)      ; load the buffer address into pointer Z
    ldi  r31, hi8(buffer)      ; ditto
0:  in   r24, 0x03             ; read the port
    st   Z+,  r24              ; store into buffer, increment the pointer
    ldi  r24, hi8(buffer+1024) ; save (buffer+1024)>>8 in r24
    cpi  r30, lo8(buffer+1024) ; compare the pointer with buffer+1024
    cpc  r31, r24              ; ditto
    brne 0b                    ; loop back
    sei
    ret

The loop takes 8 cycles per iteration. With an 8 MHz clock, that
would be one reading per microsecond. Too slow by a factor two.
One could save one cycle by using a different register for the port data
and for the end-of-loop condition, and by moving the third ldi out of
the loop. Another cycle could be saved by testing only the high byte of
the Z pointer, but that would require aligning the buffer to
256 byte boundaries. With those two optimizations, we still need
6 CPU cycles per iteration, i.e. 0.75 µs at 8 MHz.
In order to make this faster, the only solution is to unroll the loop.
This can be done in assembly by using the .rept (meaning “repeat”)
directive:
void fill_buffer()
{
    cli();
    asm volatile(
        ".rept %[count]\n"  // repeat (count) times:
        "in r0, %[pin]\n"   //   read the port input register
        "st Z+, r0\n"       //   store in RAM
        "nop\n"             //   1 cycle delay
        ".endr"
        ::      "z" (buffer),
        [count] "i" (sizeof buffer),
        [pin]   "I" (_SFR_IO_ADDR(PINB))
        : "r0"
    );
    sei();
}

This takes 4 cycles, or 0.5 µs per iteration. Note that a
delay cycle had to be introduced, otherwise the sampling would be too
fast : 3 cycles, or 0.375 µs, per iteration.
This is not the fastest one can get. It is possible to take one sample
per CPU cycle with something like this:
    in r0, 0x03
    in r1, 0x03
    in r2, 0x03
    ...

However this technique is limited to burst readings of at most
32 samples.

user4143: You need:

A timer
A board that is capable of running fast enough to do what you want.

The Nano fits the first criteria, but not the second.
At 16MHz you get a clock period of 63ns.  That means you get a mere 8 clock ticks (actually gives you 504ns) per interruption from the timer. That's at most 8 assembly instructions that can be executed within that time. 
Since an interrupt service routine's preamble is longer than 7 instructions you can see there would be a slight problem there.  No time for actually reading a digital IO port - and if you are using a serial protocol to communicate with your ADC you can multiply the reading time by the double the number of bits you need to read. That's a long time compared to 500ns.
So no. Think again. Use a more suitable board. Maybe an ARM based board (like the Teensy 3.x) would be a better fit.

45082: <p>I have an ADC that have sampling rate up to 40 MSPS, but i use 8 MHz clock so it will be 8 MSPS. The board used is arduino nano. The problem is i have to sampling it just 2 MHz (because the capacity of array variable in arduino Nano, which is around 10.000 elements in array variable). I know that using direct port reading will increase the speed of the digital read, but how can i set the direct port reading to just read every 0.5 us? Micros function cannot do the job of course</p>

<p>Thank you</p>
 7508: <p><strong>Note</strong>: this is an attempt to answer the question as asked. This
answer is unlikely to be of any use to the original poster, who
presumably asked the wrong question. I am writing this only as a way to
explore the limits on how fast a modest AVR can sample a port. For an
answer that genuinely attempts to address the OP’s problem, see
Majenko’s answer.</p>

<p>I read the question as follows: can we sample a digital port at
2&nbsp;MHz on an Arduino Nano clocked at 8&nbsp;MHz? Can we do so while
storing the values in a RAM-based buffer?</p>

<p>The answer is yes, but it is non trivial, and it requires some assembly.
To see the problem, let’s start by trying to do it in C++:</p>

<pre class="lang-c++ prettyprint-override"><code>uint8_t buffer[1024];

void fill_buffer()
{
    cli();
    for (size_t i = 0; i &lt; sizeof buffer; i++)
        buffer[i] = PINB;
    sei();
}
</code></pre>

<p>Note that the loop runs with interrupts disabled, otherwise the timer
interrupt would wreak havoc with the loop timing. This is translated by
gcc into an assembly equivalent to this:</p>

<pre class="lang-none prettyprint-override"><code>    cli
    ldi  r30, lo8(buffer)      ; load the buffer address into pointer Z
    ldi  r31, hi8(buffer)      ; ditto
0:  in   r24, 0x03             ; read the port
    st   Z+,  r24              ; store into buffer, increment the pointer
    ldi  r24, hi8(buffer+1024) ; save (buffer+1024)&gt;&gt;8 in r24
    cpi  r30, lo8(buffer+1024) ; compare the pointer with buffer+1024
    cpc  r31, r24              ; ditto
    brne 0b                    ; loop back
    sei
    ret
</code></pre>

<p>The loop takes 8 cycles per iteration. With an 8&nbsp;MHz clock, that
would be one reading per microsecond. Too slow by a factor two.</p>

<p>One could save one cycle by using a different register for the port data
and for the end-of-loop condition, and by moving the third <code>ldi</code> out of
the loop. Another cycle could be saved by testing only the high byte of
the Z pointer, but that would require aligning the buffer to
256&nbsp;byte boundaries. With those two optimizations, we still need
6&nbsp;CPU cycles per iteration, i.e. 0.75&nbsp;µs at 8&nbsp;MHz.</p>

<p>In order to make this faster, the only solution is to unroll the loop.
This can be done in assembly by using the <code>.rept</code> (meaning “repeat”)
directive:</p>

<pre class="lang-c++ prettyprint-override"><code>void fill_buffer()
{
    cli();
    asm volatile(
        ".rept %[count]\n"  // repeat (count) times:
        "in r0, %[pin]\n"   //   read the port input register
        "st Z+, r0\n"       //   store in RAM
        "nop\n"             //   1 cycle delay
        ".endr"
        ::      "z" (buffer),
        [count] "i" (sizeof buffer),
        [pin]   "I" (_SFR_IO_ADDR(PINB))
        : "r0"
    );
    sei();
}
</code></pre>

<p>This takes 4&nbsp;cycles, or 0.5&nbsp;µs per iteration. Note that a
delay cycle had to be introduced, otherwise the sampling would be too
fast : 3&nbsp;cycles, or 0.375&nbsp;µs, per iteration.</p>

<p>This is not the fastest one can get. It is possible to take one sample
per CPU cycle with something like this:</p>

<pre class="lang-none prettyprint-override"><code>    in r0, 0x03
    in r1, 0x03
    in r2, 0x03
    ...
</code></pre>

<p>However this technique is limited to burst readings of at most
32&nbsp;samples.</p>
 4143: <p>You need:</p>

<ol>
<li>A timer</li>
<li>A board that is capable of running fast enough to do what you want.</li>
</ol>

<p>The Nano fits the first criteria, but not the second.</p>

<p>At 16MHz you get a clock period of 63ns.  That means you get a mere 8 clock ticks (actually gives you 504ns) per interruption from the timer. That's <em>at most</em> 8 assembly instructions that can be executed within that time. </p>

<p>Since an interrupt service routine's preamble is longer than 7 instructions you can see there would be a slight problem there.  No time for actually reading a digital IO port - and if you are using a serial protocol to communicate with your ADC you can multiply the reading time by the double the number of bits you need to read. That's a <em>long</em> time compared to 500ns.</p>

<p>So no. Think again. Use a more suitable board. Maybe an ARM based board (like the Teensy 3.x) would be a better fit.</p>
