Programowanie
Programowanie
'ing Ii Obsługa w
: ą_.ftkt.Myswiet.l
- g_BaneWyświe-
- g_DaneCom! 1
(~(l«COMl) ,
- (l«COM2) , ~ (KCCOM3) , ~ (l«COM4) } ;
IllllinmillllltlUIIIIIII/
dostrzegą jednak migotanie wyświetlaczy. Przyjrzyjmy się naszemu programowi - z jaką częstotliwością obsługujemy wyświetlacze? Dobrze byłoby, gdybyś mógł razem ze mną zajrzeć do karty katalogowej naszego mikrokontrolera. Nasz tiiner wywołuje przerwanie po każdym przepełnieniu — oznacza to przerwanie co 256 zliczonych impulsów'. Dodatkowo rejestr TCCRO został ustawiony w taki sposób, że licznik zlicza impulsy zegara systemowego, podzielone w preskalerze przez 64. Jak łatwo obliczyć:
4MHz/(256*64) = 2441 łz
Przy czterech wyświetlaczach otrzymujemy częstotliwość odświeżania całego pola rzędu 60Hz. Niby więcej niż granica częstotliwości, jaką człowiek zauważa, jednak w praktyce często tak niska częstotliwość jest nieprzyjemna w odbiorze. Można spróbować ją podwyższyć, zmniejszając stopień preska-lera. Znów zaglądamy do dokumentacji. Oj -niedobrze... najbliższy, niższy stopień jest 8 razy mniejszy. Można zobaczyć, jaki będzie efekt. Zamień pierwszą linijkę inicjacji limera
TCCRO = 1 «CSO 1;
Migotanie rzeczywiście całkowicie ustało. Warto zobaczyć, jak takie przyspieszenie wyświetlacza obciążyło procesor. Z pomocą przyjdzie nam tutaj AVRStudio. Zakładam, żc jego uruchomienie oraz wczytanie pliku programu nie sprawia Ci problemów. Jeśli pracujesz na poprzednim kodzie — w katalogu powinien nawet znajdować się już plik o rozszerzeniu aps. którego dwukrotne kliknięcie otworzy od razu AVRStudio zc skonfigurowanym symulatorem.
Uruchom teraz na chwilę program w trybie pracy ciągłej. Zatrzymaj go w dowolnym momencie za pomocą klawisza pauzy na pasku narzędziowym (CTRLI F5). Zależy nam, aby zatrzymać program już po inicjacji części sprzętowej, w pustej pętli głównej. Jeśli pechowo trafiłeś właśnie na obsługę przerwania - uruchom program jeszcze na sekundę i ponownie zatrzymaj. Innym, bardziej eleganckim sposobem zatrzymania programu w interesującym nas punkcie jest ustawienie kursora na instrukcji for i wybranie z paska narzędzi komendy Run to cursor (CTRL+F10).
Jest wiele sposobów, żeby sprawdzić czas, przez jaki będzie wykonywać się dana procedura. Jeśli jest to podprogram, można na przykład wyzerować licznik czasu tuż przed jego wywołaniem, kazać symulatorowi go przeskoczyć (F10) i już mamy czas wykonania procedury. Próbę dobrze jest powtórzyć kilkakrotnie i za czas wykonania podprogramu uznać otrzymany czas średni. W naszym przypadku mamy do czynienia z przerwaniem. Zasada będzie więc troszkę zmieniona, aczkolwiek ogólnie pozostaje zacho-
Spójrz na rysunek 22. Przedstawiłem na nim widok prawidłowo skonfigurowanego symulatora AVRS-tudio razem z dodatkowymi komentarzami. Spróbuj doprowadzić do podobnej sytuacji. Przyjrzyj się, jakie zakładki zostały przeze mnie rozwinięte w lewym panelu. Najbardziej interesuje nas licznik cykli. Wykonując kilkakrotnie komendę Run to cursor, stwierdzimy, że wykonanie pętli for zajmuje procesorowi dwa cykle. Zapamiętujemy tę wartość. Gdy program jest już zatrzymany, zerujemy licznik cykli, tak jak opisują to komentarze na obrazku. Ustawiamy flagę symulującą wystąpienie przerwania przepełnienia licznika 0 i wykonujemy ponownie komendę Run to cursor. U mnie licznik wskazał 82 cykle. Wiemy, że wykonanie samej pętli i dojście do kursora dodaje do tej wartości dwa cykle - aby uzyskać dokładny czas zajmowany przez przerwanie, należy wartość tę odjąć od uzyskanej. Po kilkakrotnej próbie, raz na 3 przerwania, czas wykonania jego obsługi wynosił 83 cykle. Jest to o tyle oczywiste,
// Wpisanie do tablicy próbnych war
::g_Da.neWyswietlacza ; = - (i«LS;D_B g DafteWyswie tlacza [ ) ■ ~ (1«LSD_A
i ~ ' «LED_D | l«i£0_E I T-icLED S)
g_DaReKysw.ieflacza[2] = - (1«I,F.D_A :«LBI3_C | «LSD_ D I 14<LED_G)
• g_0ar.eHyswi e t.l aersj 3 ] ” B i
/ Wygaś
l«COM3 | l«COM4;
COMPORT |
II Wysłanie odpowiedniej danej
LEDPORT = g_DaneWyswietlacza [g_AktWyswietlacz] ;
// Włączenie odpowiedniego wyświetlacza COMPORT S= g_DaneCom[g_AktWyswietlacz] ;
// Zwiększenie Stanu zmiennej wskazującej na // obsługiwany wyświetlacz ++g_AktWyswietlacz; if (g_AktWyswietlacz > 3) g_AktWyswietlacz = 0;
ABC... C C a format linii
Może zauważyłeś, że w kolejno przedstawianych kodach źródłowych dzielę linię praktycznie tam, gdzie jest to dla mnie wygodne, listing opracowuję tak, aby zmieścił się ładnie w ramce? Wydawać by się mogło, że jest to tylko zabieg mający zmniejszyć objętość całego tekstu, okazuje się jednak, że jakkolwiek wpisałbyś kod - wszystko będzie działać.
C jest językiem niezależnym «d formatu linii. Ważne jest to, aby każdą instrukcję pojedynczą zakończyć znakiem średnika, wnżne jest by zawsze zaniknąć otwarty nawias czy klamrę. Natomiast w większości przypadków zupełnie nie ma znaczenia, gdzie rozpoczniemy nową linię, wstawimy znak tabulacji czy więcej znaków spacji. Oznacza to, że zwykle możesz przerwać pisanie bieżącej linii i rozpocząć je w linii następnej. W obliczeniach na przykład możesz to zrobić przed lub po znaku działania.
W rzadkich przypadkach, w których koniec linii ma znaczenie (przykładem jest dyrektywa tłdefine), a linia staje się nieznośnie długa, można zastosować na końcu znak ukośnika (\). Spowoduje to, że kompilator potraktuje linię następną jako przedłużenie poprzed-
Elektronika dla Wszystkich Lipiec2005 39