4

I am controlling an ADC with my Arduino Uno. I would like the clock of the ADC to be the same frequency of the Arduino. Is there any way that I can have a constant clock output from one of the Arduino pin ?

Thanks,

Liam

2
  • Sounds a lot like this question
    – Gerben
    Commented Oct 10, 2015 at 18:38
  • Which ADC? If you are reading via SPI, than the clock speed is typically the SPI clock speed, default is 4 MHz, and 8 MHz, 2 MHz, 1 MHz, 512KHz, 256KHz, 125 KHZ and I think 62/5KHz are selectable as well. If you just want a constant, free running clock, then 16 MHz is available at the CKPOUT pin with a change to Low Fuse byte bit 6: The CKOUT Fuse allows the system clock to be output on PORTB0 [on a '328P chip]. Refer to Clock Output Buffer section in the System Clock and Clock Options chapter for details. Ah - 2015 - well, maybe this will come in handy for someone.
    – CrossRoads
    Commented Jan 3, 2020 at 20:50

2 Answers 2

9

This outputs 8 MHz on pin 9:

#ifdef __AVR_ATmega2560__
  const byte CLOCKOUT = 11;  // Mega 2560
#else
  const byte CLOCKOUT = 9;   // Uno, Duemilanove, etc.
#endif

void setup ()
  {
  // set up 8 MHz timer on CLOCKOUT (OC1A)
  pinMode (CLOCKOUT, 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 ()
  {
  // whatever 
  }  // end of loop

How can add a prescaler?

You change the prescaler bits. You can look at the datasheet or my cheat sheet here:

Timer 1 bits

You may not need a prescaler, depending on the frequency. Change OCR1A to some number between 0 and 65535 to slow it down.

Edit by Edgar: I tested the OCR1A values with an oscilloscope. At the end of this answer are the frequencies.


you use TCR1A, COM1A0 and similar variables. Are these always present and implicitly defined when running code on the ATmega

Registers like TCCR1A and so on are defined in files which are automatically included by the Arduino IDE. If you use another toolchain they may be also automatically included. The start point is:

#define <avr/io.h>

Inside that file it checks your processor type (from a symbol passed to the compiler) and then includes an appropriate sub-file. Inside those files are defines which relate the register names to their address in the address-space of that particular chip. For example:

#define TCCR1A _SFR_MEM8(0x80)

The _SFR_MEM8 basically generates a pointer to a volatile address (because it might change without the compiler knowing it) and then dereferences that variable.

Notice that the number 0x80 in that define agrees with the number shown on my chart.

Underneath that define in the appropriate file are also the bit positions for the bits in that register, like this:

#define TCCR1A _SFR_MEM8(0x80)
#define WGM10 0
#define WGM11 1
#define COM1B0 4
#define COM1B1 5
#define COM1A0 6
#define COM1A1 7

Secondly, do I correctly understand that the output pin is defined in TCR1A, Output A and Output B, to be on Digital Pin 9 and 10 respectively?

Yes, in effect. The datasheet says that if you set the appropriate bits in TCCR1A (note the spelling) then OC1A (board pin 9 on the Uno) or OC1B (board pin 10 on the Uno) will be unchanged/toggled/cleared/set depending on the bits. You can find these names on the datasheet for the Atmega328P (and other devices) and then use the Arduino schematic to find which processor pins are connected to which board pins.

Atmega328P datasheet snippet:

Atmega328P datasheet

Uno datasheet snippet:

Uno datasheet


Why do you set it to "Toggle" rather than "Set"?

Because every time the counter matches I want to flip the pin. That is, on/off/on/off etc.


What does CTC stand for?

Clear Timer on Compare. What this means is that (unlike other modes) once the compare match is made, the timer is cleared, thus it starts counting up from zero again.

Edit by Edgar: OCR1A values and frequencies

Value, MHz
 0 8.00
 1 4.00
 2 2.67
 3 2.00
 4 1.60
 5 1.33
 6 1.14
 7 1.00
 8 0.889
 9 0.800
10 0.727
11 0.667
12 0.615
13 0.571
14 0.533
15 0.500
8
  • This is exactly what I needed . How can add a prescaler ?
    – Liam F-A
    Commented Oct 10, 2015 at 20:39
  • See amended reply.
    – Nick Gammon
    Commented Oct 10, 2015 at 22:10
  • Thank you for this helpful chart and code. I have trouble understanding some finer points. First, you just, well, use TCR1A, COM1A0 and similar variables. Are these always present and implicitly defined when running code on the ATmega (or just on an arduino) or do you actually declare them outside of your shown code snippet? Secondly, do I correctly understand that the output pin is defined in TCR1A, Output A and Output B, to be on Digital Pin 9 and 10 respectively? Why do you set it to "Toggle" rather than "Set"? And lastly, an easy one: What does CTC stand for? Many thanks to you. Commented Oct 10, 2016 at 17:49
  • See amended reply.
    – Nick Gammon
    Commented Oct 10, 2016 at 20:18
  • This is an absolutely amazing answer. I wish I had more rep to give you bounty points. For now: Thank you! Commented Oct 11, 2016 at 19:13
3

You can use one of the PWM pins on Arduino to output a PWM signal. If you want a constant clock, you need to set the duty cycle of the PWM to be 0.5, i.e. 50%.

Syntax: analogWrite(pin, value) where the parameter "value" is the duty cycle ranges from 0 (always off) to 255 (always on) since it is a 8-bit PWM generator inside Arduino.

If you need a PWM wave with duty cycle of 0.5, you need to set the "value" above to be 127, which is exactly in middle of 0 and 255:

analogWrite(clkpin, 127);
2
  • analogWrite only works on PWM pins, not on the analog pins.
    – Gerben
    Commented Oct 10, 2015 at 18:37
  • You are right, my fault.
    – Penthrite
    Commented Oct 11, 2015 at 6:59

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.