Programowanie ■
Programowanie ■
momencie za pomocą klawisza pauzy na pasku narzędziowym (CTRL+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 - uiuchom 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 zachowana.
Spójrz na rysunek 22. Pizedstawiłcm na nim widok prawidłowo skonfigurowanego symulatora AVRS-tudio razem z dodatkowymi komentarzami. Spróbuj doprowadzić do podobnej
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 limer 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 prze2 ( 64. Jak łatwo obliczyć:
4MHz/(256*64) = 244Hz
Przy czterech wyświetlaczach otrzymuje-) my 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 timera na:
TCCRO = I «CS01;
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, że 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 apSy kr.órego dwukrotne kliknięcie otworzy od razu AYRStudlo zc skonfigurowanym symulatorem.
Uruchom teraz na chwilę program w trybie pracy ciągłej. Zatrzymaj go w dowolnym
ABC... C C a format linii
Może zauważyłeś, że w kolejno przedstawdanych 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 tek-j stu, okazuje się jednak, że jakkolwiek wpisałbyś kod - wszystko będzie działać.
C jest językiem niezależnym ud formatu linii. Ważne jest to, aby każdą instrukcję pojedynczą zakończyć znakiem średnika, ważne jest by zawsze zamknąć otwarty nawias czy kłamię. 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, żc 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 ikiefme), 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 poprzedniej.
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.
Listing 11 Obsługa wyświetlacza LED u przerwaniach
finoludo <avr\io.h> linclude CinttypGO.h>
#include <ćvr\signal.h> finclude <avr\interrupt. h>
(... definicje wyprowadzeń - bez zmian...)
uint8_t q_AkiWyswietlacz ■ ;
nint8_t g_DaneWyswietlaczaf;}; uint8_t g__DaneOom[<ł ] =
t~(l«COMl), ~(3«CO«2), ~(l«rOM3). m:«C0M4)); int main(void)
t
/////////////////////////////
// inicjacja
ŁEODDR = Qx£tj
COMDDR - L«COMl I . «COM2 I «COM3 i «C0N4;
// TiroerO
TCCRO - 1«CS01 |1«CSOO;
TIMSK - 1«TOIEO;
// Globalne zezwolenie na przerwania
sei O ;
// koniec inicjacji /////////////////////////////
// Wpisanie do tablicy próbnych wartości ę__DaneWyswiet lacza [ ] «* - ( «T.F.n_B | <<LED_C) ; ę_DaneWyawietlacza[1) - -(1«LED_A | i <«rLED_B | 1«LED_D | 1 «LED_E | : <<LED_C) i ę_DaneWysvietłacza[2] >= ~(1«LED_A | 1<<UED_D i 1«LED_C | 1«LEDJJ | i«LED~G); ę DaneWyswietlacza[3] » M1«LED_B I 1«L.EL»_C . «LED_F I «LSD G) ;
for(;;)
t
1
recurn 0;
}
li_
// Obsługa przerwań ST GNAŁ | SI G_CVER5'LOW 0)
t
// Wygaozonic wyświetlaczy
COMPDRT |= 1«CCM1 | 1 «COM2 | >«COM3 | «COM4;
// Wysianie odpowiedniej danej
LEDPDRT = g_DaneWyswietlacza[g__AktWyswietlaczl ;
// Włączenie odpowiedniego wyświetlacza COMPORT &= g_DaneCom[g AktWyswietlacz]; ii Zwiększenie stanu zmiennej wskazującej na ii obsługiwany wyświetlacz ++g_AktWyswiotlac2; i£(g_AktWyswietlacz >3) g_AktHyawietlacz = 0;
)
Elektronika dla Wszystkich Lipiec2005 39