Skocz do zawartości

Oryginalność mikrokontrolerów AVR z Chin


Pomocna odpowiedź

marek1707, tylko, że dla mnie to nie jest babol. Dlaczego nie dopuszczacie do siebie myśli, że coś z tym mikrokontrolerem jest nie tak? I ten błąd powstaje właśnie przez mój, nie do końca zgodny ze sztuką kod. Ten sam program z przerwaniem wywoływanym przez przycisk działa w mikrokontrolerze z TME sterującym 99 diodami i przez kilka tygodni wiszenia lampek na choince i moim synku, który siedział i wciskał przycisk po kilkanaście razy na raz, nigdy nie doszło do sytuacji, w której mikrokontroler przestał reagować na przerwania. Oczywiście pomijam już w tym momencie kwestię sprzętowej kasacji drgań. Przycisk ma kondensator 10nF równolegle i przez 10kΩ jest podciągany do plusa a do pinu mikrokontrolera jest podłączony przez rezystor 100Ω.

Wychodź z podprogramu jak się zmieni indeks, a w pętli głównej wchodź do następnego.

[ Dodano: 16-06-2016, 12:12 ]

Btw, pamiętaj o "volatile" (czy co tam Bascom ma) na tej zmiennej!

Bascom jest wydajny i dla początkujących przygodę z mikrokontrolerami, w starszych wersjach bascoma wiele błędów korygował kompilator im nowsze wersje tym bardziej wymagające świadomości programisty 🙂

@Sabre

Obsługa przerwania ma w tle programu odebrać daną z pilota, a program w pętli głównej ma zadecydować co z tą daną zrobić i jakie zmiany ona wprowadziła, po obsłużeniu tego zezwalasz

na odebranie kolejnej danej z pilota, wtedy pętla główna programu będzie jedynie przerywana na czas odebrania danej co statystycznie trwa ok 10 - 100ms zależy od pilota, takiego sporadycznego zakłócenia w pracy programu nie zauważysz.

Nad takimi problemami siedziałem kilka lat temu i nie miałem z kim o tych problemach pogadać 🙂

Napiszę to samo co wyżej, bo widzę, że nie czytasz tego co piszę a tylko się wymądrzasz.

Po obsłużeniu przerwania program wróci w miejsce z którego wyskoczył. Przy sekwencjach zmian koloru, które mam zdefiniowane typu płynąca tęcza kolorów na 100 diodach (no 99 bo jedną spaliłem przez odwrotne przylutowanie kabli zasilających) niemożliwe jest, aby wyskoczyć z tego kodu w tak krótkim czasie jak zapewnia mi aktualna konstrukcja kodu, nawet jeśli jest ona nie do końca zgodna ze sztuką. Taka sekwencja wykonuje się co najmniej kilka sekund, i nawet dopisanie w kilku miejscach kodu warunków na wyskoczenie z niego nie przyspieszy działania do poziomu obecnego. A tylko zanieczyszczę kod masą warunków.

Sabre, gdybyś znalazł wolną chwilę spróbuj proszę resetowania stosu. Takie rozwiązanie powinno działać bez modyfikacji całej reszty programu.

Oczywiście w pełni zgodzę się, że najczęściej z przerwania wraca się do miejsca jego wystąpienia, ale nie zawsze tak się robi. A skoro napisałeś taki nietypowy program, to dlaczego go nie poprawić?

Napiszę to samo co wyżej, bo widzę, że nie czytasz tego co piszę a tylko się wymądrzasz.

Widzę że mama szacunku nie nauczyła, dalej radź sobie sam.

Dziękuję nic tu po mnie 🙂

Napiszę to samo co wyżej, bo widzę, że nie czytasz tego co piszę a tylko się wymądrzasz.

Widzę że mama szacunku nie nauczyła, dalej radź sobie sam.

Dziękuję nic tu po mnie 🙂

No wybacz kolego, ale jako jedyny nie napisałeś ani nie zaproponowałeś niczego sensownego a tylko głupie komentarze pod moim adresem.

Nie byłoby tego tematu gdyby podkreślę ponownie ten sam kod, działał tak samo na 3 mikrokontrolerach, z czego 2 pochodzą z Chin a jeden ze sklepu od nas.

EDIT:

Sabre, gdybyś znalazł wolną chwilę spróbuj proszę resetowania stosu.

Sprawdzę to wieczorem w pierwszej kolejności, jak dosiądę się do płytki i całego kodu.

To już się robi tak zagmatwane że tylko .lss całości może rozwiązać wszelkie wątpliwości. 🙂

Z wrzuconego kodu Bit_send, bez wglądu w całość, ciężko również wywnioskować co właściwie ma robić lub jaki ma efekt wrzucanie rejestrów na stos bez żadnego kodu do ich zdejowania:

$asm

Bit_send:                                                   
  ldi r17, Ile_ledow                                   
  clr R18                                               
  clr r19
  ;****************************************
  LDI XL , LOW(LABEL3)                                 
  LDI XH , HIGH(LABEL3)
  PUSH  XL <-------------------
  Push  XH <------------------
  LDI XL , LOW(LABEL2)
  LDI XH , HIGH(LABEL2)
  PUSH  XL <-------------------
  Push  XH <------------------
  LDI XL , LOW(LABEL1)
  LDI XH , HIGH(LABEL1)
  PUSH  XL <-----------------
  Push  XH <-----------------
  IN R23, SPL  <--- SP jest ładowany już po wrzuceniu danych na stos                                            
  in R24, sph                                           
Led_loop_:
...

A wracając do tematu dyskusji; to jeśli przerwanie wywołuje podprogram który czeka w pętli nieskończonej na kolejne przerwanie, to nie tylko musisz zdejmować ze stosu adresy powrotu zarówno w przerwaniu jak i w podprogramie czy tablice alokowane na stosie(SP), ale również zrzucone rejestry na wejściu do przerwania.

Coś takiego to tylko w assemblerze się widuje gdzie ma się pełną kontrolę nad stosem a nie w BASCOM'ie.

Oczywiście pomijam możliwość zastosowania "chińskich jednostek", przez alternatywnego producenta, gdzie 2kB to w rzeczywistości 1 kB i objawia się to właśnie nachodzeniem stosu na zmienne. 😉

Trochę się czuję pokrzywdzony traktowaniem mojej propozycji rozwiązania problemu jako rozpaczliwej.

Po pierwsze to jedyna jak na razie metoda na sprawdzenie, że faktycznie problem leży w obsłudze stosu. Jeśli napiszemy cały program od nowa, może mieć inne błędy, albo program może działać chociaż problem nadal istnieje. Zmieniając tylko jeden element na raz mamy kontrolę nad testowanym problemem.

Druga sprawa to sam pomysł - w pierwszej chwili też pomyślałem że to paskudna metoda na obsługę przerwań. Z drugiej strony sam ostatnio siedzę w obsłudze przerwań, gdzie powrót wcale nie następuje to miejsca wywołania przerwania 🙂 Nieco przypadkiem Sabre napisał własną namiastkę systemu operacyjnego - dlaczego tego nie docenić? Co prawda jest to uproszczona wersja, ale po poprawieniu obsługi stosu może całkiem fajnie działać.

Hej, to nie miało być uwłaczające. Rozpaczliwa, bo nie naprawia błędu w założeniach a tylko łata dziurę dla tego jednego, konkretnego przypadku. Jest prosta i pewnie skuteczna - jeśli w ogóle rozumiemy o co tu chodzi..

Nie traktuję napisania zupełnie nowego kodu jako metody naprawy istniejącego, tylko jako próbę wymuszenia innego spojrzenia na problem w przyszłości. No i odróżniłbym przypadkowe działanie od celowego pisania mini-systemu operacyjnego. Następnym razem, gdy urządzenie będzie miało robić jeszcze kilka innych rzeczy Sabre - stosując dotychczasowe podejście - będzie bez szans. Posiadając umiejętność tworzenia kodu "udającego" prawdziwą pracę współbieżną wielu procesów na raz, problemem zaczyna być jedynie dostępna moc obliczeniowa i zasoby pamięciowe. Wystarczy zachować trochę programistycznej higieny i skomplikowane programy nagle stają się proste. Być może inną (lepszą? trudniejszą?) ) drogą rozwoju będzie rozpoczęcie używania jakiegoś RTOSa, ale coś z tym trzeba zrobić. Już tu widać, że nawet w tak prostym kodzie trzeba było łapać się prawą ręką za lewe ucho a i tak powstał.. hm, potworek. Szkoda na to czasu.

@marek1707:

"Tego nie może przerwać nawet obsługa odbiornika IR i to powinna być sekcja krytyczna."

Na moment obsługi LED'ów wystarczy zablokować przerwania, pozostanie do rozwiązania weryfikacja poprawności odebranej ramki danych, na tyle ile jeszcze pamiętam to funkcje odbiorcze w bascomie maja flagę "err" do obsługi takich błędów.

Rozkazy z pilota są cyklicznie wysyłane, tak że nawet jak jakaś ramka będzie czytana od "połowy" to następną już się odczyta prawidłowo w całości. W tym produkcie nie ma znaczenia czy będą wyłapywane wszystkie ramki wysyłane z pilota 🙂

Ten kod można w całości napisać w Bascomie tylko wystarczy trochę pomyśleć 😉

Debuger bascoma odlicza czas pomiędzy ustawionymi breakpointami, wszystko spokojnie można dopracować. Nie trzeba kolegom udowadniać jaki to się genialny kod napisało, błędy popełniamy wszyscy.

Dlaczego od razu potworek. Jest to nieco inny kod niż można byłoby się spodziewać, ale jeśli się mu bliżej przyjrzeć ma swój urok.

Moim zdaniem procedurę każdego efektu można traktować jako kolejne zadanie, a procedura przerwania pełni rolę schedulera w tym systemie. Każdy "proces" zaczyna od początku, więc nie ma potrzeby zachowywania kontekstu. Jedyny problem to zarządzanie stosem, stąd moja propozycja żeby podczas przełączania zadań, resetować wskaźnik stosu.

W sumie gdyby dodać zachowywanie rejestrów każdego zadania i dać im oddzielne stosy mielibyśmy ciekawy kernel systemu. Tak też jest to namiastka systemu, chociaż mocno uproszczona.

@Elvis: Twoje rozwiązanie jest genialne, tylko kolega "Sabre" nie ma pojęcia o assemblerze i źle reaguje na wskazywane błędy w napisanym przez siebie kodzie. Więc nie wiadomo czy analizujemy problem związany z procesorem, jego programem czy jego EGO. Przepraszam Koledzy ale ja zgłupiałem.

EDIT:

... hmm, tak głębiej myśląc ustawienie wskaźnika stosu na początek zniszczy i adresy powrotu z przerwania ?? , wtedy program zacznie pracować od resetu procesora ...

Tak sobie gdybam, mam nadzieje że kolega nie jest tak wrażliwy jak Sabere ??

Chyba że resetujemy wskaźnik pozostawiający ostatnio odłożony adres powrotu ??

[ Dodano: 16-06-2016, 14:08 ]

... tak tylko ustawienie wskaźnika stosu na początkowy adres powrotu, nie naprawi już uszkodzonej zawartości ramu ...

nse, ustawienie wskaźnika stosu sprawi że będzie on pusty, albo chociaż po każdym przerwaniu/przełączeniu zadań będzie w tym samym stanie.

Adres powrotu z przerwania nie ma znaczenia, ponieważ program z przerwania nie wraca - nie używa instrukcji RETI, więc resetu też nie będzie.

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...