Hallo,
bevor ich auf die programmiertechnischen Probleme komme (und damit zum
eigentlichen µC-Problem), vielleicht erstmal eine Vorabeinschätzung
eurerseits.
Ich möchte mit meiner Schaltung einen hochfrequenten, speziell geformten
Impuls erzeugen, der einer recht komplizierten, aber fixen
mathematischen Funktion gehorcht. Das geht dann per SPI an einen
D/A-Wandler und dann... nun, darüber zerbreche ich mir meinen Kopf, wenn
ich soweit bin.
Nun habe ich gelesen, dass die CPU des µC das nicht in Echtzeit
berechnen sollte, sondern dass man lieber eine Wertetabelle erzeugt und
aus dieser jeweils den benötigten Wert auslesen lässt.
Anscheinend scheitere ich aber schon am Sampling (Nyquist). Die höchste
Frequenz, die in meinem 4ms-langen Puls vorkommt, beträgt 31,5kHz. Für
mich rechnet sich das dann so:
31500*2 = 63000; Das entspricht einer Abtastung pro 16µs.
Wenn ich nun 4ms lang abtaste, und zwar alle 16µs, dann komme ich auf
252 Abtastwerte. Diese Werte spuckt mir mein Matheprogramm (Maple) aus
und Excel visualisiert sie mir dann. Das ist aber keineswegs die Kurve,
die ich in Maple sehe. Auch, wenn ich mit dem Faktor 2,2 f sample, ist
das Aliasing ganz stark sichtbar. Was mache ich hier falsch?
Wenn ich jetzt tatsächlich mehr Werte für die Wertetabelle brauchen
sollte -- ab 4stellig wird es erst schön --, reicht mir der
SRAM-Speicher aber nicht mehr aus. Nur der Flash-Speicher ist groß
genug. Aber ist der auch schnell genug? Oder ist der überhaupt dafür da,
um zur Laufzeit dort "permanent" Werte auszulesen?
Ist leider etwas länger geworden, aber trotzdem Danke schon mal :)
> Ich möchte mit meiner Schaltung einen hochfrequenten...Impuls erzeugen> Die höchste Frequenz, die in meinem 4ms-langen Puls vorkommt,> beträgt 31,5kHz.
Ja wass denn nun, hochfrequent, oder niederfrequent?
> Diese Werte spuckt mir mein Matheprogramm (Maple) aus> und Excel visualisiert sie mir dann. Das ist aber keineswegs> die Kurve, die ich in Maple sehe.
Zeig doch mal her!
> Was mache ich hier falsch?
Ohne Einblick in Deine Ergebnisse zu bekommen, können wir alle nur
Raten.
Die Abtastrate hängt von der höchsten Frequenz ab, die im Signal
enthalten ist, wie Du schon geschrieben hast. Diese höchste Frequenz
muss ein Sinus Signal sein.
In der Relität hast Du aber immer Frequenzen außerhalb des gewünschten
bereiches, denn das Gesamt-Signal ist ja kein reiner Sinus. Daher
filtert man das Signal durch einen Tiefpass.
Auch das Ausgangssignal des D/A Wandler filtert man durch einen
Tiefpass.
Wenn die Tiefpässe perfekt funktionieren, kommt nach Deiner A/D->D/A
Wandlung wieder genau das ürsprüngliche Signal heraus (abzüglich der weg
gefilterten oberen Frequenzen).
> Flash-Speicher ist groß genug. Aber ist der auch schnell genug?
Vermutlich nicht, wenns um Schreibzugriffe geht. Da musst Du einen
RAM-Puffer vorschalten.
> Oder ist der überhaupt dafür da, um zur Laufzeit dort "permanent"> Werte auszulesen?
Ja, das ist kein Problem.
Es gibt übrigens statische RAM's mit serieller (SPI) Schnittstelle -
sehr praktisch für Mikrocontroller.
Okay, vielleicht war das "hochfrequent" etwas hochgegriffen. Ich empfand
das durchaus als viel. ;)
Ich hab mal zwei Bild angehängt, die sagen eigentlich schon alles aus.
Die y-Einheiten sind willkürlich, die x-Achse ist Zeit in Sekunden.
Unter dem Gauß steckt ein Sinus, der in der Frequenz ganz leicht
ansteigt. Bei 4ms beträgt die Frequenz besagte 31,5kHz. Das zweite Bild
zeigt das Aliasing, wenn ich die Wertetabelle wieder zu einem Graphen
mache.
Von statischem RAM habe ich bisher nichts gehört, aber laut Pin-Belegung
hat der ATMega16 eh nur ein SPI, das ich aber schon für den DAC brauche.
Zu FPGAs hat man mir auch schon geraten, allerdings fehlen mir da noch
vollkommen die Erfahrungen.
SPI ist ein Bus und mit den CS Pins wird das Slavegerät ausgewählt.
Also Flash/RAM und DAC an einem SPI ist kein Problem.
Welches ist denn die geringste Frequenz unterm Gauss?
Das geht ja iwie von xxkHz bis zu den 31,5kHz.
@ Peder (Gast)
>Anscheinend scheitere ich aber schon am Sampling (Nyquist). Die höchste>Frequenz, die in meinem 4ms-langen Puls vorkommt, beträgt 31,5kHz. Für>mich rechnet sich das dann so:>31500*2 = 63000; Das entspricht einer Abtastung pro 16µs.
Das ist die Theorie. Praktisch wird man eher das Doppelte brauchen, denn
es gibt keinen unendlich steilen Anti-Aliasing Filter.
>Wenn ich nun 4ms lang abtaste, und zwar alle 16µs, dann komme ich auf>252 Abtastwerte.
Nicht viel.
>die ich in Maple sehe. Auch, wenn ich mit dem Faktor 2,2 f sample, ist>das Aliasing ganz stark sichtbar. Was mache ich hier falsch?
Du hast keinen Anti-Aliasing Filter.
>Wenn ich jetzt tatsächlich mehr Werte für die Wertetabelle brauchen>sollte -- ab 4stellig wird es erst schön --, reicht mir der>SRAM-Speicher aber nicht mehr aus. Nur der Flash-Speicher ist groß>genug. Aber ist der auch schnell genug?
Er ist fast so schnell Wie der SRAM. Ein Lesezugriff dauer 3 Takte, beim
SRAM sind es 2.
>Oder ist der überhaupt dafür da,>um zur Laufzeit dort "permanent" Werte auszulesen?
Was denn sonst? KLAR!
Wenn wir mal grob die Abtastrate mit 200ksmps ansetzen sind das
5us/Sample. Das kann man gerade noch per SPI an einen DAC schicken. Dann
ist die CPU aber zu 100% beschäftigt für die 4ms.
@Martin
Stimmt, an die Master/Slave-Möglichkeit habe ich gar nicht gedacht.
Damit wird die Zielstrecke immer dichter. Nur der Start hapert noch. ^^
Die Frequenz steigt linear von 28,5kHz bis zu 31,5kHz an.
@Falk
Ich bin testweise irgendwie bei 2500 Samples für die 4ms stehen
geblieben, damit bin ich bei 1,6µs/Sample. Das ist schon deutlich
weniger als deine veranschlagten 5µs. Der µC läuft mit 7,37MHz, meinst
du, der kriegt das trotzdem hin?
Prinzipiell stelle ich mir das Programm so vor, dass "nur" ein simpler
Counter läuft. Der zählt tatsächlich nicht weit hoch -- bis 11 etwa --,
was dann einen Interrupt auslöst. Die ausgelöste Routine liest dann den
benötigen Wert ein und gibt ihn an den DAC weiter. Das ist alles. Und
das soll er nur einmal machen, wenn ein bestimmter Pin von außen auf HI
gesetzt wird. Dann kann er sich wieder 'ne Weile ausruhen.
Um schon mal langsam in Richtung Programmierung zu gehen: Wie speichere
ich diese Tabelle? Mein Instinkt sagt mir, als Array. Aber normalerweise
liegen diese Arrays dann komplett im Arbeitsspeicher und nicht "extern"
irgendwo. Und für den Arbeitsspeicher wäre das dann zu groß. Wie löst
man das normalerweise? Per Direktzugriff mit Pointer? Ehrlich gesagt
mache ich immer einen sehr weiten Bogen um diese Dinger!
@ Peder (Gast)
>Ich bin testweise irgendwie bei 2500 Samples für die 4ms stehen>geblieben, damit bin ich bei 1,6µs/Sample. Das ist schon deutlich>weniger als deine veranschlagten 5µs. Der µC läuft mit 7,37MHz, meinst>du, der kriegt das trotzdem hin?
Schon mal überlegt, wieviel Takte da pro Sampe zur Verfügung stehen?
1,6us * 7,3 MHz ~12 Takte. Es gibt Einige clevere Sachen in Assembler,
die schaffen das, aber nicht per SPI und DAC, sondern direkt über
IO-Pins und einen R2R DAC.
http://www.myplace.nu/avr/minidds/index.htm>Prinzipiell stelle ich mir das Programm so vor, dass "nur" ein simpler>Counter läuft. Der zählt tatsächlich nicht weit hoch -- bis 11 etwa --,>was dann einen Interrupt auslöst. Die ausgelöste Routine liest dann den>benötigen Wert ein und gibt ihn an den DAC weiter. Das ist alles.
Jaja, und das dauer alles nur einen Takt?!?
>ich diese Tabelle? Mein Instinkt sagt mir, als Array.
Sicher.
> Aber normalerweise>liegen diese Arrays dann komplett im Arbeitsspeicher und nicht "extern">irgendwo. Und für den Arbeitsspeicher wäre das dann zu groß.
Beim ATmega16, ja.
>Wie löst>man das normalerweise? Per Direktzugriff mit Pointer?
Jain.
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial#Programmspeicher_.28Flash.29> Ehrlich gesagt mache ich immer einen sehr weiten Bogen um diese Dinger!
Dann wird es Zeit, das Problem anzugehen.
Aber wie gesagt, 1,6us Abtastzeit ist mit SPI und C eine Illusion, das
machen bestenfalls Profis mit 100% Assembler. Bei 5us und 16 MHZ
CPU-Takt hat man eine Chance mit SPI und C.
Okay, dann danke schon mal. Ich schaue mir das morgen mal an und mach
mir dann noch mal Gedanken darüber. Jetzt geht's erstmal Richtung
Feierabend. (Man hat mir das aufs Auge gedrückt, ich arbeite sowas
normalerweise nicht. ;))