LTC6904 is a programmable oscillator which is capable of generating frequencies from 1kHz to 68MHz. The oscillation frequency can be changed via the I2C interface and thus makes it very easy to interfacing with MCUs.
According to the data sheet, the output frequency is determined by the OCT and DAC bits in the 16 bit serial port register. For a given frequency, the register bits can be obtained by:
\[OCT=Trunc\left( 3.322\cdot log{\frac{f}{1039}}\right) \]
\[DAC=Round\left( 2048 – \frac{2078\cdot2^{(10+OCT)}}{f}\right) \]
The following code shows the implementation using Arduino.
#include <Wire.h> #include <math.h> const byte I2C_ADDR_0 = 0x17; const byte I2C_ADDR_1 = 0x16; byte i2cAddress = I2C_ADDR_0; //set oscillation frequency //freq: frequency in kHz //compOutputOn: whether the complementary clock output is enabled //register format: //OCT3 OCT2 OCT1 OCT0 DAC9 DAC8 DAC7 DAC6 DAC5 DAC4 DAC3 DAC2 DAC1 DAC0 CNF1 CNF0 void setFreq(float freq, boolean compOutputOn=true) { unsigned int oct = (int) (3.322*log10(freq * 1000.0 / 1039.0)); unsigned int dac = (int) (2048.0 - 2078.0 * pow(2, 10 + oct) / (freq * 1000.0) + 0.5); unsigned int cnf = compOutputOn ? 0 : 2; unsigned int reg = oct << 12 | dac << 2 | cnf; byte high = (reg >> 8) & 0xff; byte low = reg & 0xff; Wire.beginTransmission(i2cAddress); Wire.write(high); Wire.write(low); Wire.endTransmission(); } void setup() { Wire.begin(); setFreq(23.0); //set frequency to 23.0 kHz } void loop() { }
LTC6903 offers the same frequency range as LTC6904 except that it is controlled via SPI.