Expanding from my comment... any signal level generated by this kind of
microcontroller can only last for an integer number of CPU cycles. In
order to generate it, you first have to compute the timing
characteristics of the desired signal in terms of CPU cycles:
period = 16 MHz ÷ 1.7 MHz = 9.412 cycles
The closest you can get is 9 cycles, which gives the frequency
frequency = 16 MHz ÷ 9 = 1.778 MHz
Assuming this is acceptably close to your target, you can configure a
timer to do it. The example code you provided uses Timer 2 with the
OC2A output set to toggle mode. This approach can only give periods
which are an even number of cycles, thus I am using the regular
“non-inverting fast PWM” mode instead in the solution below. In this
mode, the pin OC2A cannot be used with a controlled frequency, then I
changed it to OC2B (pin 3 on the Uno). Here is the code:
const uint8_t OUTPUT_PIN = 3; // = OC2B
const uint8_t PERIOD = 9; // 9 CPU cycles ~ 1.778 MHz
void setup()
{
pinMode(OUTPUT_PIN, OUTPUT);
TCCR2B = 0; // stop timer
TCNT2 = 0; // reset timer
TCCR2A = _BV(COM2B1) // non-inverting PWM on OC2B
| _BV(WGM20) // fast PWM mode, TOP = OCR2A
| _BV(WGM21); // ...ditto
TCCR2B = _BV(WGM22); // ...ditto
OCR2A = PERIOD - 1;
OCR2B = PERIOD/2 - 1;
}
void soundBuzzer() {
TCCR2B |= _BV(CS20); // F_CPU / 1
}
void silenceBuzzer() {
TCCR2B &= ~_BV(CS20);
TCNT2 = 0;
}
The generated signal is slightly asymmetric: it stays HIGH during
4 cycles and LOW for 5 cycles. If you want a symmetric signal
(50% duty cycle), you can set PERIOD
to 10 (5 cycles HIGH
and 5 cycles LOW), but then the frequency drops to 1.6 MHz.
Edit: You could also replace your Arduino Uno by a cheap ATtiny85
microcontroller, or maybe an Arduino-compatible dev board based on it,
like the Trinket or the Digispark.
This microcontroller has a built-in PLL which allows it to run one of
its timers at 64 MHz, even though the CPU is running much slower.
A 64 MHz timer allows you to hit the target 1.7 MHz frequency
to within 1%:
64 MHz ÷ 38 = 1.684 MHz