Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Помогите внести ясность в применении фильтра.
Форум разработчиков электроники ELECTRONIX.ru > Цифровая обработка сигналов - ЦОС (DSP) > Алгоритмы ЦОС (DSP)
Amx
Доброго времени суток.

Сразу приношу извинения за нубские вопросы.
Но какую литературу я бы ни читал о ЦОС там высвечиваются только алгоритмы, методы анализа и расчета.
Меня интересуют можно сказать таки детские вопросы, и так по порядку.

1. Я рассчитал FIR фильтр в Matlab и получил искомые коэффициенты, фильтр устойчив, порядок фильтра оптимальный.
2. Теперь я хочу применить его для обработки сигнала полученного из АЦП микроконтроллера STM32F103 то есть от 0 до 4096.
3. Для STM32 серии CortexM3 имеется библиотека DSP которая поставляется как отдельная библиотека от ST а так же есть в составе CMSIS например можно задействовать ее в Keil. Так как F103 не содержит DSP - инструкций, как я понимаю все алгоритмы выполняются на стандартной арифметике.
4. И вот тут у меня начинаются вопросы....
5. Я хочу применить FIR фильтр из состава библиотеки. Но какой использовать? Если логически подумать, так как входные данные целочисленные то мне нужна функция arm_fir_fast_q15, но она ругается на коэффициенты. Так как они имеют вид:
-0.0085006295830239147,
-0.039315452455814658,
0.020190437531132147,
0.0076176048595180471, (взял первые парочку чтоб не копировать весь массив.)
Если применять функцию arm_fir_f32 то коэффициенты ей подходят, но ведь данные мы имеем целочисленные и выход нужен целочисленный.
6. И еще один вопрос, в примере из CMSIS FIR фильтр реализован где в функцию arm_fir_f32 передается массив выборок равный 32. Можно ли пользоваться этими фильтрами передавая на вход всего одну выборку соответственно и получая один результат за итерацию чтобы не накапливать массив для постобработки.

Может кто пользуется этими библиотеками, расскажите пожалуйста как правильно использовать, если не затруднит.
За ранее благодарен.

Genadi Zawidowski
Код
  /**
   * @brief Processing function for the floating-point FIR filter.
   * @param[in] *S points to an instance of the floating-point FIR structure.
   * @param[in] *pSrc points to the block of input data.
   * @param[out] *pDst points to the block of output data.
   * @param[in] blockSize number of samples to process.
   * @return none.
   */
  void arm_fir_f32(
  const arm_fir_instance_f32 * S,
  float32_t * pSrc,
  float32_t * pDst,
  uint32_t blockSize);


f32 означает тип данных. Количество передается в blockSize. Заглячнул в код CMSIS... когда увидел цикл,
Код
  /* Copy numTaps number of values */
  tapCnt = numTaps - 1u;

  /* Copy data */
  while(tapCnt > 0u)
  {
    *pStateCurnt++ = *pState++;

    /* Decrement the loop counter */
    tapCnt--;
  }

Смотреть расхотелось навсегда...

Фильтр для своей работы в любом случае требует массива значений - предшествующих текущему моменту.

Вот такое использую в своих проектах:
Код
// Ограничение алгоритма генерации параметров фильтра - нечётное значение Ntap.
// Кроме того, для функций фильтрации с использованием симметрии коэффициентов, требуется кратность 2 половины Ntap

#define NtapValidate(n)    ((unsigned) (n) / 4 * 4 + 1)
#define NtapCoeffs(n)    ((unsigned) (n) / 2 + 1)

#define Ntap_rx_AUDIO    NtapValidate(241)    // single samples, floating-point implementation

static FLOAT_T FIRCoef_rx_AUDIO [NPROF] [NtapCoeffs(Ntap_rx_AUDIO)] = { { 0 }, { 0 } };
static FLOAT_T FIRScale_rx_AUDIO [NPROF] = { 1, 1 };

static FLOAT_T filter_fir_rx_AUDIO(FLOAT_T NewSample)
{
    const FLOAT_T * const k = FIRCoef_rx_AUDIO [gwprof];
    enum { Ntap = Ntap_rx_AUDIO, NtapHalf = Ntap / 2 };
    // буфер с сохраненными значениями сэмплов
    static FLOAT_T x [Ntap * 2] = { 0, };
    static uint_fast16_t fir_head = 0;

    // shift the old samples
    fir_head = (fir_head == 0) ? (Ntap - 1) : (fir_head - 1);
    x [fir_head] = x [fir_head + Ntap] = NewSample;

    uint_fast16_t bh = fir_head + NtapHalf;            // Начало обрабатываемой части буфера
    uint_fast16_t bt = bh;    // Позиция за концом обрабатываемого буфера
    // Calculate the new output
    uint_fast16_t n = NtapHalf;
    // Выборка в середине буфера
    register FLOAT_T v = k [NtapHalf] * x [bh];             // sample at middle of buffer
    do
    {    
        {
            const FLOAT_T kv = k [-- n];
            v += kv * x [-- bh];
            v += kv * x [++ bt];
        }
        {
            const FLOAT_T kv = k [-- n];
            v += kv * x [-- bh];
            v += kv * x [++ bt];
        }
    }
    while (n != 0);
    // Обеспечиваем масштабирование к ранее расчитанному усилению фильтра (1.0)
    return v * FIRScale_rx_AUDIO [gwprof];
}


Перевести на целочисленный вариант легко. Придется накапливать в 64 битах (для q31), при использовании результата учесть разрядность рассчитанных коэффициентов

Цитата
ругается на коэффициенты. Так как они имеют вид:
-0.0085006295830239147,
-0.039315452455814658,
0.020190437531132147,
0.0076176048595180471

Множите перед использованием на 32768 (в случае Q15). Результат фильтрации делите на 32768

Библиотечная функция arm_fir_fast_q15 использует SIMD инструкции для работы с парами 16-ти битных чисел за одну операцию, данные для фильтрации можете располагать как в моей функции (массив двойной длинны, без необходимости копирования массива данных для сдвига).
Amx
Большое спасибо за разъяснение и за пример реализации фильтра.

Цитата(Genadi Zawidowski @ Jul 1 2015, 19:52) *
Фильтр для своей работы в любом случае требует массива значений - предшествующих текущему моменту.


Да, я понимаю что для работы фильтра нужен массив предшествующих данных который равен порядку фильтра.
Меня интересовал вопрос именно в передаче нового значения в фильтр за раз в виде одной выборки а не пакетно.
Но как я вижу из Вашей реализации Вы тоже передаете одну последнюю выборку, значит вариант с кормлением фильтра одной новой выборкой и получением одного нового результата естественного с задержкой равной порядку фильтра за одну итерацию возможен.
Спасибо.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.