LABORATORIUM TM 4 07.05.2010 1. Cel laboratorium Zadaniem polegało na zaprojektowaniu oraz realizacji dynamicznego wyświetlania, na 8- pozycyjnym wyświetlaczu LED, przesuwanego napisu o stałej treści. Przy naciśnięciu przycisku kierunek ruchu ulega zmianie. 2. Schemat połączenia 3. Kod programu: #include <msp430x14x.h> Tablica odwzorowania kodu binarnego na litery short int _C_ = 0x4E; short int _O_ = 0x7E; short int _A_ = 0x77; short int _L_ = 0x0E; Tablica ktora przechowuje nasz napis w trakcie dzialania progamu nie ulega zmianie short int tablica[8]; Zmienna okreslajaca od ktorej litery tablicy zaczynamy wyswietlanie napisu na wyswietlaczu. short int d;
Zmienna przechowuje informacje o tym, ktora aktualnie litere mamy odswiezyc. Sluzy tylko do odswiezania napisu, nie do jego przesuwania short int litera; 8 bitowa zmienna ktora wskazuje, do ktorej pozycji wyswietlacza aktualnie piszemy unsigned char przesuniecie; Zmienna okresla czy w aktualnym cyklu timera odswiezamy pozycje wyswietlacza, czy piszemy do niej int wygaszanie; Licznik stanu wystapienia stanu niskiego na przycisku. Sluzy do odszumiania i probkowania w celu stwierdzenai, czy na pewno zostal wcisniety przycisk zmainy kierunku wyswietlacza int przycisk = 0; Zmienna przechowuje stan licznika programowego, sluzacego do przesuwania napisu int counter = 600; Zmienna przechowuje kierunek w ktorym sie poruszamy. 0 == prawo, 1 == lewo int kierunek = 0; Flaga, ktora jest podnoszona, kiedy program stwierdzi, ze przycisk jest wcisniety. Dopiero zwolnienie przycisku opuszcza te flage. Sluzy do tego, aby w przypadku trzymania przycisku, napis nie zmienial non-stop kierunku int flaga_zmiany = 0; Flaga stwierdzajaca, czy zostal zmieniony kierunek. Sluzy do zachowania plynnosci "animacji" int flaga_zm_kierunku = 0; int main( void ) WDTCTL = WDTPW + WDTHOLD; Ustawienie timera w tryb zliczania w gore TACTL = TASSEL_2 + MC_1; Wskazanie na pierwsza litere do wyswietlenia przesuniecie = 0x01; Zaczynamy wyswietlania od konca, tj od ostatniej litery d = 7; Ustawienie aktualnie odswiezanej litery na ostatnia litera = d; Aktualnie nie wygaszamu, tylko chcemy wyswietlic litere wygaszanie = 0; Ustawiamy porty 2 i 3 MSP jako wyjsciowe. Port 2 to wybor pozycji wyswietlacza Port 3 to dane wysylane na pozycje wyswietlacza P2DIR = 0xff; P2OUT = 0x01; P3DIR = 0xff; P3OUT = _A_; Ustawiamy port 1 jako wejsciowy P1DIR = 0x00; Ustawiamy ze kanal 0 timera A moze zglaszac przerwanoia
CCTL0 = CCIE; Okreslenie do jakiej wartosci ma zliczac timer w trybie UP CCR0 = 800; Wypelniamy tablice znakami tablica[0] = _C_; tablica[1] = _O_; tablica[2] = _C_; tablica[3] = _A_; tablica[4] = _C_; tablica[5] = _O_; tablica[6] = _L_; tablica[7] = _A_; Przechodzimy w tryb uspienia procesora i odblokowujemy przerwania _BIS_SR(LPM0_bits + GIE); return 0; #pragma vector=timera0_vector interrupt void Timer_A (void) Sekcja sluzaca do odszumiania przycisku i sprawdzania jego stanu wcisniecia. W przypadku stwierdzenia, ze przycisk zostal wcisniety, podnosimy flagi if(!(p1in & 1)) Czy przypadkiem nie trzymamy non stop wcisnietego przycisku? Jesli tak to nie liczymy wystapien if(flaga_zmiany == 0) przycisk++; if(przycisk > 50) przycisk = 0; flaga_zmiany = 1; flaga_zm_kierunku = 1; Przycisk nie jest wcisniety, lub zostal zwolniony Opuszczamy wiec flage i zerujemy licznik wystapien przycisk = 0; flaga_zmiany = 0; Sekcja odpowiedzialna za obsluge programowego licznika sluzacego do przesuwania napisu. Licznikiem zliczamy w dol. Dekrementujemy wpierw stan licznika counter--; if(counter <= 0) counter = 3000; Czy flaga zmiany kierunku jest podniesiona? Jesli tak to dopiero teraz mozemy zmienic kierunek if(flaga_zm_kierunku == 1)
if(kierunek == 0) Przesuwamy zmienna d w druga strone. Ma to na celu unikniecie efektu przeskoku w jeszcze starym kierunku d++; if(d > 7) d = 0; kierunek = 1; Przesuwamy zmienna d w druga strone. Ma to na celu unikniecie efektu przeskoku w jeszcze starym kierunku d--; if(d < 0) d = 7; kierunek = 0; Obsluzylismy zmiane kierunku, wiec opuszczamy flage flaga_zm_kierunku = 0; Przesuwamy napis w jedna ze stron zgodnie z aktualnym kierunkiem if(kierunek == 0) d--; if(d < 0) d = 7; d++; if(d > 7) d = 0; Sekcja odpowiedzialna za odswiezanie oraz wlasciwie przesuwanie napisu Wpierw sprawdzamy, czy w aktualnym cyklu mamy zgasic stara wartosc litery, czy juz pisac nowa if(wygaszanie == 0) wygaszanie = 1; Piszemy litere do aktualnej pozycji P3OUT = tablica[litera]; Zmieniamy aktualna pozycje na nastepna P2OUT = przesuniecie; Zmieniamy stan licznika okreslajacego na ktorej aktualnie pozycji jestesmy if(kierunek == 0) litera--; if(litera < 0) litera = 7; litera++; if(litera > 7) litera = 0; Wygaszamy stara wartosc na wskazanej pozycji wygaszanie = 0; P2OUT = 0x00;
Przesuwamy bitowo o jeden zmienna okreslajaca na ktorej aktualnie pozycji jestesmy if(kierunek == 0) przesuniecie = przesuniecie << 1; przesuniecie = przesuniecie >> 1; Jesli doszlismy do jednego z koncow i tym samym wartosc zmiennej zostala wyzerowana, ustawiamy stan licznika pozycji na przeciwlegly koniec if(przesuniecie == 0x00 ) litera=d; if(kierunek == 0) przesuniecie = 0x01; przesuniecie = 0x80; 4. Podsumowanie Opierając się na doświadczeniu zdobytym na laboratorium trzecim, oparliśmy kod programu na przerwaniach, pomiędzy obsługą których mikroprocesor pozostaje uśpiony w oczekiwaniu na przerwanie od timera A. Użyty przez nas w projekcie tryb zliczania Timera to tryb UP, dzięki czemu mogliśmy dokładnie określić interwał między kolejnymi zgłaszanymi przez licznik przerwaniami. Zrezygnowaliśmy z możliwości zgłaszania oddzielnego przerwania przez przycisk na porcie 1 na rzecz przeniesienia odszumiania przycisku do obsługi cyknięć timera, co naszym zdaniem jest metodą efektywniejszą. Sama obsługa wyświetlacza opiera się na odświeżaniu wyświetlanego napisu, naprzemienne pisząc na aktualnie ustawioną pozycję jak i gasząc następną. Ten zabieg jest wymagany do poprawnej pracy wyświetlacza dynamicznego i wynika z jego budowy. Przesuwanie napisu zorganizowanego zostało za pomocą programowego licznika, który zostaje zdekrementowany przy każdej obsłudze przerwania Timera A. Po dojściu do zera napis zostaje przesunięty o jedną pozycję zgodnie z aktualnym kierunkiem. Dość sporym utrudnieniem było zapewnienie stabilnej pracy wyświetlacza pomimo zmiany aktualnego kierunku. Ów problem rozwiązaliśmy za pomocą specjalnej flagi, która podniesiona zapewnia dopiero przy następnym cyklu przesunięcia zmianę kierunku przesuwania napisu.