Skocz do zawartości

Oryginalność mikrokontrolerów AVR z Chin


Pomocna odpowiedź

deshipu, ehhh, problemu nie wywołuje kawałek kodu tylko pewna ilość wykonań przerwań. Widać to ewidentnie przy obsłudze z pilota, że zawsze przestaje reagować na przerwania po 36-37 zmianach koloru pilotem. W przypadku wywoływania przerwania przyciskiem zawiesza się najczęściej na jednym z podprogramów, ale nie zawsze. Więc naprawdę nie widzę celu w publikowaniu całego kodu bo nie ma błędu w programie jako takim bo powtórzę po raz kolejny, że ten sam program działa poprawnie na mikrokontrolerze z tme, problemem nie jest zasilanie, bo przekładałem mikrokontroler z arduino do płytki propoxa i dalej było to samo, dlatego nie widząc innej możliwości założyłem ten temat.

Mógłbym jeszcze sprawdzić jedną rzecz, przeprogramować moje lampki choinkowe i sprawdzić czy dalej będą działały poprawnie, bo może coś w międzyczasie wydarzyło się z Bascomem, choć prawdę mówiąc nie przypominam sobie żadnych aktualizacji od momentu programowania lampek a w nich ten kod działał bez problemu, mój synek wielokrotnie zmieniał przyciskiem wyświetlane sekwencje, a lampki świeciły przez cały dzień bez żadnych zawieszeń.

Nie twierdzę, że jest problem w twoim programie (choć oczywiście zawsze istnieje taka możliwość), tylko chciałbym mieć minimalny kawałek kodu, którym mógłbym przetestować swoje mikrokontrolery pod kątem tego problemu.

Mówisz, że problem wywołuje ilość wykonań przerwań. Dowolnych przerwań? Czy funkcja obsługi przerwania może być pusta, czy musi zajmować co najmniej ileś cykli procesora? Czy jest to niezależne od kodu, który poza tym w tym czasie działa? Czy przerwanie musi mieć podłączoną funkcję obsługi, żeby ten problem wystąpił, czy wystąpi też na przykład ze zwykłym blinkiem albo programem, który po prostu nic nie robi tylko siedzi w nieskończonej pętli?

To są wszystko bardzo ciekawe pytania, które mogłyby nas trochę nakierować na naturę tego problemu. Rozumiem, że ty nie masz cierpliwości, żeby to sprawdzić, dlatego zapytałem o kod.

Kod jest prosty, ale skoro nie znasz Bascoma ani też nie posiadasz jego pełnej wersji to nic Ci po moim programie. Mogę opisać jedynie co się dzieje w przerwaniu albo dać Tobie bina albo hexa do wgrania do mikrokontrolera żebyś sam się przekonał jak on działa.

W przerwaniu wyzwalanym niskim zboczem jest wykonywany odbiór kodu RC5 (dla wersji z pilotem), albo następuje przejście do kolejnego podprogramu na podstawie sprawdzenia indeksu zmiennej, która dla każdego podprogramu (każdej sekwencji wyświetlanych kolorów) jest inna. I tak w kółko, dopóki działa 😉. Główna pętla programu jest pusta, cały czas wykonują się podprogramy, do których się skacze z obsługi przerwania.

Jeżeli jest taka prawidłowość (te 36-37) to jesteś prawie w domu. Na mój nos to w programie jest jakiś problem ze stosem. Nie wiem czy to funkcja obsługi przerwania źle zdejmuje ramkę ze stosu czy np. nawarstwiające się przerwania (w przypadku zgłaszania ich z przycisku nie kontrolujesz liczby zboczy) są źle obsługiwane w BASCOMie, ale nie sądzę by w procesorze był jakiś magiczny mechanizm zawalający pracę CPU po 37 przerwaniach. Jeżeli wykluczyć problemy z zasilaniem i (na razie) także tanią chińskość podrobionej kości, to jedyną zmienną jest sposób zgłaszania przerwań. Mówiłeś, że raz tam był kondensator a raz nie. Czy możesz na próbę zmontować układ który bezwzględnie będzie generował dokładnie jedno zbocze/impuls na jedno wciśnięcie? Np. na przerzutniku RS i przełączniku lub od biedy np. generator impulsów 1 czy 0.5Hz na 555 albo na ATtiny.

Powinieneś też wmontować w programie prosty test sprawdzający poziom wskaźnika stosu SP np. poprzez zapalanie diodki LED na pinie gdy SP opadnie poniżej jakiegoś przyjętego poziomu. Scenariusz jest taki, że stos powoli rośnie w dół i w końcu włazi na dane trzymane w RAMie a to masakruje zarówno same dane jak i wykonywany kod bo powroty z funkcji zaczynają być wykonywane pod przypadkowe adresy.

Dobrze byłoby obejrzeć kod asemblerowy.

nse Problem jest ewidentnie z wykonywaniem programu bo zawsze mikrokontroler zawieszał się po 36-37 wywołaniach przerwania z pilota gdy zmieniałem kolory.

... ja bym sprawdził dokładniej obsługę przerwania, a dokładniej kolejność rejestrów odkładanych i zdejmowanych ze stosu. Oczywiście jest jeszcze problem drżenia styków, czyli przerwanie jest wywoływane wielokrotnie po sobie zamiast 1 raz, a to przepełnia stos i program zaczyna się krzaczyć. Spróbuj równolegle do styków dodać pojemność ok 100nF, lub przy wyjściu z przerwania wygasić flagę z rejestru statusu to powinno pomóc.

Piszę z doświadczenia nie wgłębiałem się w schemat tego kursu, więc wybacz jak opisuje mało precyzyjnie 🙂

Kolega marek1707 pięknie ten mechanizm opisał 🙂

[ Dodano: 14-06-2016, 15:20 ]

push R1

push R0

in R0,SREG

...

kod obsługi przerwania

...

sbis EIFR,INTF0 / INTF1

out SREG,R0

pop R0

pop R1

Dlatego lepiej obsługę przerwań pisać w Asemblerze 🙂

Poczytałem trochę dzisiaj i wiem już jak włączyć w Bascomie jakieś debugowanie stosu. Jutro postaram się w ciągu dnia sprawdzić jak to się zachowuje i zdam raport. Zrobię też test z jakimś wyzwalaniem przerwań za pomocą stabilnych impulsów.

Poczytałem trochę dzisiaj i wiem już jak włączyć w Bascomie jakieś debugowanie stosu. Jutro postaram się w ciągu dnia sprawdzić jak to się zachowuje i zdam raport. Zrobię też test z jakimś wyzwalaniem przerwań za pomocą stabilnych impulsów.

Debugowanie w bascomie może nic ci nie dać, zakładam że zastosowałeś standardową obsługę pilota w kodzie RC5, poczytaj jak działa konfiguracja przerwań w Bascomie w trybie "no save". Niestety w Bascomie są pluskwy które można zweryfikować debugując program na poziomie asemblera, przykładowo w AVR studio.

nse, używam opcji "no save" w obydwu programach, tej z obsługą pilota i tej z obsługą przycisków i nic to nie zmienia. Asemblera nie znam i nie będę poznawał tylko po to żeby się dowiedzieć, że to jest nie do końca sprawny mikrokontroler. Później sprawdzę to debugowanie stosu.

Już trochę zgłupiałem, spiąłem razem dwie płytki, jedna robiła za generator impulsów do przerwań, druga odbierała te impulsy i sterowała diodami. Mikrokontroler tak jak wcześniej przestawał reagować na przerwania na jednej z sekwencji wyświetlanych kombinacji. W tej sekwencji jest sporo generowanych liczb losowych. I teraz najdziwniejsze jest to, że mikrokontroler przestaje reagować na przerwania jak mam zdefiniowane 15 diod, czyli tyle ile jest na tej płytce. Jeśli zdefiniuje 100 diod, czyli płytka wysyła więcej danych i w programie tworzy się więcej zmiennych (do każdej diody jest generowane 3 zmienne typu Byte) to mikrokontroler nie zawiesza się i przerwania działają prawidłowo. Zostawiłem obie płytki na jakieś 15-20 minut i jak wróciłem to dopiero zauważyłem jakiś zwis, bo wyświetlało się zupełnie co innego. Nie wiem, w którym momencie mikrokontroler przestał reagować ale przerwań musiało wykonać się bardzo dużo w tym czasie bo miałem ustawiony impuls zmieniający efekty co 5 sekund. Już nawet nie chce mi się dzisiaj tego sprawdzać, ale możliwe, że funkcja randomizera korzysta z timera, na którym mam obsługę przerwań. Może to wina kompilatora, nie wiem.

Mikrokontroler przestaje reagować na przerwania, gdy wyświetla się sekwencja z 48 sekundy. Na tym nagraniu jest zdefiniowane 100 diod i prawie wszystko działa poprawnie.

nse, używam opcji "no save" w obydwu programach, tej z obsługą pilota i tej z obsługą przycisków i nic to nie zmienia. Asemblera nie znam i nie będę poznawał tylko po to żeby się dowiedzieć, że to jest nie do końca sprawny mikrokontroler. Później sprawdzę to debugowanie stosu.

Jak nie stosujesz assemblera to nie używaj tej opcji 🙂

Ta opcja jest dla świadomych i powoduje że kompilator nie generuje kodu odpowiedzialnego za odkładanie rejestrów na stos i trzeba to robić w programie

rozkazem "push" i zdejmować poleceniem "pop". Zastosowanie tej opcji bez ręcznej obsługi stosu jest wystarczającym powodem złego działania programu.

Pisałem byś poczytał o tej opcji, a nie ją stosował 😉

Ps.Niechęć i niecierpliwość w uważnym czytaniu sprawia wiele trudności przy uruchamianiu programów 😉

http://kaktusa.pl/bascom-nosave-parametr-w-on-interrupt-oraz-nosave-tool/

Na przyszłość wklej swoje kawałki kodu o które jesteś proszony to zaoszczędzi wielu kolegom czasu 🙂

Powodzenia 😉

Jak nie stosujesz assemblera to nie używaj tej opcji 🙂

Ta opcja jest dla świadomych i powoduje że kompilator nie generuje kodu odpowiedzialnego za odkładanie rejestrów na stos i trzeba to robić w programie

rozkazem "push" i zdejmować poleceniem "pop"

Ehh, użyłem tej opcji celowo jeszcze nim o niej napisałeś. Właśnie po to, aby mikrokontroler nie wrzucał niczego na stos skacząc z jednego podprogramu do drugiego. Bo niby po co ma coś zapisywać skoro już nie wróci do podprogramu, z którego jest wyciągany przerwaniem. Dzięki tej opcji te programy w chwili obecnej jako tako działają bo nie przepełnia się stos, a przynajmniej nie od razu.

Niestety dalej z uporem maniaka będę twierdził, że coś jest nie tak z tymi mikrokontrolerami. Ten sam kod działa bez takiego problemu na mikrokontrolerze z TME, tam nie ma opcji "no save" i nic się nie zawiesza od bardzo wielu przerwań. Tu musiałem użyć "no save", aby mikrokontroler reagował na kolejne przerwania. A i tak po iluś cyklach, ale znacznie większej ilości, przestaje reagować, ale dalej wykonuje kod z podprogramu, na którym się zatrzymał.

Bo niby po co ma coś zapisywać skoro już nie wróci do podprogramu, z którego jest wyciągany przerwaniem.

To się robi coraz ciekawsze. Mówisz, że twój program nigdy nie wychodzi z kodu przerwania?

Może wklej ten kod, bo teraz to mnie wystraszyłeś i wyobrażam sobie straszne rzeczy tam.

To się robi coraz ciekawsze. Mówisz, że twój program nigdy nie wychodzi z kodu przerwania?

Nie, nie czytasz ze zrozumieniem. Wychodzi z kodu przerwania do innego podprogramu na podstawie obsługi warunku. Pisałem o tym kilka postów wyżej, niestety nie mogę sam siebie cytować 😋.

Proszę bardzo

Przerwanie:
  Disable Interrupts
  Disable Int0

  If Indeks = 0 Then
     Waitms 500
     For Y = 1 To Ile_ledow

        Red(y) = 0
        Green(y) = 0
        Blue(y) = 0

     Next Y
     Gosub Bit_send
     Efekt1
  End If


  If Indeks = 1 Then
     Waitms 500
     For Y = 1 To Ile_ledow

        Red(y) = 0
        Green(y) = 0
        Blue(y) = 0

     Next Y
     Gosub Bit_send
     Efekt2
  End If

  If Indeks = 2 Then
     Waitms 500
     For Y = 1 To Ile_ledow

        Red(y) = 0
        Green(y) = 0
        Blue(y) = 0

     Next Y
     Gosub Bit_send
     Efekt3
  End If

  If Indeks = 3 Then
     Waitms 500
     For Y = 1 To Ile_ledow

        Red(y) = 0
        Green(y) = 0
        Blue(y) = 0

     Next Y
     Gosub Bit_send
     Efekt4
  End If

  If Indeks = 4 Then
     Waitms 500
     For Y = 1 To Ile_ledow

        Red(y) = 0
        Green(y) = 0
        Blue(y) = 0

     Next Y
     Gosub Bit_send
     Efekt5
  End If


  If Indeks = 5 Then
     Waitms 500
     For Y = 1 To Ile_ledow

        Red(y) = 0
        Green(y) = 0
        Blue(y) = 0

     Next Y
     Gosub Bit_send
     Efekt6
  End If

  If Indeks = 6 Then
     Waitms 500
     For Y = 1 To Ile_ledow

        Red(y) = 0
        Green(y) = 0
        Blue(y) = 0

     Next Y
     Gosub Bit_send
     Efekt7
  End If

  If Indeks = 7 Then
     Waitms 500
     For Y = 1 To Ile_ledow

        Red(y) = 0
        Green(y) = 0
        Blue(y) = 0

     Next Y
     Gosub Bit_send
     Efekt8
  End If

  If Indeks = 8 Then
     Waitms 500
     For Y = 1 To Ile_ledow

        Red(y) = 0
        Green(y) = 0
        Blue(y) = 0

     Next Y
     Gosub Bit_send
     Efekt9
  End If

  If Indeks = 9 Then
     Waitms 500
     For Y = 1 To Ile_ledow

        Red(y) = 0
        Green(y) = 0
        Blue(y) = 0

     Next Y
     Gosub Bit_send
     Efekt10
  End If

  If Indeks = 10 Then
     Waitms 500
     For Y = 1 To Ile_ledow

        Red(y) = 0
        Green(y) = 0
        Blue(y) = 0

     Next Y
     Gosub Bit_send
     Efekt11
  End If

  If Indeks = 11 Then
     Waitms 500
     For Y = 1 To Ile_ledow

        Red(y) = 0
        Green(y) = 0
        Blue(y) = 0

     Next Y
     Gosub Bit_send
     Efekt12
  End If

Return

Bit_send to podprogram do wysyłania danych do ledów, napisany w asemblerze (nie przeze mnie). Efekt1 do 12 to podprogramy obsługi różych efektów 😋, do których właśnie wychodzi z przerwania i już nie wraca bo każdy z efektów jest pętlą.

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...