Hallo Leute,
ich schaue mir gerade das Beispiel AVR1502 zum Thema DMA an. In diesem
Beispiel werden die Tasten nach 10 sec abgespeichert und wieder
abgespielt. Soweit so gut!!!
Nun habe ich mir gedacht, dass ich ja dasselbe für meinen ADC entwerfen
kann. Also mein ADC soll Werte erstellen und mithilfe von DMA in den
SRAM schreiben.
Jetzt habe ich meinen ADC eingestellt. Leider habe ich beim Einstellen
vom DMAC große Problem.
Hier mal meine Einstellungen:
DMA:
1
//Direct Memory Access initialisieren
2
#define ADC_WERTE 10 //Wie viele Werte gespeichert werden sollen
3
int16_tsamples[ADC_WERTE];//ADC-Werte hier abspeichern
DMA_CH_SRCRELOAD_BURST_gc,//Quellereload nach einem Burst
10
DMA_CH_SRCDIR_INC_gc,//Quellenrichtung increment
11
samples,//Zieladresse
12
DMA_CH_DESTRELOAD_BLOCK_gc,//Zielreload nach einem Block
13
DMA_CH_DESTDIR_INC_gc,//Zielrichtung increment
14
ADC_WERTE,//Blockgröße
15
DMA_CH_BURSTLEN_2BYTE_gc,//Burstlänge liegt bei 2 Byte
16
0,//Anzahl der Blocks <- wird nicht verwendet
17
false//Verwendung von Repeat <- wird nicht verwendet, deswegen false
18
);
19
20
DMA_EnableSingleShot(dmaChannel);
21
DMA_SetTriggerSource(dmaChannel,DMA_CH_TRIGSRC_ADCA_CH0_gc);//ADCA als Triggerquelle
22
}
main:
1
//Hauptfunktion
2
intmain(void){
3
// The DMA channel to use for reading switch state.
4
DMA_CH_t*ReadChannel=&DMA.CH0;
5
6
// Prepare DMA
7
DMA_Enable();
8
SetupReadChannel(ReadChannel);
9
//SetupWriteChannel(WriteChannel);
10
11
while(1){
12
DMA_EnableChannel(ReadChannel);
13
DMA_ReturnStatus_blocking(ReadChannel);
14
}
15
}
Die Abspeicherung in den SRAM klappt auch soweit, es werden jedoch genau
die HÄLFTE der angegebenen ADC_WERTE hineingeschrieben, obwohl die
Variable sample die richitge Länge hat.
Also sample sieht so aus, dass 5 Werte vom ADC sind und die anderen 5
genau 0 sind.
Nun habe ich mal folgendes ausprobiert. Ich habe einfach mal in der
Funktion DMA_Setupblock die Blockgröße (siehe Komentare) auf 2*ADC_WERTE
gestellt und siehe da, es wird der komplette Vektor "sample" mit den
Werten vom ADC gefüllt.
Die Frage ist nun, warum muss die Blockgröße doppelt so groß sein???
Oder verstehe ich da was flasch??
Im Beispiel muss ja diese Größe auch nicht doppelt so groß sein!!!
Gruß Joe
Hallo Joe,
in der Funktion DMA_SetupBlock wird ja folgendes gesetzt:
channel->TRFCNT = blockSize;
und das Datenblatt sagt:
TRFCNT defines the number of bytes in a block transfer.
Also Blocksize ist die Anzahl der Bytes die übertragen werden,
unabhängig der Burstlänge und den Datentyp in den geschrieben wird.
Grüße,
Michael
Danke für die Antwort!!! :)
Du wirst es nicht glauben, aber ich habe das gerade selber entdeckt.
Da ja die Blockgröße die Anzahl der zu übertragenen Bytes festlegt und
ich ja für 2 Byte einen Wert habe, muss ich ja 2 * Anzahl der Werte (in
meinem Fall "ADC_WERTE") nehmen!!!
Trotzdem Danke für die schnelle Antwort!!!
Gruß Joe
So, nun habe ich aber wirklich ein Problem. :(
Laut diesem Beispiel wird ja die Zieladresse (destination memory adress)
als
1
void*destAddr
angegeben. In meinem Beispiel ist das
1
samples[ADC_WERTE]
Nun möchte ich aber 20 Messungen machen und diese alle hintereindaner
auf den SRAM schieben. So wie ich das verstehe, aber ich bin halt noch
Anfänger, müsste ich ja mehrere Vektoren anlegen (z.B. samples2,
samples3...) und dann mithilfe einer Interation immer den nächsten
Vektor nehmen. Dies ist aber nicht sehr elegant und benötigt
zusätzlichen Speicher. Ist es vllt möglich, dass immer den selben Vektor
verwende?
Ich bin mir sogar relativ sicher, dass es gehen muss, aber ich komme
nicht darauf.
Gruß Joe
Hi Harald,
früher habe ich dieses LUFA Project verwendet, dadurch konnte ich aber
nicht debuggen. Nun habe ich mir einen Jtagice MK2 gekauft, nun kann ich
debuggen und die Register einzeln auslesen. Das ist wirklich
vorteilhaft, kostet aber auch einiges.
Gruß Joe
Hi Joe,
Du machst doch eh einen Single - Shot ... dann kannst Du ja die
Destination Adresse verbiegen ... ggf. mach doch einfach nen 2
dimensionales Array ...
Grüße,
Michael
Das ist ein gute Idee. Jedoch ist mir aufgefallen, dass wenn ich einen
großen Vektor anlege (z.B mit 1000 Werten) mein Speicher zu 25% voll
ist. Wenn ich also z.B. noch 20 Messungen mache, dann ist das anlegen
einer solchen Matrix (Vektor) nicht machbar.
Deswegen war meine Idee, dass ich einen Vektor anlege und diesen ständig
überschreibe.
Mir ist aufgefallen, als ich mich heute so im Forum mal durchgekämpft
habe, dass es einen gewaltigen Unterschied gibt, zumindest beim
Xplain-Board, zwischen SRAM und SDRAM. Viele schreiben zwar, dass sie
SDRAM ansteuern wollen, aus dem Code heraus liest man jedoch, dass sie
SRAM ansteuern, da sie kein EBI verwenden. Da ich noch ein Anfänger bin,
bin ich auch so ein Beispiel reingefallen und habe statt SDRAM SRAM
angesteuert (sieht man ja an meinem Code). Was auch den 25% vollen
Speicher erklärt. Bei großen Datenmengen werde ich wohl nicht drum
herumkommen, den SDRAM ansteuren zu müssen. Dazu muss ich aber noch
einiges lesen.
Gruß Joe
> Was auch den 25% vollen>Speicher erklärt. Bei großen Datenmengen werde ich wohl nicht drum>herumkommen, den SDRAM ansteuren zu müssen. Dazu muss ich aber noch>einiges lesen.
In dem Thread findet sich ein Beispiel:
Beitrag "XMEGA/ AVR-EXPLAIN code examples und Diskussion"
Hallo,
Danke erstmal für die Antworten und Tipps.
also ich möchte erstmal ein Signal AD wandeln, dazu habe ich meinen
AD-Wandler schon richtig eingestellt (12 Bit Auflösung, differential,
usw.). Nun möchte ich bei einer 500kHz Abtastung die Werte, ca 1000
Stück pro Messung, in den SDRam schreiben. Dabei will ich ca. 20
Messungen machen. Dies entspricht 20000 Werten, die alle 12 Bit lang
sind. Diese Werte möchte ich später wieder aus dem SDRam lesen und
weiterverarbeiten. Da mein SRam auf dem Xplain nicht ausreicht, wollte
ich SDRam nutzen. Dieser hat ja beim Xplain Board 8MB. Dies sollte auf
jeden Fall reichen.
Um den 8MB SDRam "anzusteuern", muss ich ja EBI verwenden. Das ist für
mich völlig neu, deswegen muss ich mich da einlesen.
@ Klaus
Danke für den Tipp.
Ich habe mir diesen Thread mal durchgelesen und habe 3 Fragen.
1. Werden hier die vollen 8MB angesteuert? Ich meine mich erinnern zu
können, dass ich irgendwo gelesen habe, dass man mit Winavr-gcc und AVR-
Studio nicht den gesamten Speicher ansprechen kann! Warum eigentlich
nicht?
2. EBI.REFRESH und EBI.INITDLY, wie werde diese Werte berechnet und was
bedeuten diese genau bzw. für was werden diese benötigt? Ich habe sie im
Datenblatt zwar gefunden, aber die Erklärung ist nicht gut.
3. Im Moment habe ich meinen µC auf 32 MHz eingestellt. Wenn ich die
Einstellungen vom Taktsystem von Hagen Re verwende, ändert sich meine
aktuelle Taktfrequenz? So wie ich es verstanden habe, ist seine
Taktfrequenz auch auf 32 MHz eingestellt (Quarz extern oder intern??),
nur für das Schreiben in den SDRam verwendet er eine höhere Frequenz,
oder?
Gruß Joe
>1. Werden hier die vollen 8MB angesteuert? Ich meine mich erinnern zu>können, dass ich irgendwo gelesen habe, dass man mit Winavr-gcc und AVR->Studio nicht den gesamten Speicher ansprechen kann! Warum eigentlich>nicht?
Wenn Du die separaten Funktionen nimmst, wird der ganze Speicher
angesprochen. Die Begrenzung für kleiner 8MB tritt nur auf, wenn man das
SD-RAM direkt in den GCC einbindet, wenn man also z.B. via
x=data[uint32_t d] zugreifen will.
Danke Klaus.
Eine Frage noch dazu:
Wenn ich Winavr-gcc und AVR-Studio verwende und in den SDRam schreibe,
kann ich trotzdem per Debug diesen Wert irgendwie anschauen? Wenn ich
die geschriebene Variable, die ich anschauen will, in das
"Watch-Fenster" schiebe, steht bei mir "out of location". Ist das
korrekt?
Mal eine andere Frage:
Ich habe nun viel über den XMEGA gelesen und was ich nicht verstehe,
wieviel SRAM steht denn dem XMEGA nun zur Verfügung? Im Datenblatt steht
8kb, soweit so gut. Aber laut dem AVR1312 stehen dem XMEGA 128kb SRAM
zu. Was entspricht nun was?
Damit ihr nicht lange suchen müsst, hier die Links:
SRAM 8kb:
http://www.atmel.com/dyn/products/product_card.asp?part_id=4298
SRAM 128kb (AVR1312):
http://www.atmel.com/dyn/products/app_notes.asp?family_id=607
Gruß Joe
Klar, die Tabelle habe ich auch schon gesehen. Das ist ja was mir unklar
ist. Überall steht, dass XMEGA 128A1 8kb SRam hat.
TROTZDEM werden im AVR1312 128kb SRam angesprochen????
Gruß Joe
Ok, falls sich das ein Admin durchliest, bitte den Beitrag obendrüber
löschen.
Dieses sram_example.c mit 128kb SRam funktioniert nicht auf dem
XMEGA128A1. Es geht nur, wenn man die SRAM_SIZE auf 8kb reduziert, was
ja auch Sinn macht, denn dieser XMEGA hat nur 8 kb SRam.
Gruß Joe