background image

Ćwiczenie D3:

K

OMUNIKACJA

 

RDZENIA

 

PROCESORA

 

SYGNAŁOWEGO

 

TMS320 

SERII

 2400 

Z

 

PAMIĘCIĄ

I

 

URZĄDZENIAMI

 

PERYFERYJNYMI

opracował:

mgr inż. Tadeusz Białoń

Tadeusz.Bialon@polsl.pl

Cele ćwiczenia:

poznanie trybów adresowania procesorów serii C24xx

poznanie mechanizmów wielokrotnego dostępu do pamięci

doskonalenie umiejętności programowania w asemblerze

Część I:

Komunikacja z pamięcią danych

Obliczenia iteracyjne na przykładzie generacji ciągu Fibonacciego

Ciąg   Fibonacciego   jest  to   ciąg   liczbowy   którego  pierwsze   dwa   wyrazy   są   równe  jeden   a   każdy 
następny wyraz jest sumą dwóch poprzednich. Ciąg ten ma postać:

a = 1, 1, 2, 3, 5, 8, 13, 21, 34, 55 ...

Ciąg ten jest używany do matematycznego opisu niektórych zjawisk przyrodniczych i wykorzystywany  
między innymi przez fraktalne metody przetwarzania obrazów. Metoda jego generowania stanowi  
dobry i prosty przykład algorytmu iteracyjnego.
Podczas przeprowadzania obliczeń iteracyjnych zawsze pojawia się operacja zastępowania starych,  
nie potrzebnych  już  danych   nowymi,  otrzymanymi   w  ostatnim   kroku  obliczeń.   W rozpatrywanym  
przypadku   ciągu   Fibonacciego   musimy   przechowywać   dwie   poprzednio   obliczone   wartości  
(oznaczmy je jako a(n-2) i a(n-1)) aby obliczyć trzecią, najnowszą (oznaczoną jako a(n)). Na 

przykład, gdy  a(n-2) = 5  oraz  a(n-1) = 8  otrzymamy wynik  a(n) = 13. Przechodząc do 

następnego kroku obliczeń, wyrazy starsze musimy zastąpić wyrazami nowszymi czyli a(n-2) = 8 

i  a(n-1) = 13. Teraz możemy obliczyć wartość kolejnego wyrazu ciągu. Procesory sygnałowe  

dzięki rozbudowanej strukturze magistral służących do komunikacji z pamięcią mogą jednocześnie  
zapisywać i odczytywać dane z pamięci. Dzięki temu możliwe jest wykonanie powyższej operacji  
przeniesienia  danych za  pomocą jednej  instrukcji asemblera, bez wykorzystania akumulatora, co 
znacznie skraca czas wykonywania algorytmów iteracyjnych. 
Przedstawiony   poniżej   algorytm   generacji   ciągu   Fibonacciego   wykorzystuje   akumulator   do  
obliczania i przechowywania ostatniego wyrazu ciągu (a(n)). Dwie komórki pamięci danych są 

wykorzystywane   do   przechowywania   dwóch   starszych   wyrazów   ciągu,   odpowiednio:   komórka   o 
adresie  200h  wyrazu  a(n-1)  i   komórka   o   adresie   201h   wyrazu  a(n-2).   Algorytm   w 

nieskończonej pętli wykonuje operację dodawania i dwie operacje kopiowania.

Zadanie 1:

Algorytm programu generującego kolejne wyrazy ciągu Fibonacciego

1.  Przygotowanie danych

Przygotowujemy dane dla pętli głównej algorytmu.

background image

1.1. Załaduj stronę pamięci danych DP_B1

1.2. Załaduj do akumulatora wartość 01h

1.3. Załaduj wartość 01h do komórek pamięci o adresach 200h i 201h

2.  Pętla główna

Zaczynamy obliczać kolejne wyrazy ciągu Fibonacciego.

2.1. Dodaj do akumulatora zawartość komórki pamięci o adresie 201h

2.2. Przesuń zawartość komórki pamięci o adresie 200h do komórki o adresie 201h

2.3. Zapisz zawartość akumulatora do komórki pamięci o adresie 200h

2.4. Wróć do punktu 2.1

Instrukcje asemblera potrzebne do napisania programu:

add, b, dmov, lacc, ldp, sacl, splk 

Zadanie 2:

Generacja ciągu Fibonacciego z zapisem kolejnych wyrazów w buforze pamięci

Podczas   wykonywania   obliczeń   iteracyjnych   bardzo   często   zachodzi   konieczność   zapisywania  
wyników tych obliczeń w pamięci. Zwykle w tym celu definiuje się jeden duży sektor pamięci, w 
którego kolejnych komórkach zapisuje się dane w takiej kolejności w jakiej są one wyliczane. Do  
adresowania   kolejnych   komórek   pamięci   tego   sektora   najłatwiej   jest   wykorzystać   pomocniczą  
jednostkę arytmetyczno logiczną i adresowanie pośrednie. Rozwiązanie to ma dodatkową zaletę taką, 
że   nie   wymaga   użycia   akumulatora,   przez   co   operacja   zapisu   danych   nie   ingeruje   w   aktualnie  
wykonywany algorytm. 
Program napisany w zadaniu 1 należy rozbudować wykorzystując następujące zasoby pomocniczej  
jednostki arytmetyczno logicznej: Rejestr 
AR1 będzie przechowywał aktualny adres komórki pamięci  

bufora danych w której należy zapisać kolejny wynik obliczeń. Po każdym zapisie zawartość tego  
rejestru należy zwiększyć o jeden. Rejestr  
AR0  będzie przechowywał adres końca bufora danych. 

Zawartość   tego   rejestru   po   każdym   zapisie   należy   porównać   z   zawartością   rejestru  AR1.  Jeżeli 

zawartość   rejestrów  AR1  i  AR0  będzie   taka   sama   należy   zakończyć   działanie   algorytmu,   gdyż  

oznacza to całkowite zapełnienie bufora pamięci.

Algorytm z zadania 1 należy rozbudować o następujące punkty:

1.  Przygotowanie danych

1.4. Ustaw jako aktualny rejestr pomocniczy AR1

1.5. Załaduj do rejestru AR1 adres początku bufora danych

1.6. Załaduj do rejestru AR0 adres końca bufora danych

2.  Pętla główna
     2.3.A. Zapisz zawartość akumulatora w komórce pamięci o adresie przechowywanym w
          rejestrze AR1 i zwiększ zawartość tego rejestru o 1
     2.3.B. Porównaj zawartość rejestrów AR1 i AR0 sprawdzając czy zawartość aktualnego rejestru

          pomocniczego (AR1) ma mniejszą wartość od zawartości rejestru AR0 

W  tym   celu   należy   zastosować   instrukcję  cmpr  z odpowiednim  warunkiem.  Instrukcja  ta  wynik  
porównania zapisuje w bicie testowym  
TC  (1 gdy warunek jest spełniony, 0 gdy warunek nie jest  

spełniony). 

     2.3.C. Jeżeli warunek testowany w punkcie 2.3.B. nie jest spełniony należy wykonać skok do
          punktu 3 

3.  Kończenie algorytmu

Opuszczamy algorytm i przechodzimy do nieskończonej pętli. 

     3.1. Wykonaj instrukcję nop
     3.2. Wróć do punktu 3.1.

background image

Dodatkowe instrukcje asemblera potrzebne do napisania programu:

bcnd, cmpr, lar, mar, nop 

Część II:

Komunikacja z urządzeniami peryferyjnymi

Algorytm programu mierzącego napięcie na potencjometrze i wyświetlającego wynik pomiaru na 

linijce diodowej (procesor docelowy TMS320F240).

Procesor   sygnałowy   TMS320F240   jest   wyposażony   w   dwa   niezależne   przetworniki   analogowo  
cyfrowe. Każdy z nich obsługuje zestaw ośmiu wejść analogowych. Każdy przetwornik za jednym  
wyzwoleniem   może   wykonać   dwa   pomiary   napięcia   na   dowolnie   wybranych   wejściach   (można  
również dwukrotnie zmierzyć napięcie na tym samym wejściu). Wyniki pomiaru są zapisywane w  
dwustopniowym   rejestrze   kolejkowym   typu   FIFO   (
ang.  first   in,   first   out),   który   jest   rejestrem  
mapowanym w pamięci danych. Aby odczytać obydwa wyniki pomiaru, należy po prostu dwukrotnie 

odczytać zawartość komórki pamięci danych sprzężonej z tym rejestrem. Pierwsza odczytana wartość  
będzie   wynikiem   pierwszego   pomiaru,   a   po   pierwszym   odczycie   zawartość   tej   komórki   pamięci  
zostanie automatycznie zastąpiona drugim wynikiem pomiaru (jest to rejestr kolejkowy więc wyniki  
pomiarów są odczytywane „po kolei”, w kolejności w jakiej wykonywane były pomiary).
Przetworniki analogowo cyfrowe procesora TMS320F240 mogą współpracować (tzn. być wyzwalane 
lub   powodować   zadziałania)   z   innymi   urządzeniami   peryferyjnymi   procesora,   mogą   również  
generować przerwania. Za konfigurację przetworników analogowo cyfrowych odpowiadają rejestry 
kontrolne 
ADCTRL1 i ADCTRL2 

1.  Konfiguracja przetwornika AC.

Konfiguracja przetworników analogowo cyfrowych polega na odpowiednim ustawieniu zawartości 
rejestrów
 ADCTRL1  i  ADCTRL2. Rejestry zawierają informację o liczbie i warunkach rozpoczęcia  

pomiarów, interakcjach z innymi urządzeniami peryferyjnymi oraz numery wejść analogowych dla  
których   zostaną   wykonane   pomiary.   Poniżej   podano   sposób   konfiguracji   odpowiedni   dla   tego  
zadania.  

1.1. Załadować stronę pamięci danych DP_ADC.

1.2. Zapisać do rejestru ADCTRL1 wartość 1001100001101110b.

1.3. Zapisać do rejestru ADCTRL2 wartość 0000000000000011b.

2.  Rozpoczęcie pomiaru.

Aby  rozpocząć   pomiar   należy  ustawić   na   1   pierwszy   bit   rejestru  ADCTRL1. Pozostałe bity tego 

rejestru zostały ustawione w punkcie poprzednim i muszą pozostać bez zmian. 

2.1. Załadować stronę pamięci danych DP_ADC.

2.2. Aby rozpocząć pomiar, należy bit 0 (pierwszy od prawej) rejestru ADCTRL1 ustawić na 1. 

3.  Oczekiwanie na koniec pomiaru.

Czas   trwania   pomiaru   jest   trudny   do   określenia,   gdyż   jest   w   skomplikowany   sposób   zależy   od  
konfiguracji   przetworników.   Przetworniki   jednak   sygnalizują   zakończenie   pomiarów   stanem  

background image

siódmego bitu rejestru  ADCTRL1. Bit ten jest automatycznie ustawiany na 1 zaraz po rozpoczęciu  

pomiaru i pozostaje w tym stanie aż do jego zakończenia. Z wykonaniem dalszej części programu  
trzeba więc zaczekać aż bit ten zmieni swoją wartość ponownie na 0.
Najłatwiej jest wykorzystać w tym celu najpierw instrukcję 
bit, która ładuje wartość wybranego bitu 
komórki pamięci danych do bitu testowego  
TC (jest to jeden z bitów rejestrów statutowych rdzenia  

procesora).   Następnie   należy   wykorzystać   instrukcję   skoku   warunkowego  bcnd,   wybierając 
odpowiedni warunek skoku zależny od stanu bitu 
TC

3.1. Załadować zawartość bitu 7 rejestru ADCTRL1 (ósmy od lewej) do bitu testowego TC

3.2. Jeżeli bit testowy TC jest równy 1, skocz do punktu 3.1.

4.  Odczyt i przetworzenie wyniku pomiaru

Dziesięciobitowy wynik pomiaru odczytany z rejestru wynikowego ADCFIFO2 ma postać:

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

w9 w8 w7 w6 w5 w4 w3 w2 w1 w0 0

0

0

0

0

0

jak widać brakujących sześć bitów zostało uzupełnionych zerami. W celu wyświetlenia na linijce  
diodowej wynik ten musi być przetworzony do postaci gotowej do zapisania w rejestrze sterującym  
uniwersalnymi   wejściami   –   wyjściami   cyfrowymi.   Po   przetworzeniu,   gotowa   kombinacja   bitów  
powinna mieć postać:

15

14

13

12

11

10

9

8

7

6

5

4

3

2

1

0

1

1

1

1

1

1

1

1

__________

w9

__________

w8

__________

w7

__________

w6

__________

w5

__________

w4

__________

w3

__________

w2

Starsze 8 bitów określa kierunek przesyłu danych (1 = wyjście, 0 = wejście) pozostałe bity to 8  
starszych bitów wyniku pomiaru. Bity te są zanegowane ze względu na ujemną logikę linijki diodowej  
(0 zapala diodę, a 1 gasi). 

4.1. Załaduj do akumulatora zawartość rejestru wynikowego ADCFIFO2, z przesunięciem o 8 

bitów w lewo.

W   ten   sposób   8   starszych   bitów   wyniku   pomiaru   znalazło   się   w   starszym   słowie   akumulatora. 
Operując dalej na starszym słowie akumulatora pomijamy 2 najmniej znaczące bity wyniku pomiaru, 
które i tak nie zmieszczą się na linijce diodowej.

4.2. Wykonaj logiczną operację NOT na zawartości akumulatora.
4.3. Wykonaj logiczną operację OR na starszym słowie akumulatora i liczbie 0ff00h.

5.  Wyświetlenie wyników pomiaru.

5.1. Załaduj stronę pamięci danych DP_IO.

5.2. Zapisz zawartość starszego słowa akumulatora do rejestru PBDATDIR.

6.  Wróć do punktu 2.

Instrukcje asemblera potrzebne do napisania programu:

and, b, bcnd, bit, cmpl, lacc, ldp, or, sach, sacl, splk

Sprawozdanie z ćwiczenia

Sprawozdanie z ćwiczenia powinno zawierać kody napisanych w trakcie ćwiczenia programów 
wraz z komentarzami opisującymi ich działanie.