Przeskocz do treści

Lekcja 3, programujemy linijke LED

9 listopada, 2011

Linijka LED, kolejny program

Dzisiaj zajmiemy się programem, którego celem będzie wyświetlanie linijki LED na wyjściach PORTA. Wiesz chyba co to jest linijka LED? Chodzi o to, że co pewien okres czasu zapala się kolejna dioda podłączona do wyjścia PORTA, a gaśnie poprzednia. Cykl powtarza się, aż do dojścia do ostatniej diody i rozpoczyna powrót dokładnie w ten sam sposób.

Wstępne założenia

Ze względów omówionych później do linijki nie wykorzystałem w swoim programie wyjścia PORT,4, dlatego moja linijka skład się jedynie z czterech diod o kolorze żółtym. Program jest napisany tak by 1 na wyjściu włączała diodę. Oznacza to, że dla uzyskania tego samego efektu dioda powinna być włączona z wyjścia portu do masy. Schemat znajdziesz na końcu artykułu. Oczywiście nic nie stoi na przeszkodzie, aby umieścić diody drugą stroną. To znaczy od plusa do wejścia portu. W takim przypadku diody zapalałyby się, kiedy na wyjściu byłoby zero logiczne, a rotacja 1 z opisywanego programu wyglądałaby tak, że poruszałaby się jak gdyby jedna zgaszona dioda zamiast jednej zapalonej jak w przypadku opisywanej linijki.

Zmiany

Oczywiście Ty jeżeli masz trochę chęci możesz zmienić podany program i podłączyć diody LED pod wyjście PORTB. Będziesz miał wtedy aż 8 diod do testów. Pamiętaj tylko, że linia programatora RB7 nie może być włączona podczas działania programu. Jeżeli pozostawisz ją włączoną nic się nie stanie programatorowi, ani procesorowi. Nie będzie po prostu się zapalać ostatnia dioda z linijki. Pisałem już o tym w jednej z poprzednich części.

Nowe komendy

Poznaliśmy już ostatnimi czasy kilka pożytecznych komend teraz czas na kolejne. Przy realizacji programu przyda nam się komenda, która przesuwa bity rejestru w określona stronę. W asemblerze pod PICa mamy dwie takie komendy. Mianowicie

RRF rejestr,d

Gdzie rejestr to nazwa rejestru, którego bit chcemy przesuwać, a d to miejsce do którego ma zostać przeniesiona liczba powstała po przesunięciu. Dla przykładu w rejestrze PORTA mamy liczbę 00100 i chcemy ta jedynkę przesunąć o jedno miejsce. Możemy oczywiście w najnormalniejszy sposób wpisać do Porta liczbę 00010, ale my tego nie robimy, ponieważ chcemy poznać działanie nowej komendy.

RRF PORTA,f

Po wykonaniu tego działania liczba zapisana w PORTA będzie miała postać 00010, czyli taką jaką oczekiwaliśmy. To f na końcu oznacza, że przesuniętą wartość wpisujemy do PORTA. Gdyby komenda miała postać:

RRF PORTA,w

Liczba, czy mówiąc ściślej wynik nie zostałby zapisany do PORTA tylko do rejestru w. Nasz PORTA miałby wtedy wygląd taki jak na początku czyli 00100.

Najpierw wpisujemy jedynkę

Hasło z tytułu jest chyba najważniejszą rzeczą w tym projekcie. To jest chyba jedyne miejsce, w którym można i popełnia się błąd. Próba przesunięcie zawartości rejestru, w którym znajduję się liczba 00000 spełźnie na niczym. Zapamiętaj, żeby przesunąć jakakolwiek jedynkę w lewo, czy w prawo najpierw musimy ta jedynkę tam wpisać, chyba że już tam jest 😉 . W każdym bądź razie rejestr, na którym chcemy dokonać przesunięcia musi zawierać choćby jedną jedynkę.

Program

Po kilku wstępnych uwagach bierzemy się za program. Oczywiście na samym początku ustawiamy fusebity, deklarujemy procesor itp. Kolejny krok to ustawienie portów. Ja w swoim programie jako port wyjściowy dla LED przyjąłem PORTA, ale równie dobrze mógłby to być PORTB. Nawet byłoby lepiej, ponieważ do niego możemy podłączyć większą ilość LED-ów.

Procedury, rotacja w lewo

Kolejną czynnością do wykonania dla programisty, czyli w tym przypadku Ciebie, jest wpisanie tej jedynki do aktualnie czystego, wyzerowanego rejestru. Jak już wspominałem musimy mieć co przesuwać. Osobiście na wszelki wypadek, gdyby coś w rejestrze przez przypadek znalazło się po zaprogramowaniu, zeruje cały rejestr przed głównym programem komendą:

CLRF PORTA

Wpisanie wspomnianej jedynki może wyglądać tak:

movlw 01h ;wpisanie pierwszej jedynki

movwf PORTA ;wpisanie do PORTA 1 do najmłodszego bitu

Teraz wystarczy już wpisać komendę RLF i wszystko będzie działać. STOP. Zapomnielibyśmy o przymusie dodania opóźnienia pomiędzy włączanie  i wyłączanie kolejnych LED-ów.

Opóźnienie

Podprogram opóźnienia był już ostatnio opisany, więc nie ma co marnować na to objętości kolejnego. Tym razem dla uzyskania odpowiednio długiego opóźnienia użyłem aż trzech zmiennych. Ich inicjalizacja wygląda u mnie tak:

;***ZMIENNE***

cblock 0x0c ;blok zmiennych

liczba1 ;zmienna do opóźnienia

liczba2 ;zmienna do opóźnienia

liczba3 ;zmienna do opóźnienia

endc ;koniec bloku zmiennych

Natomiast sam podprogram opóźnienia tak:

opoznienie ;podprogram opóźnienia (długie)

movlw .4 ;czterokrotne powtórzenie najdłuższej pętli petla1

movwf liczba3

petla1

movlw .200 ;200 razy powtarza petla2

movwf liczba2

petla2

movlw .200 ;200 razy powtarza petle3

movwf liczba1

petla3

decfsz liczba1

goto petla3

decfsz liczba2

goto petla2

decfsz liczba3

goto petla1

return ;powrót do programu

Rotacja w lewo

Po wpisaniu podprogramu opóźnienia możemy już dokonać przesunięcia. Piszemy więc w ciele głównym programu np.

Program

Call opóźnienie

Rlf PORTA,f

Goto program

Kompilujemy odpalamy. Okazuje się, że program działa zgodnie z zamierzeniami. Przemiata jedynką po kolei po wszystkich wyjściach aż do samego końca. My jednak chcemy, żeby po osiągnięciu ostatniego wyjścia program zaczął wracać kolejno do poprzedniego i tak aż do pierwszego, a następnie znowu do drugiego aż do końca i tak dalej.

Sprawdzanie czy liczba osiągnęła pożądany stan

Naszym zadaniem jest teraz wyłapać moment, w którym włączone jest ostatnie wyjście i wymusić rotację w drugą stronę. W moim przypadku dla ostatniego wyświetlanego położenia jedynki w PORTA znajduję się liczba 01000 (PORTA.4 nie biorę pod uwagę ze względu na występowanie tam taimera). Jak widac musimy znaleźć moment, w którym bit PORTA,3 jest ustawiony. Dokonujemy tego znaną już procedurą :

Btfss PORTA,3

Jeżeli PORTA,3 będzie ustawiony to program przeskoczy o dwa miejsca na przykład do goto prawo, a jeżeli będzie wyzerowany powróci do programu przesuwania w lewo.

Btfss PORTA,3

Goto lewo

Goto prawo

Nasz program powinien składać się z dwóch części. Pierwsza to podprogram prawo,  a druga to podprogram lewo. W podprogramie prawo odczekujemy opóźnienie, przesuwamy w prawo, sprawdzamy czy osiągnęliśmy stan końcowy. Jeżeli osiągnęliśmy to idziemy do podprogramu prawo, a jeżeli nie wykonujemy kolejne kroki w podprogramie lewo. Podprogram prawo wygląda identycznie tyle, że przesuwamy w prawo, sprawdzenia dokonujemy dla ustawienie PORTA,0, a jeżeli będzie on ustawiony to idziemy do podprogramu lewo.

PS. W tym przypadku nie chodzi mi o podprogramy wywoływane komendą CALL, tylko zwykłe etykiety prawo, lewo, do których dostajemy się przez komendę GOTO.

Miejsce opóźnienia

Ważne jest, żeby procedura opóźnienia była na samym początku podprogramu. Mam nadzieję, że powód wydaję Ci się oczywisty. Po prostu dzięki niej możemy zobaczyć jak gdyby liczbę wpisaną do PORTA. Jako, że chcemy oglądać kolejne stany 00001, 00010, 00100, 01000, 00100 itd. Opóźnienie musi wystąpić już na samym początku gdy mamy wpisaną do rejestru PORTA jedynkę do najmłodszego bitu. Jeżeli najpierw dokonalibyśmy przesunięcia, a następnie dodali opóźnienie ta jedynka na najmłodszym bicie trwałaby tak krótko, że zamiast niej zobaczylibyśmy od razu stan 00010. Tak samo, gdy wykryjemy stan skrajny. W moim przypadku jest to PORTA,3 = 1 lub PORTA,0 = 1, musimy poczekać na wyświetlenie. Z tego względu opóźnienie umieszczamy przed, a nie po rotacji. Pewnie było to dla Ciebie oczywiste, ale zawsze warto się upewniać 😉 .

Zakończenie i przykładowy program

Dobrze by było gdybyś sam powalczył z napisaniem programu linijki LED. Najważniejsze fragment masz tutaj wklejone, ale wcale nie musisz z nich korzystać. W razie problemów dodaje program, który wykonałem. Następna lekcja to będzie omówienie przycisków. Zajmiemy się eliminacją drgań styków i dostosowaniem microswitchy do swoich potrzeb. Możliwe, że zdążymy również wzbogacić zaprogramowaną linijkę LED o obsługę przycisków. Do zobaczenia. Pamiętaj o komentarzu 😉 .

From → Kurs

Dodaj komentarz

Dodaj komentarz