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

Jak wykonać programowy reset w mikrokontrolerze 8051? Dostępne instrukcje/reset

djanj 03 Sie 2007 13:34 1422 15
  • #1 4142168
    djanj
    Poziom 21  
    Posty: 561
    Pomógł: 13
    Ocena: 66
    witam
    czy w '51 jest programowy reset? tzn czy jest taki rozkaz? ewentualnie jak mozna by to zrobic z poziomu programu?
  • #2 4142195
    Ch.M.
    Poziom 27  
    Posty: 1009
    Pomógł: 62
    Ocena: 15
    Nie znam się na '51 ale myślę, że nowe typy tych procków mają juz sprzętowy reset. Poczytaj sobie o wybranym procku datasheet. Zawsze możesz sprawdzać aktualne napięcie na komparatorze (wzmacnbiacz operacyjny zewnetrzny lub wewnętrzny ) i resetować układ gdy jest poniżej zadanej granicy
  • #3 4142423
    Fajfer2
    Poziom 20  
    Posty: 507
    Pomógł: 18
    Ocena: 14
    Jak ma Watchdog - a ,to najprościej go uruchomić i czekać na reset.
    Jak nie ma to z poziomu asemblera należy wykonać kilka razy
    rozkaz PUSH (tu adres następnej instrukcji - którą będzie znów PUSH)
    zaraz za dwoma rozkazami PUSH powinno być RETI - bez
    tego uP jak jest akurat w przerwaniu to po dojściu do początku programu
    nie będzie tych przerwań z których uP nie wyszedł.
    Kiedyś takie coś właśnie dla "zabawy" wymyśliłem i działało -
    pewnie można prościej - po prostu "normalnie" powychodzić z wszystkich
    przerwań - i skok do początku programu - tam musi być
    ustawienie początku stosu.
  • #4 4142564
    Bigfoot
    Poziom 25  
    Posty: 982
    Pomógł: 74
    Ocena: 13
    51' nie maja programowego resetu. Mozna wykonac wiec petle while(1); przy wlaczonym watchdogu ale wtedy niekoniecznie wszytskie rejestry beda mialy wartosc poczatkowa taka jak po Power On Reset - szczegoly w pdfie poszczegolnych uC. Prawde mowiac nie widze za bardzo sensu takiego dzialania - po co taki reset?

    BF
  • #5 4142722
    djanj
    Poziom 21  
    Posty: 561
    Pomógł: 13
    Ocena: 66
    musze zrobic przerwanie, z ktorego nie bede wracal przez reti, a przerwanie to moze byc uruchamiane wiele razy i pomyslalem ze reset bedzie dobrym rozwiazaniem zeby np stos sie nie przepelnil
  • #6 4142778
    Bigfoot
    Poziom 25  
    Posty: 982
    Pomógł: 74
    Ocena: 13
    Nie jest to ani dobry sposob ani elegancki styl programowania :(

    BF
  • #7 4142867
    Fajfer2
    Poziom 20  
    Posty: 507
    Pomógł: 18
    Ocena: 14
    Ale właśnie z przerwania musisz "wrócić" poprzez instrukcję RETI -
    jak np. zrobisz przez RET to uP nie wejdzie powtórnie do tego przerwania
    ( tj. normalną drogą przez wywołanie tego przerwania )
    Ja robiłem taką sztuczkę z PUSH xx PUSH xx RETI
    właśnie po to - ale zapewne w Twój program nie będzie wymagał
    takich "zabiegów" - po co chcesz wychodzić z przerwania w tak
    karkołomny sposób ? . Może lepiej w przerwaniu wg. potrzeby
    ustawić flagę i testować ją w programie głównym i od jej ustawienia
    uzależnić podejmowane decyzje (np. skok do początku gdzie powinno
    być zainicjowanie początkowej wartości stosu - wtedy nie interesuje
    Cię czy przeskoczyłeś z zagnieżdżonej instrukcji CALL - stosu nie przepełnisz )
  • #8 4142914
    kamyczek
    Poziom 38  
    Posty: 3994
    Pomógł: 394
    Ocena: 570
    Takie wychodzenie z przerwania to gwarantowane przewalenie stosu i program w lesie każde wywołanie przerwania odkłada coś na stos czego potem nikt nie zdejmuje efekt przepełnienie stosu i ....
  • #9 4143009
    BoskiDialer
    Poziom 34  
    Posty: 1530
    Pomógł: 353
    Ocena: 42
    można wszystkie te problemy rozwiązać w dość łatwy sposób (co nie oznacza, że go polecam - są bardziej czytelne i pewne metody rozwiązania przekazania sygnału z przerwania):
    kod główny służy za kod do inicjalizacji procesora - ustawia wszystko, załącza przerwania i wskakuje w pętlę nieskończoną. Teraz gdy pojawi się przerwanie, to nastąpi skok do funkcji przerwania (i zostanie skasowana flaga przerwania) - obsługujemy tu co trzeba, po czym ustawiamy stos (przpisanie adresu pierwszej komórki stosu [ściślej ostatniej] - chodzi o wymazanie kontekstu głównego wątku (pętli nieskończonej) - w tym momencie dalszą część funkcji przerwania można traktować jako wykonywanie się głównego kodu (brak punktu powrotu, czysty stos).. a więc ustawiamy flagę przerwania i wskakujemy w pętlę nieskończoną...

    Co do programowego resetu - tak jak mówią przedmówcy - załączenie watchdog'a i pętla nieskończona... Nie znam jednak osobiście sytuacji, w której był by potrzebny taki zabieg - z początku zawsze mam pełny kod do inicjalizacji sprzętu, więc wystarcza nawet skok pod adres 0
  • #10 4143027
    Fajfer2
    Poziom 20  
    Posty: 507
    Pomógł: 18
    Ocena: 14
    Nie zgadzam się z kamyczkiem - jak w początku programu umieścisz inicjalizację
    stosu to go nie przepełnisz - owo odkładanie na stos i zdejmowanie
    zawsze musi " iść w parze" - właśnie ze względu na licznik SP -
    jak dodasz 2 ( np. PUSH xx PUSH )
    do początkowej wartości po czym znów odejmniesz 2 (POP xx POP xx)
    to wyjdzie oczywiście początkowa wartość -
    jak dodasz 2 (PUSH xx PUSH xx) a po tym wpiszesz do SP wartość
    początkową to jest tam wartość początkowa - tyle że nie można robić
    tego w jakimkolwiek podprogramie bo zamazujemy "ślad" skoku.
    Najlepszym miejscem do tego jest procedura inicjalizacji.
    Domyślnie po resecie licznik SP ma wartość chyba 7 (nie pamiętam dokładnie) - nic nie stoi na przeszkodzie aby wpisać inną wartość
    (lub tą samą ! ) tylko trzeba wiedzieć " co się robi "
  • #11 4143038
    BoskiDialer
    Poziom 34  
    Posty: 1530
    Pomógł: 353
    Ocena: 42
    Fajfer2: To co mówisz, to prawda i tylko prawda, o tym wiem doskonale, ale chodzi mi o rozwiązanie takie, które podchodzi pod to:
    Cytat:
    musze zrobic przerwanie, z ktorego nie bede wracal przez reti

    w moim przykładzie pętlę nieskończoną w przerwaniu można zastąpić nieskończonym kodem etc...

    -- edit:
    Heh.. przecież to nie było do mnie :D
    -- edit2:
    "przypadku" -> "przykładzie"
  • #12 4143054
    Fajfer2
    Poziom 20  
    Posty: 507
    Pomógł: 18
    Ocena: 14
    No właśnie trzeba zapytać się autora dlaczego nie chce wracać poprzez
    RETI - bo pisze że obawia się przepełnienia stosu - a właśnie tak (RETI)
    go nie przepełni - no chyba że będzie coś umieszczać na stosie i
    nie zdejmować. ( w kontekście " normalnej " obsługi przerwań - bez
    programowego resetu )
    Cytat:

    musze zrobic przerwanie, z ktorego nie bede wracal przez reti

    to jak masz zamiar z niego powrócić ?
    Jak pisałem - zawsze na końcu podprogramu przerwania musi
    być RETI - inaczej nie wejdzie drugi raz do tego przerwania
    a jeśli jest na priorytecie wyższym od innego to zablokuje potrzebne
    nam przerwania.
  • #13 4143214
    VanThor
    Poziom 19  
    Posty: 224
    Pomógł: 34
    Ocena: 5
    W mikrokontrolerach C51 firmy Silicon Laboratories w jednym z rejestrów (RSTSRC) jest bit (SWRSF), którego ustawienie uruchamia proces zerowania mikrokontrolera.
  • #14 4145715
    bolek
    Poziom 35  
    Posty: 4099
    Pomógł: 86
    Ocena: 299
    tutaj jest końcówka przerwania do timera:
    NO_5S:	DJNZ DOG_U, NDG			;JESLI ZOSTANIE ODLICZONE 25 SEKUND BEZ ODEBRANIA ZNAKU KONCA LINI TO URUCHOM RESTART SYSTEMU
    	CLR ERR_OUT			;LINIA WYJCIA BLEDU NA ZERO	
    	POP PSW
    	POP ACC
    	MOV R0, SP
    	MOV @R0, #0H
    	DEC R0
    	MOV @R0, #0H
    	CLR F0				;ZEBY NIE WYSYLA SMS O RESTERCIE
    	RETI


    Zasada jest podobna jak z rozstawianiem pułapek dla watchdoga. W kilku miejscach programu wpisuje do zmiennej DOG_U pewną wartosć. Jeśli nastąpi zbyt wiele przerwań to... :)
    Skok następuje do adresu Oh- czyli tak jak po hardwarowym resecie, Oczywiscie trzeba posprzatać wszystkie potrzebne rejestry ;)
  • #15 4146907
    prokopcio
    Poziom 29  
    Posty: 2027
    Pomógł: 39
    Ocena: 143
    miałem kiedyś podobną potrzebę i jedynie w przerwaniu ustawiałem na nowo wskażnik stosu, wyłączałem globalne zezwolenie na przerwania, na wszystkie porty wystawiałem FFH a po tym wszystkim instrukcja skoku do 00H i już mamy reset ;-)

    pozdrawiam
  • #16 4147838
    Fajfer2
    Poziom 20  
    Posty: 507
    Pomógł: 18
    Ocena: 14
    A wchodził Ci znów po tym do tego przerwania ?

Podsumowanie tematu

✨ Mikrokontrolery 8051 nie posiadają dedykowanej instrukcji programowego resetu. Możliwe jest jednak wymuszenie resetu poprzez uruchomienie watchdog’a i wprowadzenie procesora w nieskończoną pętlę, co spowoduje reset sprzętowy. Alternatywnie, w przerwaniach można ustawić wskaźnik stosu (SP) na wartość początkową i wykonać skok do adresu 0x00, co symuluje restart programu, jednak wymaga to ostrożności, aby nie doprowadzić do przepełnienia stosu. W mikrokontrolerach C51 firmy Silicon Laboratories istnieje rejestr RSTSRC z bitem SWRSF umożliwiającym programowy reset. W praktyce lepszym rozwiązaniem jest obsługa przerwań poprzez ustawianie flag i kontrolę przepływu w głównym programie, zamiast wymuszania resetu z poziomu przerwania. Reset programowy w 8051 wymaga więc kombinacji ustawień stosu, kontrolowanego skoku do początku programu lub wykorzystania watchdog’a, a szczegóły zależą od konkretnego modelu i jego dokumentacji.
Wygenerowane przez model językowy.
REKLAMA