mikrocontroller.net

Forum: Digitale Signalverarbeitung / DSP CIC mittels C implementieren


Autor: CICanfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich bin gerade dabei ein CIC Filter zur SampleRate Reduzierung zu 
entwerfen (dsPic). Jedoch bin ich mir nicht ganz sicher, ob ich es 
richtig umgesetzt habe. Vielleicht hat noch jemand Anregungen für 
Verbesserungen.

Es müssen NumbOutputSample * DecimationFactor Inputsamples im 
Eingangsarray vorhanden sein.

Ich bin mir deswegen unsicher, da bei konstanten Eingangssamples eine 
Verstärkung >1 auftritt.

Stefan




typedef struct
{
  uint16 R;      // decimation factor
  uint16 N;      // number of stages
  uint16 M;      // comb delay, select 1 or 2 (not used now)
  int32 *intDelay;    // ptr to delay array
  int32 *combDelay;    // ptr to comb delay array
} CICStruct;


// protoype declaration
void CIC (               // CIC filtering
   uint16 numSamps,         // number of input samples (N)
          // N = R*p (p integer)
   int16 *dstSamps,           // ptr to output samples
                                        // (y[n], 0 <= n < N)
   int16 *srcSamps,           // ptr to input samples
                                        // (x[n], 0 <= n < N*R)
   CICStruct *filter            // filter structure:
);


void CIC (uint16 numSamps, int16 *dstSamps, int16 *srcSamps, CICStruct 
*filter)
{
  uint16 i;
  uint16 i_cic;
  uint16 samples = 0;
  int32 tempX;  // holds value between CIC stages
  int32 combY;

  for(i = 0; i < numSamps; i++)
  {
    // save new input sample into variable
    tempX = (int32)*srcSamps;

    // process for all N CIC stages
    for(i_cic = 0; i_cic < filter->N; i_cic++)
    {
      // y[n] = x[n] + y[n-1]
      tempX = tempX + *(filter->intDelay + i_cic);
      // make y[n] to y[n-1] for next loop
      *(filter->intDelay + i_cic) = tempX;
    }//for stages

    // select next input sample
    srcSamps++;
    samples++;

    // decimation and COMB filter
    if (samples == filter->R)
    {
      samples = 0;
      // process for all CIC stages
      for(i_cic = 0; i_cic < filter->N; i_cic++)
      {
        // backup x[n]
        combY = tempX;
        // y[n] = x[n] - x[n-1]
        tempX = tempX - *(filter->combDelay + i_cic);
        // make: x[n] to x[n-1] for next sample
        *(filter->combDelay + i_cic) = combY;
      }//for stages

      // save to output and select next output destination
      *dstSamps = (int16)tempX;
      dstSamps++;
    }//if COMB

  }//for numSamps

}//CIC

Autor: CICanfänger (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

da sich noch keiner gemeldet hat, möchte ich nachfragen, ob schon jemand 
einen CIC implementiert hat und sich mal meinen Entwurf anschauen kann?

MFG

Autor: Dipl.-Ing. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

da das CIC vor der Dezimation aus Integratoren besteht, findet eine 
Verstärkung statt.

Gmax = (RM)^N; R -> Dezimationsfaktor, M -> Anzahl der Verzögerer in den 
Combs (sinnvoll ist 1!), N -> Anzahl der Stufen von Integratoren und 
Combs.

Ich habe sowohl CICs als auch SCICs in C und VHDL realisiert und sie 
waren auch Thema meiner Diplomarbeit. Dieser möchte ich hier allerdings 
nicht so streuen.

Wenn Du einen Vorschlag hast, wie ich sie Dir zukommen lassen kann, sag' 
Bescheid.

Gruß

Autor: Dipl.-Ing. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich habe noch die Scilab-Variante entdeckt. Das sollte helfen..
//  ++
//  Die Funktion cicsim() simuliert einen CIC-Dezimator mit
//  den Parametern M, N und R für einen Eingangsvektor x
//  und gibt einen Ausgangsvektor y zurück.
//  --
function [y]=cicsim(x, M, N, R)
  ints=zeros(1,N);
  comb=zeros(N,M+2)
  l = 1;
  // Iteration über alle Samples:
  for i=1:size(x,'*')
    // Integrieren:
    ints = [x(i) ints(1:$-1)] + ints;
    // Dezimieren:
    if (modulo(i,R) == 0) then
      // Differenzieren:
      comb = [[ints($); comb(1:$-1, $)] comb(:, 1:$-1)];
      comb(:, $) = comb(:, 1) - comb(:, $-1);
      y(l) = comb($,$);       l=l+1;
    end
  end
  // Verstärkung kompensieren:
  y = y/int((M*R)^N);
endfunction

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.