logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

[Matlab] Filtry dla procesorów stałoprzecinkowych

l_smolinski 05 Maj 2009 17:20 1598 2
REKLAMA
  • #1 6493289
    l_smolinski
    Poziom 11  
    Jestem zielony w tym temacie.

    Mając filtr lub współczynniki w postaci próbek w formacie "double" (matlab), jak należy przekształcić te próbki do formatu stałoprzecinkowego. Tak, aby było można je wykorzystać w procesorze stałoprzecinkowym ???

    A tak naprawdę jak należy się zabrać za zaprojektowanie filtra dla procesorów stałoprzecinkowych? Bo chyba coś mi umknęło w tej całej mojej metodologi projektowej.
  • REKLAMA
  • Pomocny post
    #2 6497243
    __Grzegorz__
    Poziom 30  
    Licznik i mianownik transmitancji filtra pomnożyć przez stałą wartość.
    Najlepiej potęgę 2 (bo jak sobie możesz sprawdzić, w kodzie pojawi się dzielenie, które akurat tutaj sprowadzi się do przesuwania liczby o ileś bitów w prawo).

    Wyniki zaokrąglić.
    Sprawdzić charakterystyki filtru po skwantowaniu współczyników.
    Jeżeli filtr spełnia założenia wyjściowe - piszemy kod :)

    W przypadku filtrów IIR, jeżeli rząd filtra > 2, warto (TRZEBA) transmitancję rozbić na iloczyn transmitancji rzędu maksymalnie 2.
    Dodatkowo w tym przypadku (rząd fitra>>2) kolejność w jakiej połączysz ze sobą biquady MA znaczenie. ale to inna bajka.

    Przykład:
    Zaprojektowałem IIR BPF o fs=1kHz i paśmie 10Hz.
    przy fpróbkowania=8000Hz.
    Jego transmitancja:
    
    y 7.853981634e-3 - 5.559551058e-3*z^-1
    -=--------------------------------------------------------
    x 1              - 1.408684679   *z^-1 + 0.9921767803 *^z-2
    

    Obliczenia będę robił na intach, wynik MAC będę akumulował w zmiennej typu long.
    Mnożę zatem transmitancję przez 16384 (2^15) i zaokrąglam:
    
    y    129 -    91 *z^-1
    -=----------------------------------
    x  16384 - 23080 *z^-1 + 16256 *z^-2
    


    Kod wynikowy w C (najszybszy możliwy dla DSP):
    
    
    #define a1 23080L //*-1 !!!
    #define a2 -16256L //*-1 !!!
    #define b0 129L 
    #define b1 -91L 
    #define b2 0L
    
    /****************************************
    int filter (signed int x)
    //****************************************
    {
    register long signed int y;
    
    // 590ns sie wykonuje (&144MHz)
    x=x/4; //trzeba brać pod uwagę możliwość wyjścia poza zakres long wskutek operacji MAC poniżej...
    y =(b0*x);
    y+=(b1*x1);
    y+=(a1*y1);
    y+=(a2*y2);
    
    y/=16384; //magiczne dzielenie :)
    
    //ew. ogranicznik coby nie narobić śmieci na wyjściu...
    if (y>32767)  y=32767;
    if (y<-32767) y=-32767;
    
    //przepisanie próbek (konieczne dla IIR)
    x1=x;
    y2=y1; y1=y;
    return (y)
    }
    


    weryfikację właściwości filtra po kwantyzacji współczynników sobie darowałem. :)
  • #3 6524594
    l_smolinski
    Poziom 11  
    
    y/=16384; //magiczne dzielenie :) 
    



    Tak wszystko się rozchodziło o to właśnie magiczne dzielenie. A tak resztę metodologi projektowej miałem dobre.

    Z tym, że:

    2^15 = 32768

    Dzięki.
REKLAMA