Go Down

Topic: Using external clock generator instead of Arduino Uno's internal clock? (Read 2 times) previous topic - next topic

csnsc14320

I was wondering if anyone knew of a way to "replace" the Arduino Uno's internal 16MHz cock with an external clock generator. We have a CG635 (http://www.thinksrs.com/products/CG635.htm) and would like to run the Arduino off of this clock instead of the internal clock. We will be running the CG at 10MHz.

Is there any simple way to do this?

retrolefty

#1
Jun 21, 2011, 07:03 pm Last Edit: Jun 21, 2011, 07:06 pm by retrolefty Reason: 1

I was wondering if anyone knew of a way to "replace" the Arduino Uno's internal 16MHz cock with an external clock generator. We have a CG635 (http://www.thinksrs.com/products/CG635.htm) and would like to run the Arduino off of this clock instead of the internal clock. We will be running the CG at 10MHz.

Is there any simple way to do this?


First the 16Mhz clock source for a arduino is external not internal, it's setup to utilize an external 16Mhz crystal or ceramic resonator.

Second, yes the chip can be setup to utilize an external TTL voltage level clock as the clock source. Section 6.8 of the 328p datasheet covers this. Note that as well as disconnecting the existing crystal one needs to change the fuse settings for the chip per the datasheet. Changing default fuse settings can not be done from within the Arduino IDE software, but would require a proper chip programmer, software and procedure steps.

Lefty

csnsc14320


First the 16Mhz clock source for a arduino is external not internal, it's setup to utilize an external 16Mhz crystal or ceramic resonator.

Second, yes the chip can be setup to utilize an external TTL voltage level clock as the clock source. Section 6.8 of the 328p datasheet covers this. Note that as well as disconnecting the existing crystal one needs to change the fuse settings for the chip per the datasheet. Changing default fuse settings can not be done from within the Arduino IDE software, but would require a proper chip programmer, software and procedure steps.

Lefty


This datasheet? http://www.atmel.com/dyn/resources/prod_documents/doc8161.pdf
There doesn't seem to be a section 6.8 on this? =\

Is there any way to do this without removing the Arduino's crystal? I thought I saw someone try to do this using the attachInterrupt command, but I have never used that and am not sure how that would work.

If I do need to remove the crystal and change the fuse settings, how difficult is that to come by?

Thanks for the quick response  :)

johnwasser

Note that your millis() clock will run at the wrong rate unless the system clock is 16MHz or 8MHz, EVEN IF YOU SPECIFY THE NEW CLOCK FREQUENCY.

In that version of the data sheet you want section 8: System Clock and Clock Options
Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

retrolefty

#4
Jun 21, 2011, 07:31 pm Last Edit: Jun 21, 2011, 07:35 pm by retrolefty Reason: 1
This datasheet? http://www.atmel.com/dyn/resources/prod_documents/doc8161.pdf
There doesn't seem to be a section 6.8 on this? =\

Section 8.8 (page 34) of that version of the datasheet.

Is there any way to do this without removing the Arduino's crystal? I thought I saw someone try to do this using the attachInterrupt command, but I have never used that and am not sure how that would work.

attachInterrupt (or interrupts in general) has nothing to do with setup of the processors clock source.


If I do need to remove the crystal and change the fuse settings, how difficult is that to come by?

Not something easy to do for a beginner. As I said changing fuse settings requires hardware and software not built into the arduino board or the arduino IDE software. The datasheet has a section of fuse selection and setting, section 27 covers the subject.

Lefty

Thanks for the quick response  

retrolefty


Note that your millis() clock will run at the wrong rate unless the system clock is 16MHz or 8MHz, EVEN IF YOU SPECIFY THE NEW CLOCK FREQUENCY.

In that version of the data sheet you want section 8: System Clock and Clock Options


Are you sure of that? I thought the core libraries utilized the f_cpu=xxxxxxxL variable in the boards.txt file to setup the timer used for millis() and micros() ? So wouldn't he just have to modify the boards.txt entry to whatever clock speed he setup his external clock generator for? A little awkward but certainly doable.

Lefty

Coding Badly

#6
Jun 21, 2011, 08:32 pm Last Edit: Jun 21, 2011, 08:34 pm by Coding Badly Reason: 1

Note that your millis() clock will run at the wrong rate unless the system clock is 16MHz or 8MHz, EVEN IF YOU SPECIFY THE NEW CLOCK FREQUENCY.

Are you sure of that?


Nearly.  To work correctly, the millis code requires F_CPU to be an even power of two (16, 8, 4, ...).  So, a few more frequencies are supported.

Quote
I thought the core libraries utilized the f_cpu=xxxxxxxL variable in the boards.txt file to setup the timer used for millis() and micros() ?


They do.  However...

Quote
The Arduino folks wanted an efficient millisecond clock and as many PWM pins as possible.  Those three goals drive the structure of the code and limit the clock speed choices.

The simple fact is that the code in wiring.c requires the processor clock to be a power of 2 (1 MHz, 2 MHz, ... 8 MHz, 16 MHz).  To support arbitrary clock speeds requires code that is more complicated (less efficient) and, in some cases, giving up PWM on timer 0.


Quote
So wouldn't he just have to modify the boards.txt entry to whatever clock speed he setup his external clock generator for?


For non-power of two frequencies, the code in wiring.c has to be modified.

I suspect the millis code could be modified to support a wider range of frequencies (like 20 MHz) but I don't think it can be written to support an arbitrary frequency.  The problem is fourth grade math: fractions.  Some fractions are easy to determine at compile time like the one currently used in millis (1/1024).  Some fractions are not so easy to determine even by a human (what fractions are appropriate for a 14.7456 MHz frequency).

johnwasser


I thought the core libraries utilized the f_cpu=xxxxxxxL variable in the boards.txt file to setup the timer used for millis() and micros() ? So wouldn't he just have to modify the boards.txt entry to whatever clock speed he setup his external clock generator for?


It won't work.  I looked in the core code (wiring.c) and it makes some big assumptions.  It first assumes that the value is a multiple of 1,000,000 when it calculates clockCyclesPerMicrosecond().  In micros() it integer divides 64 by clockCyclesPerMicrosecond().  If the value is not an integer factor of 64 that result will get truncated.  10 MHz will be treated like it was 10.666666 MHz (64/10 -> 6.4 -> 6 and 64/6 = 10.666).  delay() calls micros() so it will be off the same way.   I'm looking at the code now and it looks like millis() might work but I can't be sure. The delayMicroseconds() code is the worst: if the value of F_CPU is not equal to 16000000L it was assumed to be 8000000L.  Only those two values work correctly.  

I'm not sure how the baud rate calculations work with an unusual clock rate.
Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

Go Up