Если в МК нет умножителя:
Имеем входной сигнал X. Дальше он проходит через компаратор:
| -1 при Х<0
x = {
| +1 при X>=0
ну или в более правильном виде -
x=sign(X)
Далее основная обработка:
N-1
---
Y = x[n]*sign(cos(2*pi*n*Fx/Fs))
/
---
n=0
N-1
---
Z = x[n]*sign(sin(2*pi*n*Fx/Fs))
/
---
n=0
В этих формулах N - размер выбранного окна в выборках. Желательно подобрать как можно ближе к тому, чтобы все частоты в этом окне имели целое количество периодов. Fx - анализируемая частота, Fs - частота дискретизации. Умножение сводится тут к операции XOR, если лог. 1 принять за +1, а лог.0 - за -1. Да, а все синусы и косинусы - держать заранее рассчитанными в таблице, достаточно 1 бита на одну выборку.
Далее:
____________
/ 2 2
E = / Y + Z
Получаем число, пропорциональное энергии сигнала на частоте Fx. Корень естественно можно не считать, так как квадрат энергии нас тоже устроит. Возведение в квадрат - по таблице.
Ну и последнее:
2
| 0, если E < Thr
T = { 2
| 1, если E >= Thr
Thr - выбранный порог срабатывания детектора. T - выходной сигнал, 1 означает что требуемая частота присутствует в спектре входного сигнала и обладает достаточной энергией.Этот метод полностью аналогичен преобразованию Фурье для одной частоты Fx.
Вариант
А если в МК есть нормальный умножитель (16 бит х 16 бит) - то используется фильтр Герцеля, который в общем-то тоже аналогичен преобразованию Фурье в 1 точке. Про это я расписывать не буду, в гугле можно тучу информации найти спросив про "Goertzel filter"
ЗЫ
Если где ошибся - подправьте...
Для функции sign принято что 0 - число положительное, и , соответственно число 0 не относится к области значений функции.
Для 51-го проца можно 1-й вариант довольно сильно улучшить, используя 4-х битные значения входного сигнала (если есть АЦП) и 4-х битные значения синуса/косинуса. Умножать командой MUL, получая 8-битное произведение, и суммировать в 16-битном варианте. Проверено экскрементами :-). Ну а в случае AVR, PIC, простеньких MSP и т.п. - вариантов нет, только однобитное.