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

[ATmega32a][USART] - Restartowanie mikrokontrolera przy "zalaniu" RXD

piotrbdg2010 10 Kwi 2013 08:39 2667 16
  • #1 12180107
    piotrbdg2010
    Poziom 9  
    Witam,

    Mam pytanie czy to co opisuję poniżej jest normalne:
    Mikrokontroler restartuje się przy wyłączonym interfejsie USART w sytuacji, w której pin RXD zaczynam "zalewać" sygnałem, tj. wysyłam kolejne bajty.

    Zjawisko obserwuję niezależnie od szybkości wysyłania danych na pin RXD, natomiast zadaża się częściej przy większych częstotliwościach wysyłania danych przez port szeregowy na PC. Testowałem 230400, 19200, 9600.

    Będę wdzięczny za informację czy jest to naturalne zjawisko?
  • #3 12180290
    BlueDraco
    Specjalista - Mikrokontrolery
    Przy błędnym projekcie sprzętu i oprogramowania to jest bardzo naturalne zjawisko. Skoro jednak ani na temat sprzętu, ani oprogramowania nie chcesz puścić pary, proponuję szukać pomocy u wróżki a nie tutaj.
  • #4 12181096
    piotrbdg2010
    Poziom 9  
    Ok, postaram się sprecyzować:
    W docelowym podejściu wykorzystany uC to ATmega32a. Kod do inicjalizacji interfejsu USART to raczej standard w postaci:
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    przekazywany ubrr to dla zadanego zegara (14745600UL), 230400UL bitów na sekundę.

    Komunikacja PC-ta z uC odbywa się przez przez przejściówkę USB->Serial. Odbiór danych nie przez polling tylko poprzez przerwanie z wektorem TIMER0_OVF_vect. Wszystko działa. Tzn przesyłane są prawidłowe dane jednak co kilka-kilkanaście sekund następuje restart uC. Aha, uC jest cały czas, w pętli, odpytywany o pewne informacje i pewne informacje o swoim stanie odsyła. Dodatkowo mogę wspomnieć, że włączone są jeszcze przerwania ADC_vect oraz TIMER0_OVF_vect, które działają bez zarzutu.

    Szukając przyczyny problemu postanowiłem zredukować problem czyli wykluczyć ewentualne przyczyny i maksymalnie to uprościć. Co zrobiłem, to ostatecznie całkowicie wyłączyłem interfejs usart (aby wykluczyć przyczyny problemu związane z potencjalnie błędną obłsugą przychodzących danych - zapis i analiza).

    Mam zatem, w tej chwili uC, z włączonym przetwornikiem A/D, PWM-em, przerwaniami timera i wyłączonym USART-em. Test, który przeprowadzam polega na wysyłaniu danych na pin RXD z dowolnymi pręckościami transmisji i sprawdzaniu czy uC będzie się restartował. To właśnie miałem na myśli pisząc "zalewać".

    Przepraszam za mało precyzyjny opis problemu, natomiast uzanałem, że w tym przypadku przy takim okrojeniu problemu będzie on wystarczający. Aby jeszcze doprecyzować kwestię sprzętu wysyłam schemat.

    [ATmega32a][USART] - Restartowanie mikrokontrolera przy "zalaniu" RXD

    Kodu nie zamieszczam bo przy wyłączonym interfejsie USART właściwie go nie ma. Jest jedynie pętla w aplikacji na PC-cie, która wysyła bajty na port szeregowy. Jeżeli w analizie problemu ma pomóc zamieszczenie kodu od przetwornika ADC, albo kodu związanego z generowaniem syganłu PWM to mogę też zamieścić (choć w jednej z prób wyłączenie ADC też nic nie dało)
  • #5 12181880
    BlueDraco
    Specjalista - Mikrokontrolery
    Problem leży zapewne w kodzie, który odbiera dane z UART, albo w całej strukturze oprogramowania - zagnieżdżanie procedur, ew. samych przerwań. Dopóki tego nie pokażesz nic Ci nie pomożemy.
  • #6 12182978
    piotrbdg2010
    Poziom 9  
    problem w tym, że tak jak pisałem, nie istnieje kod odbierający dane z UART. Cały interfejs na potrzeby testów jest całkowicie wyłączony - nie inicjalizuję UART, nie ma żadnej implementacji przerwań związanych z UART (ani rxc, ani txc). Trudno mi to pokazać bo tego zwyczajnie nie ma. Specjalnie maksymalnie wszystko okroiłem żeby nikogo na forum nie męczyć analizą kodu. Ten kod jest całkowicie zakomentowany. Obecny test sprowadza się do wysyłania bitów z prędkością 9600 oraz 230400 do mikrokontrolera z wyłączonym UART-em.
    Efektem jest restartowanie uC. Im szybciej wysyłam bity tym częściej uC reaguje restartem. Czy takie zjawisko przy wyłączonym UART jest naturalne?
    uC nic nie odbiera, ani nie wysyła. Na pinie pojawia się jedynie sygnał z PC, ale uC nie ma go odbierać. Ma być zwyczajnie głuchy, a się restartuje.
  • #7 12183329
    dondu
    Moderator na urlopie...
    Ustalałeś przyczynę resetu, na podstawie rejestru MCUCSR?

    piotrbdg2010 napisał:
    problem w tym, że tak jak pisałem, nie istnieje kod odbierający dane z UART. Cały interfejs na potrzeby testów jest całkowicie wyłączony - nie inicjalizuję UART, nie ma żadnej implementacji przerwań związanych z UART (ani rxc, ani txc).

    W kodzie włączasz przerwania od nadawania, więc musisz mieć funkcję ich obsługi - masz, czy nie?
    Chyba, że źle Ciebie zrozumiałem.
  • #8 12184090
    Tomasz Gumny
    Poziom 28  
    Czy "przejściówka USB->Serial" robi konwersję poziomów RS232C na TTL?
  • #9 12184236
    BlueDraco
    Specjalista - Mikrokontrolery
    Przejściówka USB-Serial RS232 (ze złączem DB9) ma wyjścia i wejścia z grubsza zgodne ze standardem napięciowym RS232. Przejóciówka USB-Serial TTL (ze szpilkami lub kontaktami) ma wyjścia na poziomach logicznych podobnych do TTL.
  • #10 12184424
    piotrbdg2010
    Poziom 9  
    @dondu, dziękuję za sugestię, nie sprawdzałem rejestru MCUCSR, dziś lub jutro wracam do tematu i sprawdzę przyczynę resetu. Co do kodu - nie włączam niczego związanego z USART. Jednak aby mieć pewność, że przyczyna nie leży po stronie kodu wyłączę jeszcze PWM oraz Timer. Czyli sprowadzę kod mniej więcej do
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    i po kolei będę włączał docelowe fragmenty kodu. Podejście może nieco chałupnicze, ale wierzę, że się uda.

    @Tomasz Gumny - tak
  • #11 12184704
    Konto nie istnieje
    Konto nie istnieje  
  • #12 12184978
    piotrbdg2010
    Poziom 9  
    @Albert B. - napisałem, że nie przez polling i jest tak jak napisałem. Kwiatek faktycznie jest, ale nie w kodzie tylko w opisie - pomyliłem się przy cytowanym przez Ciebie opisie, miało być "USART_RXC_vect". Przepraszam za wprowadzenie w błąd. Poza tym tak jak pisałem kilka razy cały ten kod na potrzeby testów jest zakomentowany i tak jak pisałem wszystko działa bez zarzutu do chwili, w której zaczynam na pin RXD wysyłać sygnał. Więc jeszcze raz - na potrzeby testów po stronie kodu wyłączony jest UART (nie ma przerwań ani od rxc, ani txc, nie ma i nigdy nie było pollingu) jedyne co się dzieje to fizycznie na pinie RXD pojawia się sygnał.
  • #13 12185053
    BlueDraco
    Specjalista - Mikrokontrolery
    Może przesłuch z RXD na RESET? Ja jednak stawiam na jakiś gruby błąd w kodzie.
  • #14 12195128
    piotrbdg2010
    Poziom 9  
    Witam ponownie,

    Walczę z tematem i ostatecznie szukając błedów w kodzie usunąłem cały kod i napisałem prosty kod testowy (poniżej).

    Jeszcze raz sprawdziłem układ, oddaliłem od siebie połączenia żeby nie było przesłuchu.

    Niestety problem dalej występuje. Podejrzewałem jednoczesne podłączenie programatora, ale z odłączonym jest ten sam efekt.

    Poniżej zamieszczam maksymalnie okrojony kod, dla którego problem nadal występuje.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    oraz
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Jedyne co w według mnie robi ten kod to zapalanie i gaszenie ledów podłączonych pod PC5..0 oraz PD0

    Jeżeli chodzi o kwestię rejestru MCUCSR to sprawdzam to przy pomocy kodu:
    Kod: text
    Zaloguj się, aby zobaczyć kod


    Nie jestem pewien czy tak powienienem to zrobić. W wyniku takiego sprawdzenia ustawione są 2 bity MCUCSR1..0 (PORF i EXTRF) - jest tak po podłączeniu zasilania i stan nie zmienia się przy restartach. Czasem również zamiast restartów uC się tak jakby zawiesza, tzn dioda, którą naprzemian gasiłem i zapalałem przestaje zmieniać swój stan (albo się ciągle świeci, albo jest zgaszona).

    Aha, jako dodatkową informację mogę podać ustawienia fusebitów.
    avrdude -c usbasp -p m32 -U lfuse:w:0x3F:m -U hfuse:w:0x99:m

    Zaczyna brakować mi pomysłów :(
  • #15 12195884
    Tomasz Gumny
    Poziom 28  
    piotrbdg2010 napisał:
    Nie jestem pewien czy tak powienienem to zrobić. W wyniku takiego sprawdzenia ustawione są 2 bity MCUCSR1..0 (PORF i EXTRF) - jest tak po podłączeniu zasilania i stan nie zmienia się przy restartach.
    Skasuj wszystkie flagi resetu na początku programu i napisz, która się ustawia po tym domniemanym restarcie.
  • #16 12197906
    cefaloid
    Poziom 34  
    piotrbdg2010 napisał:
    problem w tym, że tak jak pisałem, nie istnieje kod odbierający dane z UART. Cały interfejs na potrzeby testów jest całkowicie wyłączony - nie inicjalizuję UART, nie ma żadnej implementacji przerwań związanych z UART (ani rxc, ani txc). Trudno mi to pokazać bo tego zwyczajnie nie ma.


    To może być banalna sprawa.
    Włączyłeś obsługę przerwań UART, spróbuj obsłużyć wszystkie 4 przerwania:
    13 $018 = Serial Transfer Complete
    14 $01A = Rx Complete
    15 $01C = Data Register Empty
    16 $01E = Tx Complete

    Nawet pustym kodem, ale jeśli jakieś przerwanie jest włączone to musisz je obsługiwać inaczej program wykona skok pod 0000 i wykona reset.
    Być może któreś z nich się sporadycznie pojawia?

    Dodano po 14 [minuty]:
    Widzę że wyłączyłeś przerwania i to samo...
    Jeśli tak to jedyne co mi przychodzi do głowy to jakieś zakłócenia
  • #17 12210809
    piotrbdg2010
    Poziom 9  
    Witam po przerwie, problem rozwiązany połowicznie - wiem co zrobić żeby się go pozbyć, ale przyczyna nie jest do końca znana i bez oscyloskopu trudno mi to stwierdzić na 100%, ale... od początku...

    Ponieważ zredukowany, praktycznie do zera kod, dawał te same rezultaty to prosty wniosek - z kodem było wszystko OK. Zarówno testowym jak i docelowym (bo teraz już na takim działam). A zatem sprzęt...

    Poraz n-ty sprawdziłem układ - wszystko wyglądało ok. No to zacząłem podejrzewać, że może coś uszkodziłem przypadkiem więc zacząłem wymieniać po kolei - kwarc, jego kondensatory, stabilizator napięcia, na końcu sam uC i nic.

    Następne podejrzenie padło na przejściówkę USB/TTL i tu chyba jestem blisko. Poprzednio na ATtiny2313 i ATmega8 działała bez zarzutu i nie powodowała takich efektów, jednak podejrzewając uszkodzenie postawnowiłem podłączyć sygnał RXD przez 330Ohm do pinu RXD i 330Ohm (ogólnie to chyba troszkę za małe) do masy czyli zrobiłem dzielnik napięcia na tym sygnale i co się okazało - nagle wszystko zaczęło działać.

    Niestety nie mam narzędzi żeby zmierzyć faktyczne napięcie tego sygnału, ale strzelam, że przejściówka musiała się zepsuć (bądź też ja jej w tym przypadkiem kiedyś nieświadomie pomogłem bo po pierwsze działała na innych uC, po drugie nie chce mi się wierzyć w wadliwy od początku sprzęt).
REKLAMA