Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

[ATmega2560][avrasm] Brak reakcji uK na zmiany wejść

TK_Kolejarz 01 Gru 2018 13:02 729 42
  • #1 01 Gru 2018 13:02
    TK_Kolejarz
    Poziom 4  

    Witam,
    Borykam się od pewnego czasu z problemem bliżej nieokreślonym. Oczekiwane działanie opisałem poniżej:
    Mikrokontroler (ATmega2560, umieszczona na płytce "chiński klon arduino") ma podłączony zestaw przycisków do wejść, oraz 8 diod led dla sygnalizowania statusu z drugiego mikrokontrolera. Ta płytka ma stanowić pilota, więc zmiany stanów na wejściach mają powodować wysłanie określonego polecenia po magistrali szeregowej, które potem będzie dekodowane przez inny uK - każdy odebrany rozkaz (za wyjątkiem "specjalnych") ma spowodować zmianę stanu logicznego na danym wyjściu na przeciwny, lub ewentualnie przesłanie tego samego polecenia dalej (to co "dalej" zostało sprawdzone i funkcjonuje prawidłowo). Problem objawia się w ten sposób, że niezależnie od tego, co zrobię na wejściach, na magistrali nie dzieje się kompletnie nic. Zakładam zatem że błąd tkwi gdzieś w programie (poniżej). Jest go sporo (jak dla mnie), ale mam nadzieję że komuś uda się wskazać co zrobiłem źle.
    Że można wiele rzeczy zrobić inaczej lub efektywniej, jestem świadomy, ale na razie priorytetem jest sprawienie by to ruszyło :)

    (Dla lepszej czytelności programów, wyciąłem z nich wszystkie zbędne, sobie tylko potrzebne komentarze i kawałki kodu pozostałe po licznych poprawkach)

    Program "Pilota":

    Kod: avrasm
    Zaloguj się, aby zobaczyć kod


    Program "Odbiornika":
    Kod: avrasm
    Zaloguj się, aby zobaczyć kod

    0 29
  • #2 01 Gru 2018 14:18
    excray
    Poziom 39  

    Na początku powinieneś zainicjować stos.

    0
  • #3 01 Gru 2018 15:26
    tmf
    Moderator Mikrokontrolery Projektowanie

    excray napisał:
    Na początku powinieneś zainicjować stos.

    Niekoniecznie, w tym procku, o ile dobrze pamiętam, stos jest inicjowany sprzętowo na koniec SRAM.
    Przede wszystkim próbowałbym wyizolować problem, pokazując ograniczony kod, na którym problem występuje. Warto też skorzystać z programowego symulatora dostępnego w Atmel Studio - można prześledzić instrukcja po instrukcji co się dzieje i w którym miejscu program idzie w maliny.

    0
  • #4 01 Gru 2018 15:33
    TK_Kolejarz
    Poziom 4  

    Tak z dotychczasowych swoich doświadczeń, to na ogół stos nie powodował żadnych problemów, o ile tylko inicjalizację wstawiłem przed pierwszą instrukcją która go używa. Sprawdziłem co @excray proponował, ale nici z tego. Zaraz siądę do symulacji, to dam znać co wyszło.

    0
  • #5 01 Gru 2018 15:48
    excray
    Poziom 39  

    tmf napisał:
    Niekoniecznie, w tym procku, o ile dobrze pamiętam, stos jest inicjowany sprzętowo na koniec SRAM.

    Owszem. W teorii tak jest. Ale z doświadczenia wiem, że chyba to nie do końca działa poprawnie. Program w którym pominięto ręczną inicjalizację stosu potrafi się zachowywać irracjonalnie. Nie wgłębiałem się w ten temat bo 4 linijki programu to niewielki koszt.

    0
  • #6 01 Gru 2018 16:41
    TK_Kolejarz
    Poziom 4  

    Więc tak. Pierwsza ciekawostka która wyszła, to jakiś kłopot z układem watchdog, więc go wyłączyłem aby sprawdzić czy to jedyny błąd. Wszystko działa elegancko do momentu gdy program zaczyna generować instrukcje dla odbiornika - w tym miejscu nagle uaktywnia się przerwanie 'STOP' (co pokrywa się z zachowaniem całości w praktyce), a uK utyka w martwej pętli związanej z rejestrem UCSR0A:

    Kod: avrasm
    Zaloguj się, aby zobaczyć kod


    Nie wiem tylko czy jest to związane w jakiś sposób z ograniczeniami edytora (lub moim brakiem umiejętności w obsłudze), czy jest to po prostu źle skonstruowany fragment? Nie rozumiem też kompletnie skąd się bierze żądanie przerwania na pinie INT0, skoro i wewnętrznie i zewnętrznie jest on podciągnięty do zasilania, a przerwanie jest wywoływane niskim poziomem logicznym.

    0
  • #7 01 Gru 2018 18:37
    trol.six
    Poziom 31  

    TK_Kolejarz napisał:
    co pokrywa się z zachowaniem całości w praktyce)

    Jeśli się pokrywa to w czym problem? Program czeka na coś w buforze i jeśli nie ma, to będzie czekać aż flaga się ustawi... OK, źle zerknąłem ... to jest flaga zapełnienia bufora.

    Ja bym zaczął od komunikacji, jeden wysyła co np sekundę jakąś liczbę a drugi odbiera i odsyła.

    Przy wielu funkcjach nieprzetestowanych przeważnie jest trudniej.
    .

    0
  • #8 01 Gru 2018 18:47
    TK_Kolejarz
    Poziom 4  

    trol.six napisał:
    Jeśli się pokrywa to w czym problem?

    Za duży skrót myślowy, miałem na myśli bardziej to że to co obserwuję na zmontowanym układzie przedstawia sobą taki sam stan jak to co na symulatorze.
    A problem z tą flagą na którą on czeka jest taki, że ona ma się ustawić sama po zakończeniu transmisji, ponieważ wskazuje że bufor nadajnika jest pusty. I dlatego właśnie nie wiem gdzie szukać - sprawdziłem wszystkie rejestry odpowiedzialne za działanie nadajnika i odbiornika, wszystko się zgadza.
    trol.six napisał:
    Ja bym zaczął od komunikacji, jeden wysyła co np sekundę jakąś liczbę a drugi odbiera i odsyła.

    Na jutro sklecę programik i dam znać co z tego wyszło.

    0
  • #9 01 Gru 2018 19:07
    trol.six
    Poziom 31  

    TK_Kolejarz napisał:
    A problem z tą flagą na którą on czeka jest taki, że ona ma się ustawić sama po zakończeniu transmisji,

    Zgadza się, jak w międzyczasie dopisałem, nie ta flaga.

    W każdym razie tak rzut okiem i nadawanie UART jest włączone. Więc nie powinno się zapętlić. Nie wiem czy ATmega2560 potrzebuje jeszcze innych ustawień. A czym to programujesz? Na tych pinach jest interfejs, aczkolwiek teoretycznie nie powinno być z tym problemu.

    excray napisał:
    Na początku powinieneś zainicjować stos.

    Przecież ma ... ;) Nie na poczatku, ale przed włączeniem przerwań i użyciem skoków. Istnieje też możliwość że problem jest na etapie asemblacji.
    Nie wiadomo z opisu jak autor postu to realizuje i jakie pliki są dołączane.
    .

    0
  • #10 01 Gru 2018 19:58
    TK_Kolejarz
    Poziom 4  

    Od strony technicznej zatem, coby nie było wątpliwości:
    Kod piszę w AVR Studio 5.1 (nie używam 7, bo na laptopie gdzie mam XP-ka czasem mam problemy przy otwieraniu w wersji 5.1 plików z 7, a kompatybilność musi być zachowana) i tego samego programu używam do kompilacji całości. Programowanie odbywa się za pomocą AVR studio 7 (Dragon nie lubi się z 5.1, nie wiem czemu), AVR Dragon i "dongla" AVT1663 na "głównym stanowisku", sporadycznie (gdy pracuję na wspomnianym lapku) przez "ExtremeBurnerAVR" i USBasp. Czasem dragon strajkuje ale to chyba już taka jego specyfika, bo o błędach w tym temacie w googlu jest sporo... Bez względu na zastosowaną metodę (stanowisko) zawsze programuję przez ISP z pliku hex.

    0
  • #11 01 Gru 2018 20:24
    LChucki
    Poziom 24  

    Skoro masz Dragona, używasz Mega2560, zapomnij o ISP przez SPI, użyj JTAG. JATAG daje możliwość wygodnego debugowania, z palca możesz modyfikować zawartość zmiennych i peryferiów. Symulator to nie to samo. Nie wszystko działa w nim na 100% zgodnie z oryginałem. Na symulatorze nie zadziała odbieranie znaków z UART.
    Masz klona Arduino, wiec JTAG jest wyłączony. Z tego co pamiętam, wyłączony niestety przez fuses a nie w programie. Musisz więc najpierw przez SPI włączyć JTAG no i oczywiście, Arduino nie uznaje debugowania, więc te kilka kabelków do JTAG musisz dolutować.

    Dodano po 8 [minuty]:

    trol.six napisał:
    W każdym razie tak rzut okiem i nadawanie UART jest włączone. Więc nie powinno się zapętlić. Nie wiem czy ATmega2560 potrzebuje jeszcze innych ustawień.

    W C używałem tych samych funkcji do Mega2560 jak i do Mega164.

    0
  • #12 01 Gru 2018 20:50
    trol.six
    Poziom 31  

    Napisanie programu nadawczego razem z mruganiem leda, bo na razie to nic nie wiadomo (może nie ma zasilania), to jest przekopiowanie kilkanaście linijek z twojego kodu. Możesz od razu sprawdzić wysyłke przez inne porty. Jak nie zadziała (sprawdź na wyjściu portu choćby ledem), to wrzuć kod najlepiej z listingiem. Błąd wcale nie musi być w kodzie.

    W dokumentacji masz przykładową komunikacje możesz sprawdzić czy tamtejszy kod zadziała.

    LChucki napisał:
    W C używałem tych samych funkcji do Mega2560 ...

    Skoro tak, pewnie kolega wie lepiej ode mnie czy te 4 rejestry wystarczą ;) W dokumentacji w sumie też więcej nie piszą.
    Ale czasem można coś przeoczyć.
    .

    0
  • #13 01 Gru 2018 21:01
    LChucki
    Poziom 24  

    trol.six napisał:
    LChucki napisał:
    W C używałem tych samych funkcji do Mega2560 ...

    Skoro tak, pewnie kolega wie lepiej ode mnie czy te 4 rejestry wystarczą ;) W dokumentacji w sumie też więcej nie piszą.
    Ale czasem można coś przeoczyć.
    .

    Praktycznie wszystkie AVRmega mają takie same rejestry i tą sama obsługę wszystkich USART. Wyjątek stanowi nieprodukowany Mega161, produkowany nadal Mega162 (może też nieprodukowany ale można łatwo kupić). Nie pamiętam jak jest z Mega103 (nieprodukowany) ale Mega128 można ustawić w tryb zgodności z 103. Więcej AVRmega z "niestandardowymi" rejestrami, nie znam. Co do bałaganu w nazwach rejestrach, to już inna sprawa (nie wiem czy dotyczy tylko C czy także ASM). W niektórych AVR z dwoma USART, jest jak powinno być i mamy np UCSR0A, UCSR1A natomiast w innych UCSRA, UCSR1A itd.

    Pominąłem zagadnienie pracy w trybie SPI.

    0
  • #14 02 Gru 2018 12:03
    TK_Kolejarz
    Poziom 4  

    To tak, z wyników eksperymentów:
    Skleciłem prosty programik (kopiując fragmenty gotowego programu) który ma nadawać przez UART określony bajt. Przetestowałem tym wszystkie 4 nadajniki i wszędzie cisza. Linia Tx cały czas pozostaje w stanie wysokim i nie dzieje się kompletnie nic.
    Dalej: przyszło mi tak jeszcze do głowy że może problem tkwi w tym że chcę wysłać osiem zer i przez to nadajnik głupieje. Próbowałem zarówno z inną wartością, jak i z 9-bitową ramką, z ósmym bitem "1", nadal bez skutku.
    JTAG: o ile dobrze rozszyfrowałem to co jest wyświetlane, to sprawa ma się tak: flaga "rejestr nadawczy pusty" jest ustawiona, a mimo to, cały czas przechodzi w kółko pętla w przerwaniu 'STOP'. Po zlikwidowaniu obsługi przerwań zewnętrznych, coś się zaczyna dziać, bo ostatecznie lądujemy w pętli przy 'nadawanie':

    Kod: avrasm
    Zaloguj się, aby zobaczyć kod


    gdzie utyka na tak samo skonstruowanej pętli. Stawiam więc na to że ona jest przyczyną błędów, ale nie mam zielonego pojęcia w jaki sposób? Flaga jest ustawiona, powinien więc po pobraniu rejestru wykryć że tak jest i pominąć instrukcję skoku, czego nie robi najwyraźniej.

    Jeżeli pozbyć się tej pętli z programu z pierwszego akapitu, to dołączona do pinu Tx dioda zaczyna delikatnie zmieniać natężenie z jakim świeci (lub mi się tylko tak wydaje, bo po dołączeniu jakiegokolwiek odbiornika, nie otrzymuje on żadnych danych).

    0
  • #15 02 Gru 2018 12:34
    tmf
    Moderator Mikrokontrolery Projektowanie

    Jak rozumiem program pętli się w nieskońcozność na loopNad? Czy UART jest skonfigurowany, w szczególności, czy jest włączony nadajnik? W symulatorze (lub przez JTAG) po wczytaniu UCSR0A do r16, bit nr 5 jest rzeczywiście ustawiony? Bo nie widzę możliwości, aby przy ustawionym bicie nie była pomijana instrukcja rjmp, w efekcie czego nie była przerywana pętla. Zapewne masz jakiś głupi błąd w programie. Definicja UCSR0A jest poprawna i wskazuje na poprawny adres tego rejestru? Brak efektów na Tx sprawdzasz tylko diodą, czy masz do dyspozycji oscyloskop lub analizator poziomów logicznych? Normalnie na tym wyjściu powinno być 1 - nawet nadawanie samych zer nie stanowi problemu - w transmisji UART są bity stopu (przynajniej 1).

    0
  • #16 02 Gru 2018 12:51
    TK_Kolejarz
    Poziom 4  

    Jakikolwiek sprzęt lepszy niż multimetr to mogę sobie pomarzyć tylko w kwestii badania efektów działania tego programu :(
    Idąc dosłownie po jednej instrukcji, czy raczej po jednym cyklu zegara, całość zachowuje się tak (zaczynając od 'loopNad'):
    UCSR0A = 0x62, R16 = xxx
    lds -> R16 = 0x62
    sbrs(1) -> R16 = 0x62
    sbrs(2) -> R16 = 0x02 - sbrs najwyraźniej wykonuje się w dwóch taktach;
    I potem wchodzi na rjmp

    Edit: UART sprawdzałem już wielokrotnie konfigurację, sprawdziłem i teraz, nie widzę tam nic co wygląda nie tak jak powinno. Sprawdziłem też czy adres z którego pobiera UCSR0A jest prawidłowy i wszystko się zgadza wszędzie.

    Edit2: Wykombinowałem :D Pętla zaczęła funkcjonować prawidłowo, gdy przerobiłem ją na coś takiego:

    Kod: avrasm
    Zaloguj się, aby zobaczyć kod


    Wygląda to tak jakby instrukcje sbrc i sbrs nie działały na tym układzie, bo wszędzie gdzie występują dzieją się podobne rzeczy z tego co widzę jak teraz to przeglądam w debugerze.

    0
  • #17 02 Gru 2018 15:49
    excray
    Poziom 39  

    Pokaż cały kod. Nic nie wycinaj.

    0
  • #18 02 Gru 2018 15:53
    TK_Kolejarz
    Poziom 4  

    Kod jest taki jak ten w pierwszym poście, z tą tylko różnicą że wykomentowane są w inicjalizacji sekcje z przerwaniami zewnętrznymi i wdt, bo to nie chciało działać. No i ta poprawka w pętli. A tak to bez żadnych zmian.

    0
  • #19 02 Gru 2018 15:57
    excray
    Poziom 39  

    To w takim razie zapomniałeś dodać bibliotekę z definicjami rejestrów mikrokontolera.

    0
  • #21 02 Gru 2018 16:50
    trol.six
    Poziom 31  

    TK_Kolejarz napisał:
    Przetestowałem tym wszystkie 4 nadajniki i wszędzie cisza. Linia Tx cały czas pozostaje w stanie wysokim i nie dzieje się kompletnie nic.

    Trochę to dziwne zważywszy na:
    TK_Kolejarz napisał:
    Jeżeli pozbyć się tej pętli z programu z pierwszego akapitu, to dołączona do pinu Tx dioda zaczyna delikatnie zmieniać natężenie z jakim świeci

    To co w takim razie mryga tą diodą?

    To wrzuce ci hexa, na atmega2560, wysyła HELLO na prędkości ok 19200. TX0 TX1 -> PORTE.1, PORTD.3
    Teoretycznie powinien działać bo częściowo przekopiowany. Ale nie mam takiej megi więc...

    Możliwe inne błędy:
    sprzętowe: walnięty procesor, programator, kwarc, ścieżki itp.
    programowe: złe ustawienie FUSE

    0
  • #22 02 Gru 2018 17:09
    TK_Kolejarz
    Poziom 4  

    Z tym miganiem mogło mi się wydawać, nie upieram się.
    Wgrałem tego hexa, rezultaty żadne. Spróbowałem z całkiem nową płytką, to samo. Jedyny efekt to lekko świeci dioda "RX" na płytce, gaśnie gdy linię reset zewrzeć do masy. Rozumiem że nowa płytka też może mieć jakieś mechaniczne uszkodzenie, ale prawdopodobieństwo tego jest chyba znikome?

    0
  • #23 02 Gru 2018 17:29
    trol.six
    Poziom 31  

    Na 90 procent błąd jest gdzie indziej. Sprawdziłbym FUSE. Odłączyłbym programator, sprawdził pin reset. Może inny kwarc zamontuj, albo podaj sygnał z generatora.

    Nie mam schematu nie wiem czy jakaś dioda może migać czy też nie.

    acha... pisałeś coś o watch-dogu, tu masz z wyłączonym
    .

    0
  • #24 02 Gru 2018 17:49
    TK_Kolejarz
    Poziom 4  

    Gaśnie ta dioda pewnie przez to że przy resecie zeruje wszystkie porty, a po inicjalizacji uruchamia ją znowu.
    Fuse bity są ustawione tak: Brown-out na 2.7V, "On-Chip Debug" wyłączone, JTAG wyłączone, SPI włączone, WDT wyłączone, Niekasowanie eeprom wyłączone, 512 słów obszaru bootloadera, bootreset włączone, dzielenie zegara przez 8 wyłączone, wyjście zegarowe wyłączone, zegar nastawiony na zewnętrzny oscylator 8MHz wzwyż; Jako arduino działało, więc zakładam że z zegarem wszystko w porządku?

    0
  • #25 02 Gru 2018 18:06
    LChucki
    Poziom 24  

    TK_Kolejarz napisał:
    bootreset włączone,

    Jak skasowałeś bootloader a wektor resetu jest na bootloader to.......... sam się domyśl.
    Jeśli to jest błędem, już dawno byś problem rozwiązał, gdybyś użył JTAG a tak błądzisz.

    0
  • #26 02 Gru 2018 18:14
    TK_Kolejarz
    Poziom 4  

    Fakt, mój błąd, nie zauważyłem tego wcześniej.
    Niemniej nie wpłynęło to pozytywnie na działanie całości - generalnie wciąż bez zmian, czyli brak jakiejkolwiek reakcji na cokolwiek.

    0
  • #27 02 Gru 2018 18:15
    trol.six
    Poziom 31  

    BOOTRST ma być niezaprogramowany. W arduino program skacze do bootloadera.
    Ewentualnie w programie którym się pisze należy zmienić adres skoków.

    LChucki napisał:
    Jeśli to jest błędem, już dawno byś problem rozwiązał, gdybyś użył JTAG a tak błądzisz.

    O tym że błąd może być gdzie indziej pisałem już wcześniej. Do tego nie potrzeba jtaga tylko chęć sprawdzenia.

    Generalnie jest tak że jeśli programuje się przez SPI, to teoretycznie zegar powinien działać. Ale kiedy proste programy nie działają, to jest już zastanawiające.
    .

    0
  • #28 02 Gru 2018 18:24
    LChucki
    Poziom 24  

    trol.six napisał:
    O tym że błąd może być gdzie indziej pisałem już wcześniej. Do tego nie potrzeba jtaga tylko chęć sprawdzenia.

    Można trzy dni sprawdzać, można w godzinę odpowiednimi narzędziami, w tym przypadku JTAG.

    trol.six napisał:
    Ewentulanie w programie którym się pisze należy zmienić adres skoków.

    Co kolega ma na myśli? Jakie adresy skoków zmienić?
    Gdy BOOTRST jest zaprogramowany po resecie następuje skok pod adres bootloadera a tam same FF.
    Aby rozwiązać problem, należałoby stworzyć sekcję (kompilować od adresu), która będzie znajdowała sie pod adresem bootloadera a tam skok pod adres 0. Innej możliwości nie widzę.
    Jeśli zaś chodzi o przesunięcie tablicy wektorów na obszar bootloadera, to można to zrobić tylko programowo. Nie da sie przez fuses. To oznacza, ze program najpierw musi wystartować, aby tak było musi byc pod adresem bootloadera, aby tak sie stało trzeba zrobić swoja sekcję itd.

    0
  • #29 02 Gru 2018 18:27
    trol.six
    Poziom 31  

    LChucki napisał:
    Jakie adresy skoków zmienić?
    /.../
    Aby rozwiązać problem, należałoby stworzyć sekcję która będzie znajdowała sie pod adresem bootloadera

    Normalnie. Kolega pisze w asemblerze. Więc nie trzeba nic wielkiego robić, piszesz adres bezpośrednio w kodzie programu.
    .

    0
  • #30 02 Gru 2018 18:28
    TK_Kolejarz
    Poziom 4  

    Czyli dobrze rozumiem że mam tam dorzucić coś takiego:

    Kod: avrasm
    Zaloguj się, aby zobaczyć kod

    ? Czy jeszcze jakoś inaczej?

    0