Як працює ця штука?
Уявімо собі таку конструкцію.

Грузик висить на кінці пружинки, прикріпленою до нерухомого предмету. Якщо злегка відтягнути кульку вліво або вправо, він почне коливатися з деяким періодом T0. Як ми знаємо з шкільного курсу фізики з гугла, період цей дорівнює:
Де m - маса грузика, а k - жорсткість пружинки.
А власна частота коливань, відповідно, буде дорівнює 1 / T0. Думаю, ні для кого не секрет, що якщо підштовхувати грузик рівно з цією частотою, амплітуда коливань буде максимальна. Причому, чим слабкіша підштовхувати, тим сильніше амплітуда коливань буде залежати від частоти підштовхування.
Виходить такий механічний фільтрікі. Спробуємо зробити його модель.
З фізики ми знаємо ще кілька формул. Сила, з якою пружинка діє на вантаж, дорівнює:
де k - жорсткість пружинки, а x - розтягнення пружинки. Ця сила надає грузик прискорення, рівне:
де m - маса грузика. Звідси виходить, що:
Замінимо k / m на T. З найпершої формули отримуємо, що:
Тепер до самої моделі. Нам знадобляться 2 змінних - швидкість руху грузика v і положення грузика x. Також знадобиться крок моделювання t.
На кожному кроці швидкість грузика буде змінюватися за такою формулою:
а положення по формулі
У нашій системі t - в секундах, F - в герцах, а x - в папуг. Варто перейти до мілісекунди і кілогерц, щоб не отримувати страшні числа. Всі формули при цьому чарівним чином залишаються тими ж. )
Реалізація
Для початку, спробуємо просто отримати коливальний процес.
Моделюємо коливання грузика з кроком в 1/16 мс (множення на 1/16 мс замінюємо на зрушення вправо на 4 біта). Дані відправляємо в порти B і D щоб розуміти що у нас там твориться. )

До портів підключаємо ЦАПи, а до них осцилограф.

Начебто працює. Положення і швидкість змінюються по синусоїді, зсунутим на 90 градусів, прям як струм і напруга в коливальному контурі. Частота рівно 1 кГц, як і планувалося. )
Тепер додамо вхідний сигнал.
Тут ми трохи «підштовхуємо грузик» семплами з АЦП. Ось так підключено.

А ось і результат.

Синій графік - сигнал з генератора, жовтий - з ЦАПа.
Ось таку мігалочку я і зібрав щоб перевірити ідею. )

Ось остаточний код.
На колекторі транзистора повинна бути приблизно половина харчування (якщо що, підлаштовується номіналом R1). Тиньков затактована від внутрішньої RC-ланцюжка на 8 МГц.
Хм, ну ось і все ...