Вот код инициализации (по совету
blindman'а пользуюсь именами разрядов):
- Код: Выделить всё • Развернуть
//Таймер 3 (отсчёт частоты звука)
//Быстрая ШИМ, OC3A переключается при сбросе таймера
TCCR3A = 0x00 | 1<<COM3A0 | 1<<WGM31 | 1<<WGM30;
TCCR3B = 0x00 | 1<<WGM33| 1<<WGM32;
Работать работает, но попадаются прежние неприятные паузы при смене частоты, которые ликвидируются, если обнулять счетчик (TCNT3 = 0x00).
Чуть-чуть поковыряюсь ещё, и сделаю как ты советуешь.

Буду использовать программный буфер и включать прерывание при необходимости сменить частоту звука.
Добавлено спустя 3 часа 22 минуты 38 секунд:Сделал двойную буферизацию программно - не помогло. Полез выяснять, обнаружил такую штуку - пока у меня вызывается обработчик прерывания переполнения таймера-счётчика его значение уже успевает уплыть больше чем на половину периода! Вот встал на брейкпоинте:

Это нормально, доктор?
Счетчик у меня с предделителем 8 работает, значит прошло 2480 тактов процессора, прежде чем запустился мой обработчик прерывания и я считал значения двух регистров.
Добавлено спустя 15 минут 49 секунд:На данный момент решил проблему без прерываний, дешевой и сердитой проверкой на "убегание" после изменения значения регистра сравнения:
- Код: Выделить всё • Развернуть
//Установка значения счётного регистра
OCR3A = nFreq;
//Проверка на "перепрыгивание" предела
nCounter = TCNT3;
if(nCounter >= nFreq) {
//Cброс счетчика
TCNT3 = 0x00;
}