DMA w AVR lub 8051
Do niektórych układów z serii AVR i 8051/8052 można podłączyć zewnętrzną pamięć SRAM. W tym samym obszarze adresowania można też podłączyć urządzenia wejścia/wyjścia. Niestety, żaden z tych mikrokontrolerów nie ma DMA, więc ewentualne operacje przesłania danych pomiędzy pamięcią a np. wyświetlaczem graficznym, zajmują sporo czasu: po pierwsze trzeba odczytać bajt, po drugie zapamiętać go w rejestrze przeznaczonym do operacji I/O, a po trzecie zapisać w obszarze docelowym. Dodając jednak do układu „dolepianą logikę” można zbudować coś na kształt pseudo DMA i znacznie przyśpieszyć operacje transferu danych. Proponowane rozwiązanie przedstawiono na rysunku 1a (przesyłanie danych z pamięci do urządzenia I/O) i rysunku 1b (przesyłanie danych z urządzenia I/O do pamięci). Jest ono bardzo proste i już na pierwszy rzut oka można zorientować się jak działają te układy. Gdy mikrokontroler zezwala na pracę pseudo DMA, to sygnały RD/WR pochodzące z mikrokontrolera używane są również do generowania impulsów zezwalających na pracę urządzenia I/O. W tym samym czasie, w którym mikrokontroler wykonuje pracę na zewnętrznej pamięci, urządzenia I/O przechwytuje przesyłane dane. Podobnie zachowuje się układ pamięci, gdy transmisja danych odbywa się w drugą stronę. Jak łatwo domyślić się, oszczędzany jest jeden cykl zapisu lub odczytu, więc operacje przesyłania danych wykonywane są dwukrotnie szybciej. Mikrokontroler pracuje tylko jako generator adresów, czas transmisji pomiędzy zewnętrzną szyną danych w wewnętrznymi rejestrami nie ma większego znaczenia. Na rys. 1a pokazano schemat układu przesyłającego dane z pamięci do urządzenia I/O. Magistrale adresowa i danych połączone są w typowy sposób. Wejście zewnętrznego przerwania INT służy urządzeniu I/O, do którego transmitowane są dane, do zgłoszenia żądania obsługi. Sygnał odczytu RD doprowadzony jest do wejścia pamięci SRAM oraz podawany na wejście bramki OR, sumującej z nim sygnał zezwolenia na pracę pseudo DMA, a generowany przez któryś z portów I/O mikrokontrolera. W tym samym czasie, gdy mikrokontroler odczytuje dane z pamięci SRAM, to do urządzenie I/O niejako „podsłuchuje” magistrale adresową i danych. Na rys. 1b pokazano schemat układu przesyłającego dane z układu zewnętrznego do pamięci. Układ ten używa sygnału WR, ponieważ operacja zapisu do pamięci SRAM wykonywana jest w cyklu odczytu z urządzenia zewnętrznego. Odczytywane dane, zamiast w rejestrze procesora, zapisywane są w pamięci SRAM. Aby zapobiec konfliktom pomiędzy mikrokontrolerem a urządzeniem zewnętrznym konieczne jest zastosowanie rezystorów maskujących o wartości około 1 kΩ lub jakiegokolwiek przełącznika magistral. Tu jedna ważna uwaga. Rezystory szeregowe mogą zmienić kształt przebiegów na magistralach oraz margines zakłóceń, dlatego należy dobierać je ze szczególną starannością w odniesieniu do konkretnej aplikacji. W związku z tym, że czas trwania impulsu RD jest bardzo krótki, to dobrze jest wstawić w programie obsługi pojedynczy cykl oczekiwania. Na listingu przedstawiono przykładowy program obsługi pseudo DMA napisany w języku AVR Asembler, a przeznaczony do obsługi podłączonego do mikrokontrolera wyświetlacza graficznego (dane z pamięci buforowej SRAM przepisywane są do wyświetlacza). Praktyczną realizację układu można zobaczyć na stronie internetowej http://elm-chan.org/docs/avr/avrdma_e.html. Zaprezentowany układy pseudo DMA pozwala na podniesienie prędkości transmisji aż do około 2,66 MB/s, gdy mikrokontroler AVR taktowany jest częstotliwością 8MHz. Wadą przedstawionego rozwiązania jest fakt, że w podstawowej konfiguracji dane przenoszone są pomiędzy tymi sami adresami, co niejako usztywnia konfigurację systemu.
Rysunek 1. Schemat układu pseudo DMA do zapisu (a) i odczytu (b) danych z/do urządzenia I/O
Listing. Przykład programu obsługi pseudo DMA (asembler AVR)
;----------------------------------
; przerwanie timera TC0 wywoływane
; z f=10 kHz
;----------------------------------
tc0ov:
push R16 ;zapamiętanie rejestrów
in R16, SREG
push R16
push R17
push YL
push YH
outi TCNT0, -11 ;odtworzenie TCNT0
ldsw Y, VADDR ;załadowanie adresu DMA
cbi PORTD, DMAEN ;zezwolenie na pracę DMA
ldi R17, 40/10 ;przesłanie 40 bajtów danych
ldi R16, Y+
ldi R16, Y+
ldi R16, Y+
ldi R16, Y+
ldi R16, Y+
ldi R16, Y+
ldi R16, Y+
ldi R16, Y+
ldi R16, Y+
ldi R16, Y+
dec R17
brne PC-11
sbi PORTD, DMAEN ;wyłączenie DMA
lds R16, line ;załadowanie licznika linii
tst R16 ;jeśli pierwsza linia, to ładuj YD
brne PC+2
cbi PORTD, YD
inc R16 ;kolejna linia
cpi R16, 200 ;jeśli ostatnia linia, to start
brcs PC+4 ;wskaźnika DMA i licznika linii
clr R16
ldiw Y, VRAM
cbi PORTD, LP ;strobowanie linii danych
sts LINE, R16 ;zapamiętanie wskaźnika DMA i licznika linii
stsw VADDR, Y
sbi PORTD, LP
sbi PORTD, YD
pop YH ;odtworzenie rejestrów
pop YL
pop R17
pop R16
out SREG, R16
reti
Dodaj nowy komentarz