AT89C2051 i przerwania



Masz problem? Zapytaj na forum elektroda.pl z bramką pl.misc.elektronika!

Poprzedni Następny
Wiadomoœć
spis treści
From: Piotr Laskowski <Piotr.Laskowski_at_nospam_f117.n480.z2.fidonet.org>
Date: Sun, 06 Dec 98 22:35:19 +0100
Subject: AT89C2051 i przerwania



Cześć All !

Robie znajomemu uklad mierzacy predkosc wozka poruszajacego sie na szynie
zawieszonej na scianie - robia badania opryskiwaczy przy roznych predkosciach
jazdy.
Pomiar predkosci zrobilem na dwoch fotorezystorach oswietlanych przez jadacy
wozek. Generuje to dwa ujemne impulsy, ktore podaje na wejscia INT0 i INT1
Atmelka 2051. Jedno przerwanie uruchamia a drugie zatrzymuje licznik T0, ktory
zlicza do 250 generujac przerwania co 0.5ms (kwarc 6MHz). Znajac droge wylicze
sobie predkosc.
Zeby bylo trudniej wozek jedzie raz w lewo, raz w prawo, wiec INT0 raz
uruchamia licznik, a raz zatrzymuje, w zaleznosci od stanu flagi.
Zeby nie bylo problemow z wielokrotnym zglaszaniem tego samego przerwania
(wozek z zarowka moze jechac powoli i drgac) po otrzymaniu przerwania INT0
kasuje flage zezwolenia na to przerwanie i ustawiam zezwolenie na INT1, oraz
odwrotnie - po otrzymaniu INT1 zezwalam tylko na INT0.

Sprawa wydaje sie byc prosta jak drut, ale pojawil sie problem, otoz pomimo
zamaskowanego przerwania np. INT0 podajac kilkukrotnie niski poziom na INT1
(symulacja "drgan stykow") otrzymuje trzy zgloszenia przerwania w takiej
kolejnosci INT1, INT0, INT1 - dokladnie trzy. Powinno byc tylko jedno INT1.
Za cholere nie wiem skad sie bierze wtedy przerwanie od INT0, siedze juz nad
tym drugi dzien. (Przy INT0 jest analogicznie - INT0, INT1, INT0)
Zasilanie i samo przerwanie na oscyloskopie wyglada gladziutkie jak pupcia
niemowlaka, zadnych szpilek, w dodatku te 3 kolejne przerwania sugeruja blad
software'owy. Co to moze byc? Obsluga przerwania wyglada tak:

ÄÄÄÄÄÄÄÄÄÄÄÄ[ Cytuję: foto10.asm ]ÄÄÄÄÄÄÄÄÄÄÄÄ
ORG 03h ;zewnetrzne przerwanie INT0
JMP INT0_IRQ
[...]

INT0_IRQ: PUSH ACC
CLR EA ;wylacz przerwania
JNB STARTSTOP,T0STOP_0
;START
MOV IE,#00000110b ;maskuj INT0 i T1, wlacz INT1 i T0
MOV TL0,#0 ;licz od zera
SETB TR0 ;uruchom licznik T0
CLR A
MOV LOVT0+0,A ;inicjuj licznik przerwan z T0
MOV LOVT0+1,A
CLR STARTSTOP ;nastepny bedzie stop
CALL WYSW ;wyswietl komunikat
JMP INT0_1

T0STOP_0: ;STOP
MOV IE,#00001100b ;maskuj INT0 i T0, wlacz INT1 i T1
CLR TR0 ;zatrzymaj licznik T0
SETB STARTSTOP ;nastepny bedzie start
CALL CALALICZBA
MOV LOVT1,#0 ;licz T1 od zera
SETB TR1 ;uruchom licznik T1
INT0_1: CALL BEEP ;daj glos
POP ACC
CLR IE0 ;zbedne, ale na wszelki wypadek
SETB EA ;wlacz przerwania
RETI
[...]
;Inicjalizacja ukladu
MOV TCON,#00000101b ;konfig. przerwan+wskazniki
MOV TMOD,#00010010b ;konfig. licznikow
MOV IP,#00000101b ;priorytet przerwan
MOV IE,#10000111b ;rejestr zezwolen na przerwania
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ[ koniec cytatu ]ÄÄÄÄÄÄÄÄÄÄÄÄÄÄ

Obsluga przerwania od INT1 jest analogiczna, zmienia sie tylko maska
przerwania. Licznik T1 po jakims czasie po przerwaniu "STOP" wylacza maski
obydwu przerwan, tak aby mozna bylo uzyc tego samego (dowolnego) przerwania jako
"START" (MOV IE,#10001111b)

ps. sorry za przydlugi post, ale sami wiecie jak to bywa... :-]

Piotrek.

Poprzedni Następny
Wiadomoœć
spis treści
From: Olgierd Cybulski <cybulski_at_nospam_pkpf.if.uj.edu.pl>
Subject: Re: AT89C2051 i przerwania
Date: Mon, 07 Dec 1998 09:49:38 +0100


Piotr Laskowski wrote:


Pomiar predkosci zrobilem na dwoch fotorezystorach oswietlanych przez jadacy
wozek. Generuje to dwa ujemne impulsy, ktore podaje na wejscia INT0 i INT1
Atmelka 2051. Jedno przerwanie uruchamia a drugie zatrzymuje licznik T0, ktory
zlicza do 250 generujac przerwania co 0.5ms (kwarc 6MHz). Znajac droge wylicze
sobie predkosc.

Nie powiem, żebym się wyspał,
może w związku z niewyspaniem właśnie
nie całkiem rozumiem Twój program, np. nie wiem
do czego używasz licznika T1 .

Na wstępie chciałbym zauważyć, że przyczyną Twojego problemu
może być niekasowanie znaczników zgłoszenia przerwań INT1 i INT0 .
Jeśli przerwania zgłaszane są przez coś, co zachowuje się
jak drgający styk, to - jak słusznie zauważyłeś poniżej :

Zeby nie bylo problemow z wielokrotnym zglaszaniem tego samego przerwania
(wozek z zarowka moze jechac powoli i drgac) po otrzymaniu przerwania INT0
kasuje flage zezwolenia na to przerwanie i ustawiam zezwolenie na INT1, oraz
odwrotnie - po otrzymaniu INT1 zezwalam tylko na INT0.

ale być może popełniasz błędne założenia co do "kasowania flagi
zezwolenia
na przerwanie". Samo zamaskowanie przerwań przez wpisanie zera do
odpowiednich
bitów rejestru IE nie wystarczy !!!
To powoduje tylko zablokowanie związku przyczynowo-skutkowego pomiędzy
sygnałem przerywającym a procedurą obsługi przerwania, tzn. sygnałowi
przerywającemu nie towarzyszy uruchomienie procedury obsługi przerwania.
Jednak fakt zaistnienia sygnału przerywającego (czy to zbocza, czy
poziomu
w zależności od konfiguracji) jest ZAPAMIĘTANY w "zatrzasku" , np.
fakt pojawienia się impulsu przerywającego INT0 jest zapamiętany
w bicie IE0 rejestru TCON ! A zatem, jeśli twój fotorezystor uruchomi
INT0 , to procedura obsługi zablokuje maskę w celu zapobieżenia
ponownemu
przyjęciu przerwania, po czym zakończy działanie i SPRZĘTOWO wyłączy
znacznik zgłoszenia IE0 w TCON . Jeśli jednak zaraz potem pojawi
się - wskutek drgań wóżka - nowy impuls sygnału przerywającego INT0,
to - pomimo zamaskowania zezwolenia EX0 - zgłoszenie zostanie
zapamiętane
w IE0, i gdy tylko maska EX0 zostanie ustawiona ("odmaskowana") ,
natychmiast spowoduje to przejście do obsługi przerwania - zakładam
że w danej chwili jest priorytetowe.
A zatem przed odmaskowaniem przerwania INT0 w procedurze obsługi
przerwania INT1 należe WYZEROWAĆ znacznik zgłoszenia przerwania
INT0 instrukcją CLR IE0 i na odwrót.
Jak już napisałem , nie chce mi się wgłębiać w Twój program, ale
przypuszczam, że właśnie o to chodzi.
Tak poza tym, możnaby - chyba - rozwiązać sprawę prościej, wykorzystując
obydwa liczniki.
Przerwanie INT0 uruchamiałoby licznik T0 i kasowało T1,
zaś przerwanie INT1 kasowaloby T0 i uruchamialo T1, czyli na odwrót .
Dzięki temu w zależności od zwrotu prędkości wynik pomiaru
czasu przelotu byłby albo w zmiennych inkrementowanym przez przerwanie
T0,
albo przez T1 .
Pełna symetria, i na dodatek blokowanie przerwań byłoby zbędne -
nic się przecież nie stanie, jeśli uruchomią się kilka razy pod rząd
(trzeba zrobić tak, żeby uruchamiały się zboczem, nie poziomem).
Jeśli któryś z liczników jest ci potrzebny do czego innego (T1 ? )
to najprawdopodobniej nic nie szodzi, można napisać program tak,
żeby T1 służył jednocześnie do dwóch różnych celów, np.
inkrementacji zmiennej pomiaru, oraz wytwarzania dźwięku
o określonej częstości i czasie trwania.
Nie wiem, czy czasem również w Twoim programie jest konieczne
blokowanie przerwań. Być może jest niepotrzebne - stanie się coś,
jeśli INT0 lub INT1 uruchomi się kilka razy ? Jeśli za każdym
razem zrobi to samo, to nic się nie stanie, poza chwilowym
zablokowaniem działania reszty programu powtórzonymi obsługami
"migajacych" przerwan.

O.C.

-------------------------------------------------
wśród blasku laserów i szumu wentylatorów
-------------------------------------------------