Frequency sweep

Here is a Frequency Sweep example I wrote a while back, modified slightly to better fit your requirements.

const uint32_t HighestFrequency = 5000;
const uint32_t LowestFrequency = 500;

const uint32_t LowestDivisor = (F_CPU / HighestFrequency) / 2;
const uint32_t HighestDivisor = (F_CPU / LowestFrequency) / 2;

const uint32_t TotalSteps = HighestDivisor - LowestDivisor;
const uint32_t MicrosecondsForSweep = 500000ul;

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

  // 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 to Timer/Counter1 to Waveform Generation Mode 12: CTC, TOP in ICR1
  TCCR1B |= (1 << WGM13) | (1 << WGM12);

  // Enable OCR1A (Pin 9) Toggle on Compare match
  pinMode(9, OUTPUT);
  TCCR1A |= (1 << COM1A0);
  OCR1A = 8;
}

void loop()
{
  const uint32_t MAX_TOP = 0xFFFFUL;

  for (uint32_t divisor = HighestDivisor; divisor > LowestDivisor; divisor--)
  {
    // Clear the clock select bits
    TCCR1B &= ~((1 << CS12) | (1 << CS11) | (1 << CS10));

    if (divisor <= MAX_TOP)
    {
      ICR1 = divisor;
      TCCR1B |= (1 << CS10);
    }
    else if ((divisor / 8) <= MAX_TOP)
    {
      ICR1 = divisor / 8;
      TCCR1B |= (1 << CS11);
    }
    else if ((divisor / 64) <= MAX_TOP)
    {
      ICR1 = divisor / 64;
      TCCR1B |= (1 << CS11) | (1 << CS10);
    }
    else if ((divisor / 256) <= MAX_TOP)
    {
      ICR1 = divisor / 256;
      TCCR1B |= (1 << CS12);
    }
    else
    {
      ICR1 = divisor / 1024;
      TCCR1B |= (1 << CS12) | (1 << CS10);
    }

    delayMicroseconds(MicrosecondsForSweep / TotalSteps);  // Adjust to get the desired sweep time.
  }
}