Square wave generator and frequency meter

Here is an example of generating frequencies using Timer1. It can for 0.2Hz (5 seconds per cycle) to 500 kHz.

// Generating Two 180° Out of Phase Variable-Frequency 
// Square Waves on Timer1 of an Arduino UNO (Pins 9 and 10)
// Good for frequencies from 0.2 Hz to 500 kHz.
// Written June 1st, 2020 by John Wasser

void TwoPhaseBegin()
{
  digitalWrite(9, LOW);
  pinMode(9, OUTPUT);
  digitalWrite(10, LOW);
  pinMode(10, OUTPUT);

  // Stop Timer/Counter1
  TCCR1A = 0;  // Timer/Counter1 Control Register A
  TCCR1B = 0;  // Timer/Counter1 Control Register B
  TIMSK1 = 0;  // Timer/Counter1 Interrupt Mask Register

  // Set Timer/Counter1 to Waveform Generation Mode 8: 
  // Phase and Frequency correct PWM with TOP set by ICR1
  TCCR1B |= (1 << WGM13);  // WGM=8
  TCCR1A |= (1 << COM1A1);  // Normal PWM on Pin 9
  TCCR1A |= (1 << COM1B1) | (1 << COM1B0); // Inverted PWM on Pin 10

  TwoPhaseFrequency(1000.0);  // Default to 1 kHz
}

bool TwoPhaseFrequency(float frequency)
{
  byte prescaleBits; // 1, 2, 3, 4, 5
  uint16_t prescaleFactor;  // 1, 8, 64, 256, 1024
  uint32_t top32;

  // Find the smallest prescale factor that will fit the TOP value within 16 bits.
  // frequency = F_CPU / (2 * prescale *  TOP)
  // TOP = F_CPU / (2UL * prescale * frequency);

  prescaleBits = 1;
  prescaleFactor = 1;  // Used for 123 Hz to 500 kHz
  top32 = F_CPU / (2UL * prescaleFactor * frequency);
  if (top32 > 65535UL) // Too many clocks to count in 16 bits?
  {
    prescaleBits = 2;
    prescaleFactor = 8;  // Used for 16-122 Hz
    top32 = F_CPU / (2UL * prescaleFactor * frequency);
    if (top32 > 65535UL) // Too many clocks to count in 16 bits?
    {
      prescaleBits = 3;
      prescaleFactor = 64;  // Used for 2-15 Hz
      top32 = F_CPU / (2UL * prescaleFactor * frequency);
      if (top32 > 65535UL) // Too many clocks to count in 16 bits?
      {
        prescaleBits = 4;
        prescaleFactor = 256; // Only used for 1 Hz
        top32 = F_CPU / (2UL * prescaleFactor * frequency);
        if (top32 > 65535UL) // Too many clocks to count in 16 bits?
        {
          prescaleBits = 5;
          prescaleFactor = 1024;
          top32 = F_CPU / (2UL * prescaleFactor * frequency);
          if (top32 > 65535UL) // Too many clocks to count in 16 bits?
          {
            return false;
          }
        }
      }
    }
  }

  //  Serial.print("Freq: ");
  //  Serial.print(frequency);
  //  Serial.print(" prescale: ");
  //  Serial.print(prescaleFactor);
  //  Serial.print(" TOP: ");
  //  Serial.println(top32);

  if (top32 < 16)
    return false; // Require at least 16 levels of PWM

  TCCR1B &= ~((1 << CS12) | (1 << CS11) | (1 << CS10)); // Clear the three clock select bits
  TCCR1B |= prescaleBits; // Set clock prescale to prescaleBits

  ICR1 = top32;
  OCR1A = top32 / 2;
  OCR1B = (top32 / 2) + 1;
  return true;
}

void setup()
{
  Serial.begin(115200);

  TwoPhaseBegin();  // Start output at 1000 Hz
}

void loop()
{
  // Call TwoPhaseFrequency(uint16_t frequency) any time to change the output frequency
}