Цифровой фильтр вызова с фиксированной точкой в C

#c #signal-processing #avr #avr-gcc

#c #обработка сигнала #avr #avr-gcc

Вопрос:

Я пытаюсь закодировать цифровой фильтр вызова на микроконтроллере AVR, и у меня возникли некоторые проблемы с реализацией диаграммы состояний в арифметике с фиксированной точкой. Вот изображение потока сигналов, для которого я пытаюсь написать код:введите описание изображения здесь

Редактировать: (Я полагаю, что уравнение для T_c, приведенное выше, должно быть e ^ [ -1 / (F_s * D)] )

Вот что у меня есть на данный момент. У меня есть процедура под названием smultfix, которая выполняет умножение с фиксированной запятой со знаком на два 8-битных целых числа со знаком и возвращает 16-битное произведение со знаком. F_c и T_c представляют собой 8-разрядные двоичные дроби со знаком. «Выход» и промежуточный этап на стыке входа T_c и элемента задержки z1 обрабатываются как 16-разрядные двоичные дроби. Итак, у меня есть:

(предположим, что F_c и T_c определены в другом месте)

 int8_t generateSample()
{
    static int16_t z1 = 0x7FFF;  //initialize first delay element to max positive value
    static int16_t output;
    int8_t byteOutput = 0;
    int8_t bytez1 = 0;

    bytez1 = (z1 amp; 0xFF00)>>8; //make z1 into an eight bit signed binary fraction for    
                               //multiplication

    output = (smultfix(bytez1,F_c)<<1)   output; //calculate output, shift product
                                                 //left once to 
                                                 //remove double sign bit

    byteOutput = (output amp; 0xFF00)>>8;          //generate output byte

    z1 = (-(smultfix(byteOutput,F_c)<<1)) - 
            (smultfix(bytez1,T_c)<<1) //generate intermediate                
                                                             //product z1
    return byteOutput;  
}
  

К сожалению, я, кажется, только что создал плохой генератор случайных чисел, поскольку этот код генерирует много мусора, заполняющего мой выходной буфер! Если бы кто-нибудь мог указать, где я могу ошибаться, или если у них есть идея реализации, которая была бы лучше, это было бы очень ценно.

Комментарии:

1. Когда вы сдвигаете выходные данные smultfix, вы теряете знаковый бит.

2. @BrettHale Если я обрабатываю и множитель, и множимую как двоичные дроби со знаком, то при их умножении я получаю два знаковых бита, верно? Итак, я должен удалить один, да?

Ответ №1:

Код на самом деле правильный, но знак уравнения для T_c действительно должен быть положительным, а не отрицательным. В первом издании книги он показан как отрицательный, и, похоже, это изображение было взято из второго издания книги, в котором уравнение было исправлено. Если T_c оценивается с отрицательной экспонентой, будут возрастающие колебания, но если оно положительное, колебания уменьшатся, чего мы и добиваемся. Отрицательное значение T_c и изменение знака вычитания в предпоследней строке также работает.