Pages: [1]   Go Down
Author Topic: Arduino Due - 13MHz Square Wave Trigger  (Read 1252 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi all,
I' am planning to use Arduino Due as a 13MHz square wave trigger for trigging requirements of our laboratory.
I found these I/O Characteristics table from processors datasheet.
It seems I am able to use it up to 65 MHz, but I am in doubt about the frequency jitter parameters. Did anyone use Arduino Due as a high frequency generator before? If its so and if you have the waveforms, could you share it?
Thank you.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 8
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The highest I have done was generating a square wave running at 4kHz with 50% duty cycle. I will post the website I got the code from. Although since the processor runs at 16MHz this may be the limit to your maximum frequency.

http://www.instructables.com/id/Arduino-Timer-Interrupts/

Best of luck!
Logged

0
Offline Offline
Shannon Member
****
Karma: 160
Posts: 10416
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This is a question about the Due, an ARM based Arduino clocked at 84MHz.

Since 13MHz is not a simple harmonic relationship to 84MHz you will
get loads and loads of jitter I think (or are their some funky high-performance
PLLs hidden away in this beast - I'm still digesting the datasheet in small
portions!).   12MHz yes, that's 84 / 7....

The synchronous serial interface does allow external clocking though, so an external
13MHz oscillator might be the way to go (with careful reading of that section of the datasheet).
I think it can pass external clocks through without adding jitter, as its designed to handle I2S
amongst other things.
Logged

[ I won't respond to messages, use the forum please ]

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You can produce a 21MHz square wave with the 84MHz clock using direct port manipulation.  To stretch out the pulses, add an assembly language NOP statement (no operation).  Using one for each high and low state will give you a little over 14 MHz.  The challenge is that you need a fast loop to repeat it.  I would use assembler to do that.

This is rough code that toggles all the B ports at ~14MHz, except for the extra time of the while loop
Code:
int led = 13;
void setup() {
  pinMode(led, OUTPUT); // turn on one pin so we can monitor it with a scope
}

void loop() {
  while (1){
    REG_PIOB_ODSR = 0xFFFFFFFF; // 23.8nsec (2 clocks)
    asm volatile("nop\n\t"::);  // 11.9nsec (1 clock)
    REG_PIOB_ODSR = 0x0;       
    asm volatile("nop\n\t"::); 
    REG_PIOB_ODSR = 0xFFFFFFFF;
    asm volatile("nop\n\t"::);
    REG_PIOB_ODSR = 0x0;       
    //asm volatile("nop\n\t"::); replace with assembler jump, otherwise stays low for 132nsec (11 clocks)
  }
}

Using Atmel Studio to develop code fragments will let you see the disassembled version and copy the code.   There might be a way to see the assembly output in the Arduino environment.  Make sure that you disable interrupts as well. 

For longer delays or stringing together other assembly statements, concatenate them like this
Code:
    asm volatile("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t"::);
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You can adjust the clock if you use Atmel Studio.  See sample code in my recent posting "Changing the system clock frequency on an Arduino Due ".  We are working in the same area.

Note that an Arduino Uno uses a 16MHz clock directly.  It responds to direct port commands in one clock cycle for 62.5nsec resolution.  You could unsolder the crystal (or unplug the DIP) and clock it directly off your 13MHz source.  That way you wouldn't get into issues with setup/hold times when your clocks are not sync'd
Code:
    DDRD = DDRD | B11111000;  // sets pins 3 to 7 as outputs
    // Generate a 62.5nsec wide pulse at max speed
    PORTD = B00011000; // sets digital pins 3,4 HIGH
    PORTD = B00000000; // sets digital pins 3-7 LOW
Logged

Pages: [1]   Go Up
Jump to: