logo elektroda
logo elektroda
X
logo elektroda
REKLAMA
REKLAMA
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

AT89C2051 – niewywoływane przerwanie T0 przy jednoczesnym INT0, flaga TF0 ustawiona

01 Sty 2005 17:49 1946 18
REKLAMA
  • #1 1102190
    Konto nie istnieje
    Konto nie istnieje  
  • REKLAMA
  • #2 1102337
    Phaeton
    Poziom 19  
    Posty: 411
    Pomógł: 15
    Ocena: 165
    Opis obszerny, ale prawdę mówiąc bez przykladowego kodu w którym ujawnia się domniemany bug to można tylko wróżyć z fusów. Mozesz podrzucic kod (chyba ze jest sciśle tajny :-)), tobym sobie potestował na moim. Na moje błąd za duży, żeby się przemknął. Luźna sugestia: czy procedura obsługi przerwania INT0 robi coś z timerem, albo czy powrót z przerwania jest 100% clean?[/img]
  • #3 1102596
    Konto nie istnieje
    Konto nie istnieje  
  • #4 1102642
    ljmp
    Poziom 14  
    Posty: 116
    Pomógł: 6
    Ocena: 9
    Na moje oko w programie nie ma nic intrygujacego, orpocz tego ze brakuje ci kilkadziesiat srednikow. Kompilator ci to przyjal wogole ??
    Nie zebym sie czepial ale troche by mnie to zdziwilo.
  • #5 1102658
    Konto nie istnieje
    Konto nie istnieje  
  • REKLAMA
  • #6 1103170
    Vassili Zaicev
    Poziom 12  
    Posty: 27
    mnie rowniez wlasnie wystapil podobny problem, z AT89S52

    wykorzystuje fizycznie wejscia INT0 oraz INT1, na oba wejscia idzie ten sam sygnal , impulsy prostokatne

    w programie oczywiscie wlaczam przerwania EX0 i EX1, ustawiam zbocza przeciwstawne ITx, i podpinam sie pod wektory obu przerwan

    w tle odpalam timer2 wraz z obsluga przerwania

    natomiast w petli glownej wykonuje sobie cyklicznie pewna operacje

    wszystko dziala bez problemow gdy zewnetrzne zrodlo podajace impulsy jest podlaczone do zasilania

    natomiast gdy zrodlo jest bez zasilania - timer2 przestaje funkcjonowac, ale petla glowna wykonuje sie dalej

    to samo dzieje sie gdy uzywam przerwan timer0 i timer1, ale dla pewnosci ze nie ma powiazania z INTx uzywam timer2

    wyglada jakby przerwania sie blokowaly
    odkrylem ze sprawca w tym wypadku jest INT0 skonfigurowany IT0 = 1 czyli zbocze narastajace
    po ustawieniu zbocza na opadajace IT0 = 0 problem znika

    pytanie dlaczego dziwny stan na wejsciu INT0 przy IT0 = 1 powoduje blokade innych przerwan natomiast pozwala na dalsze wykonywanie programu
  • REKLAMA
  • #7 1103331
    Konto nie istnieje
    Konto nie istnieje  
  • #8 1103893
    Vassili Zaicev
    Poziom 12  
    Posty: 27
    janchar napisał:


    W ksiazce pt. "Mikrokomputery jednoukladowe rodziny MCS-51" Andrzeja Rydzewskiego na str.80 pisze "Przerwania zewnetrzne sa zglaszane opadajacym zboczem lub niskim poziomem sygnalu na wejsciach INT0 i INT1, przy czym sposob zglaszania okresla się programowo. Bit TCON.0 (IT0) oznacza ustawienie sposobu zgloszenia przerwania!


    Rzeczywiscie do tej pory sadzilem ze IT0 przelacza zbocze opadajace/zbocze narastajace. Jasne ze ten bit okresla sposob zgloszenia przerwania, natomiast nie wiedzialem ze to przelaczenie oznacza w rzeczywistosci zbocze opadajace/stan niski.


    janchar napisał:

    Tutaj, jak w pierwszym przypisie, zle interpretujesz bit IT0. Przerwanie nastapi w momencie przejscia z 1 na 0. Natomiast gdy IT0=0, to przerwanie nastapi, gdy INT0 jest w stanie 0. Musisz zadbac o to, aby sygnal zmienic spowrotem na 1 zanim nastapi koniec obslugi przerwania INT0, bo znowu wskoczy przerwanie. Co prawda u mnie w ksiazce jest blad w rozdziale 2.8.3, ktory sobie poprawilem, za to na str. 30 przy opisie slowa TCON jest napisane poprawnie. W zalaczniku wybrane strony z ksiazki.


    Janchar, masz racje, tego nie bralem pod uwage, ale z tego co wiem - gdyby przerwanie wskakiwalo caly czas - to zablokowaloby wykonywanie programu. Tymczasem petla glowna wykonuje sie. Staje tylko timer. I to mnie gnebi.
    Problem nie wystepuje gdy INT0 jest odwieszony lub przez rezystor odprowadzony do masy. Natomiast gdy nadajnik impulsow jest przylaczony bez zasilania, wtedy timer2 przechodzi do historii.

    I jeszcze jedna rzecz - dlaczego mam ustawic stan wysoki na INT0 skoro to ma byc wejscie, i do tego wejscia podlaczone jest inne urzadzenie ktore nadaje impulsy. Nie rozumiem tego jak interpretowac te porty, kiedy to jest wejscie a kiedy wyjscie. Wyglada jakby to zawsze bylo wejscie i wyjscie jednoczesnie.
  • #9 1104296
    ko_rex
    Poziom 19  
    Posty: 253
    Pomógł: 38
    Ocena: 2
    Kolego Vassili Zaicev. Taka jest własnie uroda '51, że porty są wejściami i wyjściami jednocześnie. Takie rozwiązanie pociąga za sobą pewne konsekwencje, a mianowicie niewielką wydajność prądową w stanie wysokim (kilkadziesiąt uA, w porównaniu z mA w niskim). Dzięki temu łatwo jest wymuszać stan niski na porcie, gdy sygnałem wyjściowym jest stan wysoki. Dlatego, aby poprawnie odczytać stan pinu, należy ustawić na nim stan wysoki. Jeśli ustawimy stan niski, to odczytam z pewnością "0", chyba, że "zgwałcimy" nasze wejście (a może lepiej wyjście) jedynką.
    A co do głównego zagadnienia. Proponuję tymczasowe rozwiązanie pętli głównej:
    
    start:
    	mov	sp,#stos
    	acall	ini
    
    tu:
    	djnz	r7,tu		;albo jakis inny nieużywany
    	clr	TF0
    	sjmp	tu
    

    Teraz w pętli głównej co jakiś czas będziemy kasować flagę TF0, więc może to wystarczy... (mało profesjonalnie...wiem, wiem...)
    Ooo... Wpadłem jeszcze na taki pomysł. Skoro procesor ma problem z obsługą przerwania, może by tak go zwolnić z tego zadania i zrobić to programowo? Wtedy w pętli głównej trzeba sprawdzać ciągle flagę przepełnienia licznika i w zależności do nie skakać do obsługi (oczywiscie z wyłączonym przerwaniem, programowym kasowaniem flagi i ret na końcu zamiast reti).
  • REKLAMA
  • #10 1105572
    Konto nie istnieje
    Konto nie istnieje  
  • #11 1106096
    shg
    Poziom 35  
    Posty: 2289
    Pomógł: 339
    Ocena: 135
    janchar napisał:

    Przerwanie z INT0 ma wyzszy priorytet. Po skonczeniu wykonywania przerwania RETI zostanie wykonany 1 rozkaz z petli glownej i spowrotem do przerwania z INT0.


    A to już działa, czy nie? Bo ja się w tym temacie pogubiłem :D

    Na wszelki wypadek: obsługa przerwania zajmuje za dużo czasu, już w trakcje wykonywania przerwania ustawiana jest flaga żądania przerwania (IE0) , ale procedura przerwania wykonuje się dalej. po rozkazie RETI ZAWSZE wykonany zostaje powrót i nawet, jeżeli zgłoszone zostało żądanie jakiegoś przerwania, zostanie wykonana jedna insrtukcja z głównego programu, albo z przerwania o niższym priorytecie, ale tylko pod warunkiem, że to przerwanie było obsługiwane w czasie, gdy wystąpiło przerwanie o priorytecie wyższym. Po wykonaniu jednej instrukcji następuje wywołanie przerwania o najwyższym priorytecie itd.

    Jeżeli więc w Twoim przypadku zdarzy się tak, że przerwanie timera zostanie wykonane, to będzie wykonywane po jednej instrukcji, za każdym razem, gdy w INT0 będzie RETI., gdy procek powróci z przerwania timera (po długim czasie :D) do programu głównego, to przerwanie timera nie zostanie już nigdy wywołane, bo zawsze będzie ustawiona flaga żądania przerwania INT0, albo to przerwanie będzie właśnie obsługiwane.

    Czyli jeżeli występuje taki efekt - obsługa INT0 trwa zbyt długo. może by tak zobaczyć z generatorem na INT0 nastawionym na mniejszą częstotliwość?

    Pamiętam, że też miałem dziwne ekscesy z timerem - okazało się, że procek był źle zaprogramowany (wykładało się na komurce z wektorem przerwania). Już był poruszany ten temat - proc padał po kilku programowaniach. U mnie dla odróżnienia czasami udawało się zaprogramować prawidłowo i program raz działał, raz nie, a ile się nawkur... to się opisać nie da :D
  • #12 1108263
    Konto nie istnieje
    Konto nie istnieje  
  • #13 1108319
    gmp
    Poziom 19  
    Posty: 434
    Pomógł: 29
    Ocena: 28
    janchar napisał:
    Witam.
    ...Roboty od groma, a i tak nie zmieni to faktu, ze cos jest porabane w tym procku.

    Tak jak napisal kolega wyzej, ustawienie wyzwolenia przerwania na poziom powowduje ze gdy caly czas podajemy '0' to bedei sie wykonywal program glowny po jednej instrukcji, i skok do przerwania, mozna to latwo sprdzic , generujac w programie glownym fale prostokatna na jednym z pinow i mierzac tam czestotliwosc. Uwazam ze blad jest w Twoim programie, a nie w procku, Procek jest produkowany juz ladnych pare lat i nikt nie wykryl takiego BUG'a, wiec watpie zebys byl pierwszy...
  • #14 1108344
    Vassili Zaicev
    Poziom 12  
    Posty: 27
    Nie no sam tez juz mocno zwatpilem w tego buga
    Po prawdzie z Waszych informacji wynika ze :

    * zle zinterpretowalem sposob zglaszania przerwania INT0
    * niewlasciwie ocenilem priorytet przerwania INT0
    * nie wiedzialem ze program moze sie wykonywac w przypadku zapalonej na stale flagi przerwania

    Objasnienia sa sensowne, tak ze juz wcale nie mysle ze to jest bug i moge sie polapac w tym wszystkim co zle zrobilem.
  • #15 1108482
    GienekS
    Poziom 32  
    Posty: 1971
    Pomógł: 139
    Ocena: 15
    Widzę że są problemy ze zrozumieniem "priorytetu przerwań". Wyższy poziom przerwania oznacza tylko tyle że to przerwanie może przerwać wekonywanie przerwanie o niższym priorytecie. Po wykonaniu zwojego zadania powraca do obsługi tego niższego przerwania.
  • #16 1108578
    Vassili Zaicev
    Poziom 12  
    Posty: 27
    Nie ma zadnych problemow ze zrozumieniem priorytetu przerwan, jesli flaga przerwania o wyzszym priorytecie jest zapalona caly czas wtedy nizsze przerwanie/przerwania sie nigdy nie wykona/wykonaja.
  • #17 1108620
    Konto nie istnieje
    Konto nie istnieje  
  • #18 1110454
    GienekS
    Poziom 32  
    Posty: 1971
    Pomógł: 139
    Ocena: 15
    Vassili Zaicev napisał:
    Nie ma zadnych problemow ze zrozumieniem priorytetu przerwan, jesli flaga przerwania o wyzszym priorytecie jest zapalona caly czas wtedy nizsze przerwanie/przerwania się nigdy nie wykona/wykonaja.

    I tu się mylisz. Jeżeli to przerwanie o wyższym priorytecie wykona RETI wtedy wruci do niższego przerwania na conajmniej jeden rozkaz. Także niemów że się przestanie wykonywać, bezie się wykonywać tylko wolniej.
  • #19 1110560
    Vassili Zaicev
    Poziom 12  
    Posty: 27
    Nie rozumiesz, flaga wyzszego przerwania jest caly czas zapalona. Nizsze przerwanie nie ma szans na wywolanie - wiec RETI nie ma szans wrocic do przerwania o nizszym priorytecie bo ono sie w ogole nie odpali. (no chyba zeby zapalic flage wyzszego przerwania w trakcie dzialania nizszego - wtedy jeden raz wroci). Czyzbym znow sie mylil czy w koncu sie polapalem ?

Podsumowanie tematu

✨ Dyskusja dotyczy problemu z przerwaniami w mikrokontrolerze AT89C2051, gdzie przerwanie zewnętrzne INT0 o wysokim priorytecie działa poprawnie, natomiast przerwanie timera T0 o niższym priorytecie nie jest wywoływane mimo ustawienia flagi TF0. Problem pojawia się, gdy oba przerwania zgłoszone są jednocześnie – INT0 jest obsługiwane, a przerwanie T0 pozostaje zablokowane. Uczestnicy wyjaśniają, że przerwania o wyższym priorytecie mogą przerywać te o niższym, a po zakończeniu obsługi przerwania wyższego wykonywany jest co najmniej jeden rozkaz z programu głównego lub przerwania niższego priorytetu, co powinno umożliwić obsługę przerwania T0. Zwrócono uwagę na prawidłową interpretację bitu IT0 w rejestrze TCON, który definiuje sposób wyzwalania przerwania INT0 (zbocze opadające lub poziom niski). Omówiono także specyfikę portów mikrokontrolera 8051, które są jednocześnie wejściami i wyjściami, co wpływa na stan logiczny odczytywany na pinach. Wskazano, że ciągłe utrzymywanie flagi przerwania INT0 może blokować przerwania o niższym priorytecie, jeśli sygnał na wejściu INT0 nie wraca do stanu wysokiego. Zaproponowano rozwiązania tymczasowe, takie jak okresowe kasowanie flagi TF0 w pętli głównej. Podkreślono konieczność dokładnego liczenia cykli wykonywania procedur przerwań w asemblerze, aby uniknąć nakładania się przerwań i utraty ich obsługi. Wskazano, że symulatory (np. Keil uVision2) poprawnie modelują zachowanie, ale w praktyce mogą występować różnice wynikające z fizycznych warunków sygnałów i konfiguracji sprzętowej. Ostatecznie autor przyznał, że problem nie jest błędem mikrokontrolera, lecz wynika z niepełnego zrozumienia mechanizmu priorytetów przerwań i specyfiki sygnałów na wejściach INT0.
Wygenerowane przez model językowy.
REKLAMA