Go Down

Topic: Arduino Due - 13MHz Square Wave Trigger (Read 3895 times) previous topic - next topic


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.


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.


Best of luck!


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.
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]


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: [Select]
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"::); 
    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: [Select]
    asm volatile("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t"::);


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: [Select]
    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

Go Up