Hallo zusammen, ich habe einen ATxMega128A1. Dort benutze ich den ADC und möchte nun, dass der DMA im Hintergrund, die Werte in den Speicher ablegt, damit ich diese nach und nach weiterverarbeiten kann. Den ADC habe ich programmiert und den DMA auch, aber leider tut letzterer nicht was er soll. Ich möchte das die Quelle (ADC) immer die selbe ist und das Ziel ist ein array[1000] die Zieladdresse soll also immer inkrementiert werden. Da ich den 12Bit ADC habe, habe ich den BurstMode auf 2Byte gestellt und ´möchte dass der DMA alle 100 Byte wieder von vorne anfängt. Den aktuellen Quellcode habe ich angehangen.(ADC ist auch mit dabei, vielleicht liegt hier auch der Fehler) Es wäre sehr schön, wenn jemand der sich da auskennt mal drüber schaut (ist nicht viel code) und mir einen tipp gibt, wo mein Fehler liegen könnte. Danke für Eure Mühen Viele Grüße Thorsten
Hallo, schau dir mal meine Homepage-Seite an: http://www.basteln-mit-avr.de/atxmega128a3.html#adc_dma Hier findest du einen ADC/DMA Vorgang der funktioniert. Teste das mal und erweitere dann deinen Code. Gruß G.G.
Hallo, danke ersteinmal. ich habe es mir angeguckt und es sieht bei mir auch sehr ähnlich aus. Eben auf mein Projekt zugeschnitten (nur ein Channel und ich benutze auch keine Interrupts). Ich bekomme inzwischen auch Werte in meinem Speicherarray, nur sind diese viel zu groß. (im Bereich von 40000-60000) Obwohl mein ADC nur Werte zwischen 0-4096 erzeugt. Woran könnte das liegen? Ein Überlauf? Wie finde ich das herraus? Danke und Gruß Thorsten
Wird high und low-Byte in der richtigen Reihenfolge abgelegt? Sind die vielleicht vertauscht?
Moin, ich denke nicht. DMA.CH0.DESTADDR0 = ((uint32_t) array >>0*8)&0xFF; DMA.CH0.DESTADDR1 = ((uint32_t) array >>1*8)&0xFF; DMA.CH0.DESTADDR2 = ((uint32_t) array >>2*8)&0xFF; So habe ich den DMA initialisiert. Genauso wie die source. Und der Zugriff erfolgt doch über array? heißt, wenn ich wissen will was er nun gespeichert hat: uint16_t ergebnis = array[0]; //in ergebnis steht der erste Wert, den der DMA geschrieben hat Richtig soweit?
Bin leider immer noch nicht weiter. Kennt sich denn keiner mit dem DMA aus??
//8Bit Ergebnis in array DMA.CH0.DESTADDR0 = ((uint32_t) array >>0*8)&0xFF; DMA.CH0.DESTADDR1 = ((uint32_t) array >>1*8)&0xFF; DMA.CH0.DESTADDR2 = ((uint32_t) array >>2*8)&0xFF; Ich würde da mal Klammern setzen: DMA.CH0.DESTADDR0 = ((uint32_t) array >>(1*8))&0xFF;
:
Wiederhergestellt durch Moderator
Hallo zusammen, also so sieht der aktuelle Quelltext aus: ______________________________________________________________ DMA.CH0.CTRLA = DMA_ENABLE_bm; DMA.CTRL = DMA_ENABLE_bm; //Modus Transaktion, increase und fix, Burst DMA.CH0.ADDRCTRL = DMA_CH_SRCRELOAD_NONE_gc | DMA_CH_SRCDIR_FIXED_gc| DMA_CH_DESTRELOAD_TRANSACTION_gc | DMA_CH_DESTDIR_INC_gc; // Trigger Source ist ADCA Triggerung wenn der Datenpuffer leer ist. DMA.CH0.TRIGSRC = DMA_CH_TRIGSRC_ADCA_CH0_gc; //100 Byte sind zu übertragen! DMA.CH0.TRFCNT = 20; //nur 2 byte //DMA.CH0.CTRLA |= 0x10; //Repeat in Endlosschleife DMA.CH0.REPCNT = 0; //endlosschleife DMA.CH0.CTRLA |= DMA_CH_BURSTLEN_2BYTE_gc | DMA_CH_REPEAT_bm |DMA_CH_SINGLE_bm; //repeat Bit setzten 2Byte BurstLength , singleshot //DMA.CH0.CTRLA |= 0x01; //no repeat 2Byte BurstLength //evtl noch single shot bit in CTRLA |= 0x04 setzten //16Bit Quelle DMA.CH0.SRCADDR0 =(((uint16_t)(&ADCA.CH0.RES))>> 0*8); DMA.CH0.SRCADDR1 =(((uint16_t)(&ADCA.CH0.RES))>> 1*8); DMA.CH0.SRCADDR2 = 0; //16Bit Ergebnis in array DMA.CH0.DESTADDR0 = ((uint16_t) array >> (0*8)); DMA.CH0.DESTADDR1 = ((uint16_t) array >> (1*8)); DMA.CH0.DESTADDR2 = 0; _________________________________________________________________ An den Klammern lags nicht. Wenn ich in den Speicher reingucke, schreibt er immer so doppelpaare in den Speicher. z.B. a3a3 3434 f7f7 1919 usw. es scheint fast, als ob nur ein Byte übertragen wird, aber 2-Byte-Burst-Mode ist ausgewählt. Ich weiß keine Erklärung und hoffe hier ist jemand der mir da weiterhelfen kann. Gruß Thorsten
hi, ich hab nur mal drüber geflogen, aber wenn ichs richtig seh, liest du immer die gleiche src-adresse aus. das sind ja dann vom adc das erste byte. nachdem der adc aber 2byte lange werte zurückliefert, musst du den src-mode nicht auf fixed, sondern auf inc stellen. damit die nächste messung wieder beim ursprung anfängt, schaltest du noch src-reload ein, so dass der adc nach dem 2ten adc-byte die src-adresse wieder auf das erste adc-byte zurückschaltet. War jetzt nur ganz kurz aus m Gedächtnis, aber ich hoff, der Gedankengang kommt rüber :) Viele Grüße, Alex
Schau dir mal hier http://www.atmel.com/Images/doc8046.pdf den Punkt 3.3 an. Das müsste genau das sein, was du willst. Gruß, Alex
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.