smk 0 January 16 Posted January 16 (edited) · Report post Научите как сделать на STM32 полосовой фильтр на 1 кГц. Нужно знать есть ли сигнал с чакстотой 1 кГц. Спасибо. Edited January 16 by haker_fox Переименовал тему. Переместил в раздел STM32. Quote Share this post Link to post Share on other sites More sharing options...
jcxz 84 January 16 Posted January 16 · Report post 1 час назад, smk сказал: Научите как сделать на STM32 полосовой фильтр на 1 кГц. Нужно знать есть ли сигнал с чакстотой 1 кГц. Спасибо. Так же как и не на STM32: Поставить Matlab, запустить его компонент FDAtool и смоделировать фильтр в нём. Затем - перенести полученную таблицу коэффициентов в программу в МК. Quote Share this post Link to post Share on other sites More sharing options...
Aleksandr Baranov 1 January 16 Posted January 16 · Report post Есть довольно старый бесплатный пакет Winfilter. Можно попробовать его, если нет Матлаба. Quote Share this post Link to post Share on other sites More sharing options...
smk 0 January 16 Posted January 16 · Report post А можно пример какой-то? В части контроллера. Quote Share this post Link to post Share on other sites More sharing options...
GenaSPB 7 January 16 Posted January 16 · Report post CMSIS-DSP\Examples\ARM\arm_fir_example не? Quote Share this post Link to post Share on other sites More sharing options...
GenaSPB 7 January 16 Posted January 16 · Report post Spoiler // Расчёт фильтра нижних частот // Расчёт фильтра без наложения оконной функции static void fir_design_lowpass(FLOAT_t *dCoeff, int iCoefNum, FLOAT_t m_fCutHigh) { const int iHalfLen = (iCoefNum - 1) / 2; int iCnt; /*------------------*/ /* Lowpass filter */ /*------------------*/ dCoeff [iHalfLen] = m_fCutHigh; for (iCnt = 1; iCnt <= iHalfLen; iCnt ++) { const FLOAT_t a = (FLOAT_t) M_PI * iCnt; const FLOAT_t k = SINF(m_fCutHigh * a) / a; dCoeff [iHalfLen - iCnt] = k; } } // Расчёт фильтра - пробки // ((CutLow > 0.0) && (CutHigh < 1.0) && (CutLow < CutHigh)) // Расчёт фильтра без наложения оконной функции static void fir_design_bandstop(FLOAT_t * dCoeff, int iCoefNum, FLOAT_t fCutLow, FLOAT_t fCutHigh) { const int iHalfLen = (iCoefNum - 1) / 2; int iCnt; /*------------------*/ /* Bandstop filter */ /*------------------*/ //if ((CutLow > 0.0) && (CutHigh < 1.0) && (CutLow>CutHigh)) { dCoeff [iHalfLen] = fCutLow - fCutHigh; for (iCnt = 1; iCnt <= iHalfLen; iCnt ++) { const FLOAT_t a = (FLOAT_t) M_PI_2 * iCnt; // M_PI_2 - constant pi/2 const FLOAT_t k = SINF((fCutLow - fCutHigh) * a) * COSF((fCutHigh + fCutLow) * a) / a; dCoeff [iHalfLen - iCnt] = k; } dCoeff [iHalfLen] += 1; } // Расчёт фильтра без наложения оконной функции static void fir_design_passtrough(FLOAT_t * dCoeff, int iCoefNum, FLOAT_t dGain) { const int iHalfLen = (iCoefNum - 1) / 2; int iCnt; for (iCnt = 1; iCnt <= iHalfLen; iCnt ++) { dCoeff [iHalfLen - iCnt] = 0; } dCoeff [iHalfLen] = dGain; } // Без наложения оконной функции static void fir_design_bandpass(FLOAT_t * dCoeff, int iCoefNum, FLOAT_t fCutLow, FLOAT_t fCutHigh) { const int iHalfLen = (iCoefNum - 1) / 2; int iCnt; dCoeff [iHalfLen] = fCutHigh - fCutLow; for (iCnt = 1; iCnt <= iHalfLen; iCnt ++) { const FLOAT_t a = (FLOAT_t) M_PI_2 * iCnt; // M_PI_2 - constant pi/2 const FLOAT_t k = SINF((fCutHigh - fCutLow) * a) * COSF((fCutHigh + fCutLow) * a) / a; dCoeff [iHalfLen - iCnt] = k; } } Это расчеты для симметричных FIR (с нечетным количеством отводов) - формирует половинку от массива. Для увеличения крутизны скатов еще "оконную" функцию к массиву применяют. Quote Share this post Link to post Share on other sites More sharing options...
smk 0 January 16 Posted January 16 · Report post Мне бы пример полосового фильтра на какую-то частоту и что пересчитывать нужно если частота другая нужна. Спасибо. Quote Share this post Link to post Share on other sites More sharing options...
spirit_1 2 January 16 Posted January 16 (edited) · Report post On 1/16/2023 at 5:06 PM, smk said: Мне бы пример полосового фильтра на какую-то частоту и что пересчитывать нужно если частота другая нужна. Спасибо. Наьираете в гуле чтото типа FIR Filter C Смотрите ссылки где то что вас интересует Например https://sestevenson.wordpress.com/implementation-of-fir-filtering-in-c-part-1/ https://stackoverflow.com/questions/14997850/fir-filter-implementation-in-c-programming https://lloydrochester.com/post/c/fir-filter/ https://dspguru.com/dsp/tricks/fir-filtering-in-c/ https://dspguru.com/dsp/tricks/fir-filtering-in-c/ https://github.com/topics/fir-filter итд. Для СТМ32 https://embeddedexpert.io/?p=763 Кстати у стм есть ДСП библиотека с примерами и готовыми функциями тоже можете вполне использовать Посмотрите на структурные схемы ФИРа , поймите что есть что и реализация абсолютно проста, математика программирования не сложная Тогда сможете использовать различные визарды фильтров. Но если на раз и забыть то чтото найдете в примерах выше Edited January 16 by spirit_1 Quote Share this post Link to post Share on other sites More sharing options...
Aleksandr Baranov 1 January 16 Posted January 16 · Report post 3 hours ago, smk said: Мне бы пример полосового фильтра на какую-то частоту и что пересчитывать нужно если частота другая нужна. Спасибо. Упомянутый Winfilter генерирует С-код. Пересчитвать коэффициенты в микроконтроллере "налету", так, чтобы получить любую полосу и частоту проблематично. Разве что, если это простой фильтр. Если требуется обнаружить 1 кГц или какую-то другую одну частоту - может быть подумать о преобразовании Герцеля? Quote Share this post Link to post Share on other sites More sharing options...
TU-104 0 January 17 Posted January 17 · Report post 15 hours ago, Aleksandr Baranov said: Есть довольно старый бесплатный пакет Winfilter. Можно попробовать его, если нет Матлаба. Ещё онлайн есть такая штука http://t-filter.engineerjs.com , FIR мне понравился Quote Share this post Link to post Share on other sites More sharing options...
smk 0 January 17 Posted January 17 · Report post Как это использовать? void SampleFilter_init(SampleFilter* f) { int i; for(i = 0; i < SAMPLEFILTER_TAP_NUM; ++i) f->history[i] = 0; f->last_index = 0; } void SampleFilter_put(SampleFilter* f, double input) { f->history[f->last_index++] = input; if(f->last_index == SAMPLEFILTER_TAP_NUM) f->last_index = 0; } double SampleFilter_get(SampleFilter* f) { double acc = 0; int index = f->last_index, i; for(i = 0; i < SAMPLEFILTER_TAP_NUM; ++i) { index = index != 0 ? index-1 : SAMPLEFILTER_TAP_NUM-1; acc += f->history[index] * filter_taps[i]; }; return acc; } Quote Share this post Link to post Share on other sites More sharing options...
Lmx2315 1 January 17 Posted January 17 · Report post 15 часов назад, smk сказал: Мне бы пример полосового фильтра на какую-то частоту и что пересчитывать нужно если частота другая нужна. Спасибо. Если вам нужно обнаруживать сигналы с разными частотами, то советую БПФ он же FFT . Ничего не надо будет пересчитывать. Quote Share this post Link to post Share on other sites More sharing options...
TU-104 0 January 17 Posted January 17 (edited) · Report post 27 minutes ago, smk said: Как это использовать? void SampleFilter_init(SampleFilter* f) { int i; for(i = 0; i < SAMPLEFILTER_TAP_NUM; ++i) f->history[i] = 0; f->last_index = 0; } void SampleFilter_put(SampleFilter* f, double input) { f->history[f->last_index++] = input; if(f->last_index == SAMPLEFILTER_TAP_NUM) f->last_index = 0; } double SampleFilter_get(SampleFilter* f) { double acc = 0; int index = f->last_index, i; for(i = 0; i < SAMPLEFILTER_TAP_NUM; ++i) { index = index != 0 ? index-1 : SAMPLEFILTER_TAP_NUM-1; acc += f->history[index] * filter_taps[i]; }; return acc; } Так всё же понятно: - Завести переменную - структуру SampleFiler, передать её в начале в инит (там просто нулями заполняется массив сэмплов). - Очередной сэмпл положить в массив функцией ..._put() - Забрать c выхода фильтра тоже очередное значение .._get() Но вам тут выше посоветовали для вашей задачи (обнаружение частоты) - быстрее Гертцелем Edited January 17 by TU-104 Quote Share this post Link to post Share on other sites More sharing options...
spirit_1 2 January 17 Posted January 17 (edited) · Report post On 1/17/2023 at 8:16 AM, Lmx2315 said: Если вам нужно обнаруживать сигналы с разными частотами, то советую БПФ он же FFT . Ничего не надо будет пересчитывать. Герцель в самый раз для такого, #define PI 3.14159265358979323846 #define buffer_size 44100 double samples[buffer_size]; double FS = 44100.0; //fréquence d'échantillonnage double FDETECT = 1000.0; // fréquence à détecter int K; double coefficient; double W; double sine; double cosine; double Q0, Q1, Q2; double real; double imag; double magnitude; double scalingFactor; int i; K = (int) (0.5 + ((buffer_size * FDETECT) / FS)); W = (2.0 * PI * K) / buffer_size; cosine = cos(W); sine = sin(W); coefficient = 2 * cos(W); scalingFactor = buffer_size / 2.0; Q0 = 0; Q1 = 0; Q2 = 0; for (i=0 ; i<buffer_size ; i++) { Q0 = samples[i] + (coefficient * Q1) - Q2; Q2 = Q1; Q1 = Q0; } real = (Q0 - (Q1 * cosine)) / scalingFactor; imag = (- Q1 * sine) / scalingFactor; magnitude = sqrt(real * real + imag * imag); Пример из Википедии Думаю все понятно double FS- часота вашего АЦП double FDETECT- частота детекции double samples[buffer_size]; буфер с отсчетами magnitude = sqrt(real * real + imag * imag); - амлитуда сигнала Если надо постоянно отслеживать амплитуду то постоянно суете samples как переменную и в magnitude = sqrt(real * real + imag * imag); забираете амплитуду вашей частоты Edited January 17 by spirit_1 Quote Share this post Link to post Share on other sites More sharing options...
Variant99 0 January 17 Posted January 17 · Report post Полезная тема, надо положить её в закладки. А вот еще тогда такой вопрос. В некоторых ЫЕЬ32-микроконтроллерах есть DFDSM - цифровой фильтр для сигма-дельта модуляции. Я немного поискал по этой теме и понял, что такое и как выглядит сигма-дельта модуляция. Теперь вопрос - этот модуль DFDSM в микроконтроллере, на нем можно ли построить цифровой фильтр частот? Как я понял, источник сигма-дельта сигнала нужен внешний, то есть внешний АЦП с таким выходом. Окей. А модуль DFSDM в микроконтроллере, он только преобразует входной сигма-дельта сигнал в числовые значения или же еще каким-то образом является цифровым фильтром частот? Quote Share this post Link to post Share on other sites More sharing options...