| Passwort vergessen?
Sie sind nicht angemeldet. |  Anmelden

Sprache auswählen:

Wumpus-Gollum-Forum von 'Wumpus Welt der Radios'.
Werbefreies Fachforum für Interessierte, Reparateure und Sammler
von Radios, Fernseher, Audio, usw. und deren Umfeld.
Sie sind nicht angemeldet.
 Anmelden

Software Defined Radio
  •  
 1
 1
06.10.17 22:35
HB9 

WGF-Premium-Nutzer

06.10.17 22:35
HB9 

WGF-Premium-Nutzer

Software Defined Radio

Hallo zusammen,

ich habe nach einigen Überlegungen jetzt mit einem Software Defined Radio begonnen. Die grundlegende Theorie dahinter findet man hier: http://www.wumpus-gollum-forum.de/forum/...rie-58_333.html

Als Basis dient ein Nucleo-F446RE-Board von ST Microelectronic. Das hat einen ARM-Cortex-M4 mit 180MHz Takt, A/D- und D/A-Wandler mit 12 Bit Auflösung, mehr als genug RAM und FLASH und auf einem abtrennbaren Teil eine Debug-Schnittstelle mit USB-Anschluss an den PC, und das Ganze ist für weniger als 20 Euro zu haben, also richtig bastlerfreundlich. Ebenfalls nützlich ist der auf dem Debug-Teil integrierte Umsetzer von RS232 nach USB, so bekommt man gratis eine Kommunikationsschnittstelle zu Testzwecken.



Als Entwicklungsumgebung empfehle ich das Atollic-TrueStudio lite, das ist kostenlos erhältlich, die älteren Versionen laufen auch auf Windows XP und das Nucleo-Board wird neben vielen anderen auch unterstützt. Die einzige Stolperstelle ist beim Debugger, hier muss man bei den Einstellungen unbedingt "Serial Wire Debug" aktivieren, sonst funktioniert es nicht. Die Taktfrequenzen kann man so lassen, wie sie sind.

Als erstes habe ich mal die nötige Initialisierung des Prozessors, A/D- und D/A-Wandlers gemacht. Eine Stolperfalle ist hier, dass man für jede Peripheriefunktion zuerst den Takt freigeben muss, bevor man auf die Register zugreifen kann. Daher macht es Sinn, am Anfang mal alle Taktsignale freizugeben, so vergisst man keines, und am Schluss kann man zwecks Energiesparen immer noch nicht benötigte wieder abschalten.
Die Initialisierung der Wandler dagegen ist sehr einfach.

Die Eckwerte des Empfängers sind folgende:
Samplingfrequenz 1MHz, somit Eingangsfrequenzbereich 0..500kHz, so dass die ZF der gängigen AM-Empfänger eingespeist werden kann, auch LW-Empfang ist so mit einem Tiefpassfilter oder abgestimmer Ferritantenne möglich.
Nach dem A/D-Wandler folgt ein I/Q-Mischer mit abstimmbarem numerischen Oszillator, Vorfilterung und Dezimation auf 50kHz Samplingfrequenz, danach steilflankige Filter mit wählbarer Bandbreite und Demodulation, danach Ausgabe auf D/A-Wandler.

Die Vorfilterung und Dezimation erfolgt mit einem 5-stufigen CIC-Filter, das sorgt mit geringem Rechenaufwand für eine Unterdrückung der Frequenzen ab etwa 35kHz, welche durch die Dezimation in den Nutz-Frequenzbereich von 0..10kHz gespiegelt würden. Die anschliessende steilflankige Filterung erfolgt mit einem elliptischen 8poligen IIR-Filter. Da der Prozessor eine Floating-Point-Unit hat, kann dieses Filter mit Floating-Point-Arithmetik gerechnet werden, so können direkt die Filterkoeffizienten aus dem Berechnungs-Tool übernommen werden und man muss sich nicht um Skalierungen sorgen. Hier der Frequenzgang des Filters, als Eingangssignal dient weisses Rauschen, gemessen wurde am D/A-Wandler.



Die Frequenzen sind hier alle um den Faktor 10 zu tief, da ich zwecks besseren Debugmöglichkeiten die Samplingfrequenz auf 100kHz reduziert habe (und so nach Dezimation eine Samplingfrequenz von 5kHz übrigbleibt). Die Eckfrequenz wurde auf 5kHz (500Hz effektiv) gesetzt. Die Filterkurve ist fast perfekt. Der Abfall beginnt bei 5kHz, und bei 40dB Dämpfung liegt die Frequenz bei 5.1kHz, so was schafft analog nur ein Quarzfilter, aber dann wird variable Bandbreite teuer.
Weiter sieht man das Aliasing um die dezimierte Samplingfrequenz von 45..55kHz (4.5 .. 5.5kHz effektiv). Bei 100kHz am rechten Bildrand sieht man die nächste Aliasingfrequenz. Wichtig ist hier, dass es zwischen diesen Aliasingbereichen kein Signal gibt, denn dieses würde auf eine ungenügende Filterung des CIC-Filters deuten.

Hier noch eine FFT-Messung der Signalreinheit mit einem Sinussignal am A/D-Wandlereingang, gemessen wurde wieder am D/A-Wandler:



Das Sinussignal ist beim Cursor 1, bei Cursor 2 ist die dezimierte Samplingfrequenz von 50kHz und links und rechts davon die Aliasfrequenzen. Die erste Harmonische ist noch knapp sichbar und etwa 55dB unter der Grundwelle, was schon recht nahe an der Spezifikation des D/A-Wandlers liegt. Die kleineren Peaks sind Störungen, vermutlich Einkopplungen von digitalen Signalen, da der Messaufbau nicht perfekt ist, aber für erfolgsversprechende Versuche ist die Signalqualität auf jeden Fall ausreichend, und der A/D-Wandler arbeitet sehr sauber.

Für die Berechnung der Filter habe ich das kostenlose Tool "SciLab" gefunden, das bietet ähnliche Funktionen wie Matlab. Die Details folgen noch in Form von Quellcode, Tipps und Messresultaten. Als nächstes ist die Implementation des Mischers und Oszillators dran.

Gruss HB9

Datei-Anhänge
EvalBoard.jpg EvalBoard.jpg (4x)

Mime-Type: image/jpeg, 117 kB

Filter5k.PNG Filter5k.PNG (3x)

Mime-Type: image/png, 14 kB

Sinus.PNG Sinus.PNG (3x)

Mime-Type: image/png, 13 kB

!
!!! Keine Links auf gewerbliche WEB-Seiten oder Internet-Auktionen! ... mehr dazu

!!! Photos, Graphiken nur über die Upload-Option des Forums.        !!! Keine Komplett-Schaltbilder, auf denen Urheberrechte Anderer liegen!

Nicht nur den neuesten Beitrag eines Threads lesen.
07.10.17 00:37
BernhardWGF

nicht registriert

07.10.17 00:37
BernhardWGF

nicht registriert

Re: Software Defined Radio

HB9:

Als Entwicklungsumgebung empfehle ich das Atollic-TrueStudio lite, das ist kostenlos erhältlich, die älteren Versionen laufen auch auf Windows XP und das Nucleo-Board wird neben vielen anderen auch unterstützt.


Vielleicht habe ich es schon erwähnt, nocheinmal kann aber nicht schaden. Das TrueStudio erzeugt aus dem Project-Wizard heraus und für die Discoveryboards von STM eine falsche PLL-Konfiguration. Dort wird immer von einem Taktgeber mit 25 MHz ausgegangen, auf den Boards ist aber nur ein 8-MHz Quarz verbaut! Ich kann mich jetzt nicht erinnern ob das bei den Nucleo-Boards auch so ist. Also vorher immer schauen ob die PLL-Einstellungen stimmen. Alternativ kann die "System-Workbench for STM32" http://www.st.com/en/development-tools/sw4stm32.html und http://www.openstm32.org/HomePage
genutzt werden. Im Prinzip auch eine Eclipse IDE mit dem gcc/g++ Compiler und komplett kostenlos. Dort stimmen die PLL-Einstellungen für die Discoveryboards direkt nach dem Anlegen eines neuen Projektes. Eine zusätzliche händische Korrektur in den Projektdateien für eine richtige PLL-Einstellung ist dann nicht nötig.

Gruß
Bernhard

Zuletzt bearbeitet am 07.10.17 00:41

07.10.17 18:57
joeberesf 

WGF-Premium-Nutzer

07.10.17 18:57
joeberesf 

WGF-Premium-Nutzer

Re: Software Defined Radio

Hallo HB9,

wenn Du das Projekt positiv abschließen kannst, gehst Du damit auch online? Also können wir uns zu Deinem SDR- Radio verbinden?
Ich finde das echt spannend. Meine Favoriten kannst Du hier finden.

http://www.websdr.org/

Gruß

Joerg

PS. Ich prokle gerade softwaremäßig an einem Schaltfeld mit Setzen und Rücksetzen von Ausgängen bei gleichzeitiger Kalender und Uhranzeige. Mega 2560 mit TFT - Touch. Das sind alles Studien zum letztendlich angestrebten "Morsedekodierungskästchen" mit ein bisschen Beiwerk. Hier bin ich z. Zt. an meine Grenzen gestoßen und probiere Varianten, welche ich aus Demovorlagen kombiniere und ergänze. Wichtig ist....das man immer wieder Lösungen findet.

Zuletzt bearbeitet am 07.10.17 19:19

08.10.17 16:42
HB9 

WGF-Premium-Nutzer

08.10.17 16:42
HB9 

WGF-Premium-Nutzer

Re: Software Defined Radio

Hallo zusammen,

es geht weiter. Zuerst zu Bernhard: Ich programmiere die Initialisierung des Prozessors grundsätzlich selber, da ich bisher immer schlechte Erfahrungen mit mitgeliefertem Code gemacht habe, entweder ineffizient oder auch schlicht falsch. Eine falsche Taktfrequenz merkt man noch schnell, aber bei einem falschen Interrupthandler sucht man dann tagelang sporadische Fehler
Die Nucleo-Boards haben ebenfalls einen 8MHz-Takt.

Zu Joerg: Die Hard- und Software wird selbstverständlich hier eingestellt. Online ist der Empfänger aber nicht, hier geht es darum, ein 'gewöhnliches' Radio mit sehr gutem Empfang zu bauen, und für die ZF-Verarbeitung bietet sich ein Prozessor an, so hat man gewisse Freiheiten wie variable Bandbreite oder auch adaptive Störunterdrückung. Betreibt man den SDR an der ZF eines bestehenden Empfängers, ist der Hardware-Aufwand sehr klein. So kann ein durchscnittlicher Empfänger in ein Spitzengerät verwandelt werden.

Heute habe ich den Interrupthandler optimiert, jetzt braucht er nur noch etwa 75% der Rechenleistung inklusive AM-Hüllkurvendemodulator. Somit kann wie geplant mit 1MHz Samplingfrequenz gearbeitet werden. Weiter habe ich dem A/D-Wandler auf den Zahn gefühlt, der macht eine ganz gute Falle, wie die beiden Messungen zeigen. Das Eingangssignal war ein amplitudenmodulierter Träger mit maximalem Pegel, gemessen wurde das demodulierte Signal vom D/A-Wandler. Die Empfangsfrequenz war auf 490kHz eingestellt.

Eingang 490kHz (also kein Aliasing):


Eingang 10.49MHz, also eine Aliasfrequenz:


Das Signal ist ein paar wenige dB schwächer, und das Grundrauschen hat etwa 15dB zugenommen, da hier die Ungenauigkeit der Samplingzeitpunkte sichtbar wird, aber für nicht allzu hohe Ansprüche durchaus noch brauchbar. Somit kann man die analoge ZF durchaus auch in einen Bereich über 500kHz legen, einfach mit genug Abstand zu den Vielfachen von 500kHz.

Zur Software: Um etwas Assembler kommt man nicht herum, da der C-Code zu ineffizient wird, in C ist bei einer Abtastrate von etwa 100kHz Schluss. Da dieser aber sehr einfach ist, sollte er mindestens verstanden werden, wenn er dann noch schön kommentiert ist, er folgt später.
Die Funktion ist folgende:
Per DMA (Direct Memory Access) werden die Samples im 1MHz-Takt vom A/D-Wandler in den Speicher befördert, so hat der Prozessor hier nichts zu tun. Um die Effizienz zu steigern, wird nicht jedes einzelne Sample sofort bearbeitet, sondern erst wenn alle Eingangs-Samples eingetroffen sind, die für ein Ausgangs-Sample nötig sind, hier also 20 (Dezimationsfaktor 20). So gibt es nur 1/20 der Interrupts, und man spart sich viel Overhead beim Sichern und Wiederherstellen des Prozessorzustandes.

Im Interrupt, der jeweils nach 20 Samples, also im 50kHz-Takt, kommt, müssen die 20 Cosinus- und Sinuswerte für die I- und Q-Mischung bestimmt, die Samples mit diesen Werten multipliziert und danach gefiltert werden. Nach der Dezimation (dann hat man nur noch ein Sample für I und Q) folgt das steilflankige BiQuad-Filter und die Demodulation und Ausgabe des Samples an den D/A-Wandler, danach ist der Interrupt beendet.

Das CIC-Filter für den ersten Tiefpass vor der Dezimation ist 5stufig, damit es kein Aliasing beim Dezimieren gibt. 4 Stufen würden zwar knapp reichen (ca. 52dB minimale Dämpfung), aber es soll ja ein Spitzenradio werden. Der kritische Bereich ist dabei zwischen der dezimierten Abtastfrequenz und dem doppelten Wert, hier also bei etwa 70kHz, siehe Bild (0.1 entspricht 50kHz):


Die grüne Kurve ist der Frequenzgang eines einstufigen CIC-Filters, die blaue für 4 Stufen und die rote für 5 Stufen. Da ein CIC-Filter eine von der Stufenzahl und Dezimation abhängige Verstärkung hat, braucht es hier 64bit-Arithmetik, was nicht gerade zur Effizienz beiträgt, aber machbar ist. Die genaue Beschreibung folgt in einem späteren Beitrag. Ein Vorteil vom CIC-Filter ist der, dass nur ein Teil der Berechnungen mit allen Eingangs-Samples gemacht werden muss, und ein grösserer Teil wird nach der Dezimation berechnet, wo nur noch ein Sample vorhanden ist. Der Nachteil ist die eher bescheidene Filterkurve, aber hier muss nur Aliasing im Bereich der dezimierten Abtastfrequenz (also 50kHz, 100kHz, usw.) verhindert werden, und hier ist die Dämpfung sehr gross, wenn man die Bandbreite des folgenden Filters klein hält, hier max. 10kHz,

Am Schluss noch ein Hinweis: Die Ausgabe auf dem D/A-Wandler muss ebenfalls exakt periodisch erfolgen. Da die Software aber nicht immer exakt gleich lange Ausführungszeit hat, muss die effektive Ausgabe über einen Hardware-Trigger erfolgen, z.B. ein Timer-Ereignis.

Als nächstes wird ein 'echtes' HF-Signal eingespeist, z.B. die ZF eines AM-Empfängers.

Gruss HB9

Datei-Anhänge
490kHz.PNG 490kHz.PNG (3x)

Mime-Type: image/png, 10 kB

10MHz.PNG 10MHz.PNG (2x)

Mime-Type: image/png, 11 kB

CIC.png CIC.png (2x)

Mime-Type: image/png, 7 kB

08.10.17 17:11
HB9 

WGF-Premium-Nutzer

08.10.17 17:11
HB9 

WGF-Premium-Nutzer

Re: Software Defined Radio

Hallo zusammen,

hier noch die Beschreibung, wie ein CIC-Filter funktioniert. Ein CIC-Filter ist ein Tiefpass mit der Besonderheit, dass er der Ausgangs-Samplingfrequenz und deren Vielfachen eine Nullstelle, also unendliche Dämpfung hat. Geht man weiter davon aus, dass man nur eine relativ kleine Nutzbandbreite hat, kann man so die Samplingfrequenz reduzieren, ohne dass es Aliasing gibt. Nehmen wir dazu folgendes Beispiel: Samplingfrequenz fs1 am Eingang = 2MHz und am Ausgang (also nach der Dezimation) 100kHz. Das ergibt dann folgende Filterkurve:


Nehmen wir nun die blaue Kurve (4stufiges Filter). Hier sieht man, dass im Bereich ca. 0.09..0.11MHz die Dämpfung besser als 70dB ist, also kein Aliasing entstehen kann. Ist nun die Nutzbandbreite 10kHz und wird nach der Dezimation steilflankig mit 10kHz Bandbreite gefiltert, gibt es kein Aliasing, denn die Aliasfrequenzen 50..90kHz und 110..170kHz werden von diesem Filter beseitigt, da sie auf Frequenzen über 10kHz gespiegelt werden. Somit sieht man auch die Grenzen: Die Samplingfrequenz muss auch nach der Dezimation noch viel höher als die Bandbreite sein (hier das 10fache).

Die Implementation ist einfach, hier ein einstufiges Filter:

- Die Eingangs-Samples werden aufaddiert.
- Sobald die dem Dezimationsfaktor entsprechende Anzahl Samples aufaddiert sind, wird ein Ausgangssample als Differenz dieser Summe und der Summe beim letzten Ausgangs-Sample gebildet.

In C sieht das so aus, die Berechnung wird für jedes Eingagns-Sample ausgeführt:

int Summe, Alte_Summe;

void CIC(void)
{
Summe = Summe + Sample;
Anzahl_Samples = AnZahl_Samples + 1;
if (Anzahl_Samples == Dezimationsfaktor)
{ // Aisgamgs-Sample berechnen
Anzahl_Samples = 0;
Ausgang = Summe - Alte_Summe;
Alte_Summe = Summe;
}
}

Für ein mehrstufiges Filter werden einerseits die Summierer (Integratoren) und nach der Dezimation die Differenzierer hintereinandergeschaltet, hier ein 3stufiges Filter:


int Summe1, Summe2, Summe3, Alte_Summe1, Alte_Summe2, Alte_Summe3;

void CIC3(void)
{
int x1, x2;
Summe1 = Summe1+ Sample;
Summe2 = Summe2+ Summe1;
Summe3 = Summe3+ Summe2;
Anzahl_Samples = AnZahl_Samples + 1;
if (Anzahl_Samples == Dezimationsfaktor)
{ // Aisgamgs-Sample berechnen
Anzahl_Samples = 0;
x1 = Summe3 - Alte_Summe3;
Alte_Summe3 = Summe3;
x2 = x1 - Alte_Summe2;
Alte_Summe2 = x1;
x1 = x2 - Alte_Summe3;
Alte_Summe3 = x2;
Ausgang = x1;
}
}

Man sieht schön, wie der grösste Teil des Programms (alles im 'if'-Pfad) mit der Ausgangs-Samplingfrequenz berechnet wird und mit der Eingagns-Samplingfrequenz nur die Summenbildung erfolgt.
Alternativ kann man zuerst alle Samples in einem Array ablegen und dann die Summierung in einer Schleife erledigen:

nt Summe1, Summe2, Summe3, Alte_Summe1, Alte_Summe2, Alte_Summe3;

void CIC3(void)
{
int x1, x2, i;

for (i = 0; i < Dezimationsfaktor; i = i + 1)
{
Summe1 = Summe1+ Sample[i];
Summe2 = Summe2+ Summe1;
Summe3 = Summe3+ Summe2;
}
// Aisgamgs-Sample berechnen
x1 = Summe3 - Alte_Summe3;
Alte_Summe3 = Summe3;
x2 = x1 - Alte_Summe2;
Alte_Summe2 = x1;
x1 = x2 - Alte_Summe3;
Alte_Summe3 = x2;
Ausgang = x1;
}

Bei den Datentypen ist zu beachten, dass das Filter eine ordentliche Verstärkung hat. Ein Filter der Stufenzahl n und Dezimationsfaktor k hat folgende Verstärkung:

G = k^n

Nehmen wir also ein 3stufiges Filter und ein Dezimationsfaktor von 10, ergibt das eine Verstärkung G = 10^3 = 1000. Hat man am Eingang 12 Bit grosse Samples, muss man mit 32 Bit rechnen, da die Ausgangswerte 1000*Eingangswert sind. Ebenfalls wichtig ist, dass mit 'int'-Typen gerechnet wird (int, short, long int, long long int), mit 'float' wird es falsch!

Gruss HB9

Zuletzt bearbeitet am 08.10.17 17:31

Datei-Anhänge
CIC.png CIC.png (3x)

Mime-Type: image/png, 7 kB

14.10.17 16:29
HB9 

WGF-Premium-Nutzer

14.10.17 16:29
HB9 

WGF-Premium-Nutzer

Re: Software Defined Radio

Hallo zusammen,

es geht weiter. Heute habe ich das SDR mal testweise an die ZF eines AM-Superhets angeschlossen. Die Filterung und Tonqualität waren sehr gut, wie zu erwarten, aber der nicht gerade HF-taugliche Aufbau sorgte je nach Frequenz für beachtliche Störgeräusche. Für den praktischen Einsatz fehlt auch noch die Schwundregelung.

Nach dem CIC-Filter folgt jetzt die Beschreibung des IIR-Filters, das die eigentliche Selektion macht. Hier ist zu beachten, dass der Prozessor eine endllche Rechengenauigkeit hat und somit bei ungeschickter Auslegung des Filters Müll herauskommt. Aus diesem Grund wird nicht ein 8-poliges Filter implementiert, sonder 4 2-polige hintereinandergeschaltet, genau so, wie man es auch analog macht. Ein zweipoliges Filter rechnet wie folgt:

y(n) = b0 * x(n) + b1 * x(n-1) + b2 * x(n-2) - a1 * y(n-1) - a2 * y(n-2)

Dabei ist x(n) das aktuelle Eingangs-Sample, x(n-1) das vom letzen Samplingzeitpunkt und x(n-2) das vom vorletzten Samplingzeitpunkt. Entsprechend ist y(n) das aktuelle Ausgangs-Sample, y(n-1) das vom letzten und y(n-2) das vom vorletzten Samplingzeitpunkt. a() und b() sind die Filterkoeffizienten, die z.B. mit SciLab oder Matlab berechnet werden können.
Somit braucht man also zur Berechnung neben dem aktuellen Eingangs-Sample noch die beiden letzten Ein- und Ausgangs-Samples, also müssen insgesamt 4 Werte gespeichert werden. Die beiden a-Koeffizienten sind dabei Rückkopplungsfaktoren, während die b-Koeffizienten die Vorwärts-Verstärkungsfaktoren bilden. In der Praxis werden die Produkte a*y häufig ebenfalls addiert, ich habe aber die Subtraktion gewählt, weil in der Theorie subtrahiert wird und so die Vorzeichen der a-Parameter aus den Berechnungs-Tools nicht korrigiert werden müssen. Um keine Probleme mit Ungenauigkeiten und Overflows zu bekommen, wird dieses Filter mit Fliesspunkt-Arithmetik gerechnet, da der Cortex-M4 das kann (aber nur mit einfacher Genauigkeit, also 'float' und nicht 'double'), und das sogar sehr effizient.
In C sieht das dann so aus:

// Berechnung einer Biquad-Stufe (2poliges Filter)
// input: Eingangssignal, Biq_Par: Pointer auf Parameter, Biq_State: Pointer auf Zustand
// Biq_Par: b0, b1, b2, a1, a2
// Berechnung: y = b0 * input + b1 * State(0) + b2 * State(1) - a1 * State(2) - a2 * State(3)
// State(3) <- State(2), State(2) <- y, State(1) <- State(0), State(0) <- input
float BiQuad_Stage(float input, float *Biq_Par, float *Biq_State)
{
float y;

y = Biq_Par[0] * input + Biq_Par[1] * Biq_State[0] + Biq_Par[2] * Biq_State[1]
- Biq_Par[3] * Biq_State[2] - Biq_Par[4] * Biq_State[3];
Biq_State[1] = Biq_State[0];
Biq_State[0] = input;
Biq_State[3] = Biq_State[2];
Biq_State[2] = y;
return y;
}

Für die Hintereinanderschaltung wird die Funktion einfach mehrfach aufgerufen, jeweils mit dem Resultat des vohergehenden Aufrufs als Eingangsgrösse, dabei müssen für jede Filterstufe separate Speicher für die alten Ein- und Ausgangswerte vorhanden sein. Für eine optimale Filterung sind auch die Koeffizienten für die einzelnen Filterstufen unterschiedlich.

Mit dieser Struktur kann jedes 'normale' Filter (Hoch- und Tiefpass, Bandpass, Notch) gebildet werden. Bei einem extremen Verhältnis Eckfrequenz/Samplingfrequenz funktioniert das Filter nicht mehr, bei dem von mir gewählten elliptischen Filter unter etwa 0.01, daher ist die tiefste Eckfrequenz 500Hz.

Als Filterfunktion eignet sich am besten ein elliptisches Filter, da dieses die steilsten Filterflanken hat, allerdings ist dafür die Sperrdämpfung nicht beliebig gross, und je steilflankiger, desto geringer die Sperrdämpfung. Mit einem 8-poligen Filter erreicht man aber sehr hohe Flankensteilheit bei Sperrdämpfungen von 60..80dB, was völlig ausreichend ist. Im Gegensatz zur Analogtechnik kann man hier auch verschiedene Koeffizienten im Speicher haben und so je nach Bedarf zwischen verschiedenen Filtern umschalten, so ist auch eine Bandbreitenumschaltung sehr einfach.

Mit 'SciLab' (kostenlos im Internet beschaffbar, sogar für Windows XP) kann man mit dem im angehängten File ein C-File mit den Filterkonstanten für Eckfrequenzen von 500Hz..10kHz (bei 50kHz Samplingfrequenz) bilden. Die Endung 'txt' muss in 'sci' geändert werden. Der Übergabeparameter ist die Sperrdämpfung in dB, ein sinnvoller Wert ist 60..80. Da die Verstärkung des Filters von der Eckfrequenz abhängt, ist jeweils noch vor den Filterkoeffizienten der Skalierungsfaktor (Gain), mit dem das Ein- oder Ausgangssignal für eine Gesamtverstärkung von 1 multipliziert wird. Die Koeffizienten sind für ein 8-poliges Filter, also vier Filterstufen hintereinander mit je 5 Koeffizienten, somit insgesamt 21 Werte pro Eckfrequenz (4*5 Koeffizienten + Gain).

Als Nächstes folgen der Oszillator mit Mischer, Demodulation und Schwundregelung, dann sind alle wichtigen Blöcke zusammen.

Gruss HB9

Zuletzt bearbeitet am 14.10.17 16:35

Datei-Anhänge
iirparameter2.txt iirparameter2.txt (4x)

Mime-Type: text/plain, 2 kB

14.10.17 21:16
HB9 

WGF-Premium-Nutzer

14.10.17 21:16
HB9 

WGF-Premium-Nutzer

Re: Software Defined Radio

Hallo zusammen,

noch eine wichtige Anmerkung zu Fliesspunkt-Arithmetik. Im Gegensatz zu Integer-Arithmetik gibt es hier auch die 'Werte' unendlich (inf) und 'not a Number' (NaN), was nichts anderes als das Ergebnis einer illegalen Operation ist. In der Signalverarbeitung sollten diese beiden Resultate natürlich nicht vorkommen. Kommt es aber trotzdem mal vor, hat man das Problem, dass man diesen Zustand nicht mehr los wird, denn fast jedes Filter und auch jeder Regelkreis hat eine Rückkopplung, und hier ist das Problem. Egal welche Operation, ein 'NaN' bleibt ein 'NaN', und 'Inf' bleibt 'Inf' oder wird 'NaN'. Das bedeutet für die Signalverarbeitung, dass illegale Operationen vermieden werden müssen. Wegen des sehr grossen Dynamikbereiches besteht bei Addition, Subtraktion und Multiplikation keine Gefahr, während eine Division bereits heikel sein kann, wenn der Division fast Null ist und so das Resultat zu gross wird. Bei der Quadratwurzel muss peinlich darauf geachtet werden, dass der Operand nie negativ sein kann (kann z.B. durch Rundungsfehler passieren).
Eine andere Stolperfalle sind instabile Rückkopplungen (z.B. numerisch instabile Filter oder instabile Regelschleifen). Falls man nicht explizit in der Schleife die Signalwerte begrenzt, wachsen sie an, bis der darstellbare Bereich von 'float' nicht mehr reicht und als Folge 'Inf' und daraus 'NaN' entsteht.

Beachtet man diese Fallstricke, ist Fliesspunkt-Arithmetik für digitale Signalverarbeitung eine feine Sache, was man auch an der immer grösseren Zahl 'echter' Floating-Point-Signalprozessoren sieht.

Gruss HB9

15.10.17 17:08
HB9 

WGF-Premium-Nutzer

15.10.17 17:08
HB9 

WGF-Premium-Nutzer

Re: Software Defined Radio

Hallo zusammen,

nach ein paar erfolgreichen Versuchen mit einer Vorwärts-Schwundregelung (AGC) habe ich den Empfänger so weit zusammen, dass es Zeit für ein Blockschema ist:



Der grüne Teil arbeitet mit der Samplingfrequenz vom A/D-Wandler (1MHz) und der gelbe Teil mit der dezimierten Samplingfrequenz von 50kHz.

Zuerst ist links das analoge HF-Frontend (das noch nicht existiert). Falls man nur Frequenzen unterhalb 500kHz empfangen will, reicht hier ein Tiefpassfilter zur Verhinderung von Aliasing, sowie ein Verstärker mit allenfalls umschaltbarer Verstärkung. Für Frequenzen über 500kHz ist das HF-Frontend ein klassischer Mischer und das vorgefilterte ZF-Signal gelangt an den A/D-Wandler.

Nun kommt das Signal an den A/D-Wandler (ADC), hier wird der interne Wandler verwendet, der immerhin 12 Bit Auflösung hat. Für einen Spitzenempfänger kann man einen externen Wandler mit 16 oder gar 24 Bit verwenden, so hat man mehr Dynamik und braucht keine Verstärkungsregelung im analogen Teil.

Nach dem A/D-Wandler folgen die beiden Mischer, welche das Eingangssignal mit den beiden um 90° phasenverschobenen Oszillatorsignalen multiplizieren und so die beiden Basisbandsignale I (in Phase) und Q (Quadratur) liefern. Der Oszillator ist als DDS-Oszillator realisiert, da dies in Software sehr einfach geht und eine sehr feine Frequenzauflösung ergibt, so dass auch Synchrondemodulation möglich wird. Da die Berechnung des Sinus viel zu lange dauern würde, wird hier eine Tabelle mit 4096 Einträgen verwendet. Für die cos- und sin-Werte reichen 16 Bit Genauigkeit. Im Gegensatz zu einem 'normalen' Superhet wird hier auf 0Hz Zwischenfrequenz gemischt.

Das I- und Q-Signal werden in zwei identischen Pfaden tiefpassgefiltert und auf 50kHz Samplingrate reduziert, also nur jedes 20. Sample erscheint am Ausgang. Die erste Filterstufe ist ein 5stufiges CIC-Filter, welches auch die Dezimation macht und nur dafür sorgt, dass keine Alias-Frequenzen in den Nutzbereich von 0..10kHz fallen (also die Frequenzbereiche 40..60kHz, 90..110kHz, usw. unterdrück werden). Das anschliessende 8-polige IIR-Filter macht die eigentliche Selektion und kann durch Wechsel der Filterparameter in der Bandbreite verändert werden, vorgesehen sind Bandbreiten von 500Hz..10kHz. Hier ist zu beachten, dass gegenüber dem konventionellen Superhet die Bandbreite nur halb so hoch ist, da das ZF-Signal frequenzmässig symmetrisch um 0Hz liegt. Damit man so keine Information verliert, braucht es die beiden Signalpfade I und Q, welche als Vektor aufgefasst werden können.

Die Hüllkurvendemodulation ist nichts anderes als die Bestimmung der Länge des Vektors, der aus I und Q gebildet wird. Da I und Q senkrecht zueinander stehen, ergibt sich die Länge nach Pythagoras zu (I*I + Q*Q). Vom demodulierten Signal wird einmal mit einem Tiefpass der DC-Anteil zwecks Verstärkungsregelung gewonnen, genau gleich wie in der Analogtechnik. Hier wird aber keine Feedback-Regelung gemacht, sondern eine reine Vorwärtsregelung. Das ist möglich, weil digital exakt multipliziert und dividiert werden kann. Multipliziert man nämlich das demodulierte Signal mit dem Kehrwert der Trägeramplitude (also dem DC-Anteil), bekommt man ein konstantes Signal. Das macht der Block 'AGC'.

Das so amplitudenkorrigierte NF-Signal durchläuft noch einen Hochpass zur Abtrennung des DC-Anteils vom Träger (der Koppelkondensator in der Analogtechnik) und kommt danach durch den D/A-Wandler wieder zurück in die reale Welt. Durch die hohe Samplingfrequenz von 50kHz reicht analog ein simpler Tiefpass, um den Verstärker nicht mit den Aliasing-Frequenzen zu belästigen, die bei 90kHz beginnen.

Eine AM-Synchrondemodulation ist ebenfalls einfach möglich. Dazu wird das Q-Signal als Istwert für einen Regler verwendet, der die Oszillatorfrequenz so nachregelt, dass Q Null wird (eine klassische PLL-Regelung). Das demodulierte Signal ist dann das I-Signal. Dabei ist es recht einfach, den Oszillator mit einem schnellen Regler 'einzufangen' und im phasenstarren Zustand nur sehr langsam zu regeln, so dass es keine FM-Störungen durch Regelvorgänge gibt.

Die Auslastung des Prozessors beträgt momentan etwa 70%, somit ist noch einige Reserve für SSB-Demodulation, CW-Dekodierung, Störausblendung, Klangregelung und andere Spielereien vorhanden, zudem gibt es noch etwas Optimierungspotential. Weiter kann die Rechenlast auch reduziert werden, indem man einen höheren Dezimierungsfaktor wählt, z.B. 1:25, dann gibt es 40kHz Samplingfrequenz. Ebenfalls möglich ist eine weitere Dezimierung nach dem IIR-Filter auf z.B. 25kHz, was aber mit einem erhöhten Aufwand für das Analogfilter nach dem DAC erkauft wird. Für die Auswertung von CW-Signalen kann die Samplingrate massiv reduziert werden, da hier eine Bandbreite von 500Hz reicht.

Gruss HB9

Zuletzt bearbeitet am 15.10.17 17:22

Datei-Anhänge
Blockschema.png Blockschema.png (1x)

Mime-Type: image/png, 81 kB

 1
 1
Morsedekodierungskästchen   Kommunikationsschnittstelle   Ausgangs-Samplingfrequenz   AM-Synchrondemodulation   Floating-Point-Arithmetik   Eingangsfrequenzbereich   Hüllkurvendemodulation   hintereinandergeschaltet   Eingagns-Samplingfrequenz   AM-Hüllkurvendemodulator   Floating-Point-Signalprozessoren   Rückkopplungsfaktoren   Samplingfrequenz   Fliesspunkt-Arithmetik   Vorwärts-Schwundregelung   Dezimationsfaktor   Verstärkungsregelung   Dezimation   Vorwärts-Verstärkungsfaktoren   amplitudenkorrigierte