I'm trying to figure out how to create a 24MHz clock signal on one of the I/O pins of my Arduino Zero, so that this clock signal is sent out and the processor is free to do other tasks. What is this the best way to do this in C using Arduino IDE? Or is this possible? Thx
It may not be possible. SPI on the Zero is limited to 12MHz due to pin capacitance I believe. I would assume this is a limitation of pins when used for general I/O as well.
The following code attempts to output a 24MHz clock on digital pin 7. I've tested it with the SAMD21's 8MHz clock source divided by 128, giving a 63kHz signal and divided by 64, giving 126kHz. However, I'm unable to test it at 24MHz, as I don't have access to a scope or a more powerful multimeter. My multimeter is outputting a slightly lower voltage than I'd expect, which probably indicates that the signal is attenuated at this higher frequency.
void setup()
{
// Output 24MHz signal on digital pin 7
// Set the clock generator 5's divisor to 2 (48Mhz / 2 = 24MHz)
REG_GCLK_GENDIV = GCLK_GENDIV_DIV(2) | // Set the clock divisor to 2
GCLK_GENDIV_ID(5); // Set the clock generator ID to 5
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for the bus to synchronise
// Connect he 48MHz clock source to generic clock generator 5 and enable its outputs
REG_GCLK_GENCTRL = GCLK_GENCTRL_OE | // Enable the generic clock 5's outputs
GCLK_GENCTRL_IDC | // Ensure the duty cycle is about 50-50 high-low
GCLK_GENCTRL_GENEN | // Enable the clock generator 5
GCLK_GENCTRL_SRC_DFLL48M | // Set source to be 48MHz clock Note: for 8MHz source use GCLK_GENCTRL_SRC_OSC8M
GCLK_GENCTRL_ID(5); // Set the clock generator ID to 5
while (GCLK->STATUS.bit.SYNCBUSY); // Wait for the bus to synchronise
// Output the clock on digital pin 7 (chosen as it happens to be one of generic clock 5's outputs)
// Enable the port multiplexer (mux) on digital pin 7
PORT->Group[g_APinDescription[7].ulPort].PINCFG[g_APinDescription[7].ulPin].bit.PMUXEN = 1;
// Switch port mux to peripheral function H - generic clock I/O
// Set the port mux mask for odd processor pin numbers, D7 = PA21 = 21 is odd number, PMUXO = PMUX Odd
PORT->Group[g_APinDescription[7].ulPort].PMUX[g_APinDescription[7].ulPin >> 1].reg |= PORT_PMUX_PMUXO_H;
}
void loop() { }