Forum: Projekte & Code XMEGA/ASM: Puffer->DMA->USART ausgeben


von Jan K. (pit1)


Lesenswert?

War bei den älteren AVRs noch der Data-Empty Interrupt das Mittel der 
Wahl zur seriellen Ausgabe von Daten via USART, so bieten die XMegas mit 
dem neu eingebauten DMA-Controller nun eine deutlich effektivere, 
interruptfreie Methode, die sich auf das einfache Initialisieren des 
DMAC mit den richtigen Parametern beschränkt- auf maximal 4 Kanälen 
(CHA0-3) für ebensoviele Ausgaben gleichzeitig. Vorausgesetzt, die USART 
(hier USART0/Port E) wurde bereits konfiguriert und der Transmitter 
eingeschaltet, ist nun für die Ausgabe von 100 Bytes eines Puffers Buf1 
mit DMA-Kanal 3 nur noch
1
Einmalig zu initialisieren:
2
3
;DMA Controller einschalten:
4
ldi r16,$80
5
sts DMA_CTRL,r16
6
7
;Quelladresse (Buf1) soll während der Ausgabe automatisch erhöht werden:
8
ldi r16,$10
9
sts DMA_CHA3_ADDRCTRL,r16
10
11
;USART0/Port E Data-Empty triggert die Ausgabe des nächsten Bytes:
12
ldi r16,$8c
13
sts DMA_CH3_TRIGSRC,r16
14
15
;I/O Adresse des USART0/Port E Datenregisters als Zieladresse einstellen:
16
ldi r16,$a0
17
ldi r17,$0a
18
clr r18
19
sts DMA_CH3_DESTADDR0,r16
20
sts DMA_CH3_DESTADDR0,r17
21
sts DMA_CH3_DESTADDR0,r18
22
23
Die Ausgabe zu starten:
24
25
;Quelladresse (Buf1) übergeben:
26
ldi r16,low(Buf1)
27
ldi r17,high(Buf1)
28
clr r18
29
sts DMA_CH3_SRCADDR0,r16
30
sts DMA_CH3_SRCADDR1,r17
31
sts DMA_CH3_SRCADDR2,r18
32
33
;Pufferlänge (100 Bytes) übergeben:
34
ldi r16,100
35
clr r17
36
sts DMA_CH3_TRFCNT,r16
37
sts DMA_CH3_TRFCNT+1,r17
38
39
;Byteweise Ausgabe auf Kanal 3 starten:
40
ldi r16,$84
41
sts DMA_CH3_CTRLA,r16

Voila! Schon setzt sich die Ausgabe bis zum letzten Byte parallel zum 
normalen Programmablauf in Gang, ohne daß die CPU noch weiter in 
Anspruch genommen wird. Das Ende der Übertragung lässt sich im 
DMA_CH3_CTRLB Bit 7 (Channel-Busy Flag, auf 0) prüfen, alternativ kann 
in diesem Register dafür auch ein Interrupt aktiviert werden (Bit 0/1).

von Peter D. (peda)


Lesenswert?

Jan K. schrieb:
> sts DMA_CH3_DESTADDR0,r16
> sts DMA_CH3_DESTADDR0,r17
> sts DMA_CH3_DESTADDR0,r18

Es ist besser, immer nur Code zu posten, den man auch getestet hat.

von Jan K. (pit1)


Lesenswert?

Jan K. schrieb:
> sts DMA_CH3_DESTADDR0,r16
> sts DMA_CH3_DESTADDR0,r17
> sts DMA_CH3_DESTADDR0,r18

Oh danke Peter. Sehr aufmerksam. Der Code ist zwar getestet, wurde aber 
falsch in diesen Beitrag übernommen. Es muß natürlich heißen

sts DMA_CH3_DESTADDR0,r16
sts DMA_CH3_DESTADDR1,r17
sts DMA_CH3_DESTADDR2,r18

von Peter D. (peda)


Lesenswert?

Jan K. schrieb:
> Der Code ist zwar getestet, wurde aber
> falsch in diesen Beitrag übernommen.

Daher immer wieder diese gebetsmühlenartige Empfehlung:
Hänge exakt den getesteten und compilierbaren Code als Anhang an!

Und wenn man auch nur ein Zeichen ändert, muß man eben neu testen.
Glaube ruhig einem alten Hasen.

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
Noch kein Account? Hier anmelden.