Fastest output possible

I need an output to test a clock circuit on a machine preferably 16MHz but since the Arduino clock is that speed I know that is not possible. However since it is for testing I will take the fastest I can get. I know that pwm works by taking the clock speed and dividing it by a multiplier 1,2,4,etc and counting 0-254 but that is too slow. I chose the simplest code I could think of...

void setup(){
  DDRA = B00000001;
}

void loop(){
  PORTA = B00000001;
  PORTA = B00000000;}

thinking that since it is only 2 lines that I would have a clock speed of 8 MHz However my scope shows 1 MHz. Is this because I am using the Arduino Mega? Is there a way to make an output faster?

You may be able to get 16Mhz by connecting the clock output (XTAL2) to a cmos inverter and then use its output for your project.

.

I don't know if it is any faster, or if the compiler makes it all the same in the end, but you can use the avr special write sequence to PINX to toggle a pin or pins.

void setup(){
  DDRA = B00000001;
}

void loop(){
  //PORTA = B00000001;
 // PORTA = B00000000;
PINA = 1;}

Since that pin is not accessible, It would mean soldering it to a proto-type board on top of an arduino Uno.Not sure where I could access it on my Mega. I could try that but would a 3" lead to the inverter affect the frequency? If at all possible I would like to use the internal output by using better code that I could think of. But I will try it. And I have never heard of PINX could you give an example?

void setup() {
 //sketch written for port/pin architecture of Arduino Uno atmega 328
 //blink led
  DDRB = B00100000; //set pin 13, led to output (PORTB, pin5)
}

void loop() {

 PINB = B00100000;
 
 delay(200);
}

That ended up slower 531.9KHz

On the Uno this will output 8 MHz on pin 9:

void setup ()
  {
  // set up 8 MHz timer on pin 9
  pinMode (9, OUTPUT); 
  // set up Timer 1
  TCCR1A = bit (COM1A0);  // toggle OC1A on Compare Match
  TCCR1B = bit (WGM12) | bit (CS10);   // CTC, no prescaling
  OCR1A =  0;       // output every cycle
  }  // end of setup

void loop () { }

For the Mega2560 it is pin 11:

void setup ()
  {
  // set up 8 MHz timer on pin 11
  pinMode (11, OUTPUT); 
  // set up Timer 1
  TCCR1A = bit (COM1A0);  // toggle OC1A on Compare Match
  TCCR1B = bit (WGM12) | bit (CS10);   // CTC, no prescaling
  OCR1A =  0;       // output every cycle
  }  // end of setup

void loop () { }
 PORTA = B00000001;

PORTA = B00000000;




thinking that since it is only 2 lines that I would have a clock speed of 8 MHz However my scope shows 1 MHz. Is this because I am using the Arduino Mega? Is there a way to make an output faster?

That is a lot more than 2 cycles.

Loop is doing this (cycle counts in brackets):

0000012c <loop>:
 12c:   81 e0           ldi     r24, 0x01       ; 1   (1)
 12e:   82 b9           out     0x02, r24       ; 2   (1)
 130:   12 b8           out     0x02, r1        ; 2   (1)
 132:   08 95           ret   (4)

7 cycles there.

And to call loop takes more cycles in main:

 144:   f3 df           rcall   .-26            ; 0x12c <loop>   (3)
 146:   20 97           sbiw    r28, 0x00       ; 0   (2)
 148:   e9 f3           breq    .-6             ; 0x144 <main+0xe>   (1/2)
 14a:   0e 94 00 00     call    0       ; 0x0 <__vectors>   (4)
 14e:   fa cf           rjmp    .-12            ; 0x144 <main+0xe>   (2)

9 cycles there.

Total of 16 cycles. Thus your 1 MHz output. (And the duty cycle would not be 50%).

PINA = B00000001;

Nick--Why is this slower than the two line PORTA code?

I need an output to test a clock circuit on a machine preferably 16MHz but since the Arduino clock is that speed I know that is not possible.

Of course it is. Enable the Clock output on PORTE7 fuse.

Never mind. That pin is not brought out to a header. (Unless you want to try your hand soldering an itty bitty wire.)

cattledog:

PINA = B00000001;

Nick--Why is this slower than the two line PORTA code?

In the set/clear scenario, the overhead of calling loop is spread over one cycle. In other words:

set pin / clear pin ... then 9 cycles overhead.

In the toggle scenario, the overhead of calling loop is doubled (one cycle is a set or clear). Thus you effectively have 18 cycles of overhead rather than 9.

With the PINA = 1 method loop is actually slightly shorter:

000000ac <loop>:
  ac:   80 e2           ldi     r24, 0x20       ; 32   (1)
  ae:   83 b9           out     0x03, r24       ; 3   (1)
  b0:   08 95           ret   (4)

So one "cycle" is going to be (9 + 6) * 2 = 30 clock cycles.

 1 / (1/16e6 * 30) = 533333 Hz

notfet:
That ended up slower 531.9KHz

Pretty close to the prediction. :slight_smile:

What is a lot faster is to do this:

 while (true)
   PINB = bit (5);

That gets you up to 2.6 MHz.

  ac:   80 e2           ldi     r24, 0x20       ; 32   (1)
  ae:   83 b9           out     0x03, r24       ; 3   (1)
  b0:   fe cf           rjmp    .-4             ; 0xae <loop+0x2>   (2)

Theory ... time taken to do the 3 cycles in that loop (twice):

 1 / (1/16e6 * 6) = 2666666 Hz

The hardware timer is still faster, of course.

If you have an ISP programmer or second arduino (to run arduinoasisp) you could set the CLKO fuse (low fuse for '328(p) would be 0xBF if using external 16mhz crystal) and get the system clock output on arduino pin 8 (physical pin 14, PB0).

DrAzzy:
low fuse for '328(p) ... and get the system clock output on arduino pin 8 (physical pin 14, PB0).

Wrong processor. See original post and reply #9.

Oops - somehow I managed to miss that...

Nick your explanation is clear I see how my example was 1 MHz and after loading your code The scope is 8 MHz. :slight_smile: :slight_smile: I still may try the soldering method unless there is something faster. But as per post#1 this may be the fastest software I can expect.

That pin can be available if you build/breadboard your own duino.