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).