Zakład Energoelektroniki i Sterowania Politechnika Poznańska |
---|
LABORATORIUM PROGRAMOWANIA MIKROPROCESORÓW |
Temat ćwiczenia: Ćw.3 „System obsługi przerwań oraz licznik/timer” |
Wydział Budowy Maszyn i Zarządzania Kierunek: Mechatronika |
Uwagi: |
Wstęp
System/Układ obsługi przerwań – w wielu aplikacjach mają zastosowanie układy w których istnieje konieczność reakcji układy na bodźce wewnętrzne lub zewnętrzne układu – takimi bodźcami mogą być sygnał z transmisji szeregowej, przepełnienie licznika/czasomierza czy naciśnięcie przycisku; takie bodźce nazywamy przerwaniami. Układ obsługi przerwań pozwala na natychmiastowe wykonanie działanie zdeterminowanego wystąpieniem przerwania z chwilowym zawieszeniem wykonywania pracy programu.
W układzie którym zajmowaliśmy się na zajęciach mieliśmy do czynienia z kilkoma źródłami przerwań:
przepełnienie licznika/timera T0 lub T1
transmisja szeregowa (nie korzystaliśmy z tego podczas zajęć)
naciśnięcie przycisku P3.2 lub P3.3 - bodziec zewnętrzny
Do sterowania układem przerwań służą rejestry: rejestr IE oraz rejestr IP. Rejestr IE odpowiada za zezwolenia na obsługę przerwań na liniach różnych źródeł przerwań, natomiast rejestr IP za priorytet przerwań. Pomińmy tu rejestr IP.
Rejestr IE określany jest przez 8 bitów:
IE 7 | IE 6 | IE 5 | IE 4 | IE 3 | IE 2 | IE 1 | IE 0 |
---|---|---|---|---|---|---|---|
EA | --- | ET2 | ES | ET1 | EX1 | ET0 | EX0 |
Zezwolenie na obsługę systemu przerwań | Rezerwa | Zezwolenie na obsługę przerwań na linii licznika T2 | Zezwolenie na obsługę przerwań na linii transmisji szeregowej | Zezwolenie na obsługę przerwań na linii licznika T1 | Zezwolenie na obsługę przerwań na linii wejścia zewnętrznego INT1 (linia P3.3) | Zezwolenie na obsługę przerwań na linii licznika T0 | Zezwolenie na obsługę przerwań na linii wejścia zewnętrznego INT1 (linia P3.2) |
Na zajęciach korzystaliśmy tylko z bitów EA, ET1, ET0 i EX0. W programie podawało się wartość rejestru IE w kodzie szesnastkowym jako reprezentację stanów wszystkich bitów składowych tego rejestru, np.
IE=0x01 oznacza to samo, co: IE=00000001 (jedynka tylko dla bitu IE0) co oznacza że zezwoliło się na obsługę przerwań tylko na linii P3.2
Na zajęciach oraz w programach które tworzyliśmy na zajęciach padły też oznaczenia, mianowicie: TMOD, TR0, TCON, IT0.
TCON tak samo jak IP i IE jest rejestrem, jest to rejestr kontroli timera. Do jego bitów należą m.in. TR0 (startuje timer, TR0 to szósty bit rejestru TCON), IT0 (warunek reakcji timera – 1 dla zbocza opadającego, 0 dla stanu niskiego)
TMOD jest rejestrem trybu pracy timera/licznika, składa się z 4 bitów:
GATE | C/T | M1 | M0 |
---|---|---|---|
1 – licznik 0 – timer |
Odpowiedzialne za tryb pracy: 0,1 – tryb 16-bitowy 1,0 – tryb 8-bitowy z autoprzeładowaniem … |
Wartość rejestru jest podawana analogicznie jak dla rejestru IE. Przykład:
TMOD=0x00 – czyli tryb pracy 13-bitowy, układ pracuje jako timer
TMOD=0x01 – czyli tryb pracy 16-bitowy, układ pracuje jako timer
Do zapamiętania jest częstotliwość oscylacji, tj. zmiany stanów procesora, na podstawie możemy obliczyć co ile taktów powinien się zmienić stan diody aby miganie diody odbywało się z dokładną zadaną częstotliwością. Tak więc:
fosc = 1 572 864 Hz
Na zajęciach ustawialiśmy timer w 13-bitowym trybie pracy, oznacza to 213 = 8192 stanów.
$$\frac{1\ 572\ 864}{8\ 192} = 192$$
Tyle razy na sekundę następuje zmiana stanu na 1 takt pracy timera. Aby policzyć ile razy na sekundę zmienia się stan diody liczymy:
$$\frac{192}{8} = 24$$
Czyli 24 zmiany stany diody na sekundę, dioda więc mruga z częstotliwość połowę mniejszą czyli 12 razy na sekundę.
Programy tworzone na zajęciach wraz z objaśnieniami linijek kodu źródłowego
Program obsługujący miganie diody P2.4 o zadanej częstotliwości migania
Kod programu:
#include<ADUC845.H> dołączenie biblioteki ze sterownikami do mikrokontrolera ADuC845
void timer0_isr(); deklaracja funkcji typu pustego, która ma dotyczyć przerwania na linii timera/licznik 0
void ext0_isr(); deklaracja funkcji odpowiedzialnej za przerwanie na linii External INT0, czyli na linii P3.2 (przycisk)
sbit LED=P2^4; zmienna bitowa LED zdefiniowana tak że oznacza stan diody P2.4 (przy wartości 1, diode jest zapalona, przy wartości 0 – zgaszona)
char x; zmienna znakowa, będzie potrzebna do wyliczania liczby taktów
//------------------- program głowny ---------//
void main ()
{
EA=1; zezwolenie na obsługę systemu przerwań
ET0=1; zezwolenie na obsługę przerwania od licznika czasomierza T0
EX0=1; zezwolenie na obsługę przerwania na linii 3.2
TMOD=0x01; //trzyb 13bitowy timera 0 tryb pracy timera – 13-bitowy
TR0=1; sygnalizowanie startu pracy timera
while(1) nieskończona pętla while służy do utrzymania kontroli nad kontrolerem
{
}
}
//----------------------------------------------------------------------------------------//
void timer0_isr() interrupt 1 definicja przerwania na licznika timera T0
{
x++; iteracja – zliczanie taktów – dodaje wartość 1 do obecnej już wartości x, po czym sprawdzany jest warunek poniżej
if ( x==12) ten warunek ma za zadanie negowanie stanu diody P2.4 po osiągnięciu 12 taktów pracy licznika czyli po czasie pół sekundy
{
LED=~LED; //zaneguj stan poprzedni negowanie stanu diody, polecenie gasi diodę gdy jest zapalona i zapala ją gdy jest zgaszona
x=0; po zmianie stanu diody zeruje liczbę taktów, w wolnym tłumaczeniu może rozumieć tą instrukcję tak że co pół sekundy zmienia stan diody, jeśli chcemy aby stan diody się zmieniał co sekundę, wystarczy zamiast wartości w warunku powyżej wstawić wartość 2 razy większą czyli 24
}
}
// ile mruga na sekunde jesli fosc=1572864 Hz
void ext0_isr() interrupt 0 funkcja warunkująca zachowanie sie układu przy przerwaniu pochodzącego z linii P3.2 – gdy nastąpi to przerwanie zapala się dioda P2.4, po czym następuje zatrzymanie timera
{
LED=1; zapalenie diody bez względu na jej poprzedni stan
TR0=~TR0; negowanie stanu pracy timera (włącza wyłączony timer lub wyłącza włączony timer)
}
Program pozwalający na ustalenie różnych okresów diody zapalonej oraz zgaszonej
Kod programu:
#include<ADUC845.H>
void timer0 ();
sbit dioda=P2^7;
char x;
//------------------- program głowny ---------//
void main ()
{
EX0=1;
EA=1;
ET0=1;
TMOD=0x01; //trzyb 13bitowy timera 0
TR0=1;
while(1)
{
}
}
//-------------------------------------------------------//
void timer0() interrupt 1 definiowanie przerwania timera 0
{
x++;
if(x==12) po minięciu 12 taktów czyli pół sekundy zmienia się stan diody na przeciwny…
{
dioda=~dioda;
}
if(x==24) …po minięciu kolejnych 12 taktów czyli już łącznie 24 od początku działania funkcji przerwania timera, zmienia sie stan diody na przeciwny…
{
dioda=~dioda;
}
if(x==48) … tu się zmienia czas po jakim diode zmienia swój stan, tym razem po sekundzie…
{
dioda=~dioda;
}
if(x==60) tu znów po połowie sekundy zmiana stanu diody
{
dioda=~dioda;
}
if(x==84) z kolei tu zmiana stanu diody po upłynięciu całej sekundy od poprzedniej zmiany stanu diody, dodatkowo po tej zmianie stanu diody, zmienna znakowa ulega wyzerowaniu, więc program działa od nowa
{
dioda=~dioda;
x=0;
}
}
Wnioski, spostrzeżenia, uwagi
System obsługi przerwań dzięki zastosowaniu sygnałów o wyższym priorytecie może być użyty np. w systemach ochrony danych przy silnie przeciążonych magistralach systemowych, także w komunikacji z urządzeniami zewnętrznymi, takimi jak: klawiatura, stacja dysków,
Jest możliwe dowolne definiowanie przerwania w zależności od dostępnego sprzętu czy oprogramowania
Przy ustawieniu zbyt wysokiej częstotliwości przełączania stanu diody, dioda może w ogóle nie gasnąć gdyż zbyt wysoka częstotliwość powoduje iż praktycznie nie zanika napięcie na diodzie – nie zdąży zgasnąć a znowu się zapali
Do każdego przerwania należy napisać program aby system mógł obsłużyć dane przerwanie
Z pewnością zaletą systemu przerwań jest fakt, iż program nie musi ciągle sprawdzać czy urządzenie wymaga obsługi – sprawdzanie to jest realizowane już na poziomie sprzętowym