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.

[Atmega8][C] - Zatrzymujący się program

Atlantis86 08 Gru 2012 11:43 1479 10
  • #1 08 Gru 2012 11:43
    Atlantis86
    Poziom 19  

    Patrzę na kod od godziny, nie mogąc znaleźć przyczyny problemu. Pewnie winny jest jakiś drobiazg, którego nie jestem w stanie dostrzec. Zapewne ktoś z większym doświadczeniem wychwyci go natychmiast.

    Na początek trochę o projekcie. Jest to moje pierwsze "większe" przedsięwzięcie w ramach nauki programowania AVR-ów w języku C. Krótko mówiąc jakiś czas temu wpadł w moje ręce mocno zdekompletowany, bakelitowy telefon RWT (a właściwie sama obudowa + kilka elementów). Postanowiłem zrobić z niego "komórkę" w stylu retro, przy wykorzystaniu modułu GSM Motorola D15.
    Oczywiście nie jest to pomysł w 100% oryginalny, ktoś to już wcześniej zrobił (link TUTAJ). Przy czym ten projekt wykorzystywał inny moduł oraz procesor PIC, więc jedynie częściowo wzorowałem się na tamtym kodzie.

    Na razie prowadzę próby na płytce testowej z Atmegą8 (końcowe urządzenie ma pracować na ATTiny 2312/ lub 4313), łącząc ją z komputerem przy pomocy moduły na MAX3232 (jeszcze nie prowadziłem prób z użyciem samego modułu).
    Trochę jeszcze zostało do zrobienia (zasilanie z akumultorka + układ ładowania, uruchamianie elektromechanicznego dzwonka, może nawet dialtone w słuchawce), na razie jednak pracuję głównie nad stroną programową.

    Oto kłopotliwy kod

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Na czym polega problem? Otóż program zatrzymuje się we wczesnej fazie inicjacji swojego działania. Tuż po włączeniu zasilania zapala na chwilę "status led" a potem wysyła na terminal "AT\r". W tym momencie wszystko powinno być uzależnione od odpowiedzi. W przypadku wysłania mu "OK" powinien przejść do kolejnej instrukcji i wysłać "AT+CPIN=?\r". Nie robi tego. W przypadku jakiejkolwiek innej odpowiedzi powinien zareagować przerwaniem procedury inicjującej i zwróceniem kodu błędu, który powinien wyświetlać się w postaci serii błysków "status led". Niestety - tego program również nie robi. Po prostu stoi w tym miejscu i nie chce ruszyć dalej.

    Sprawdziłem komunikację w drugą stronę - Atmega otrzymuje znaki, rozróżnia też moment otrzymania "\r".

    Do głowy przychodzą mi następujące możliwości:
    - Błąd przy przepisywaniu zawartości tabeli rx_buffer do last_line (dzieje się to w przerwaniu, w momencie odebrania "\r".
    - Błąd przy porównywaniu dwóch ciągów znaków (funkcja string compare).
    - Błąd w funkcji usart_response, szczególnie w instrukcji nakazującej czekanie do momentu pojawienia się danych w tabeli last_line.

    Problem w tym, że patrzę na te części kodu i nie mogę dopatrzeć się niczego podejrzanego...

    0 10
  • #3 08 Gru 2012 13:00
    Atlantis86
    Poziom 19  

    Hmm... W takim razie nie mam pojęcia co go może zatrzymywać.
    Procedura usart_response po wysłaniu komunikatu wstrzymuje działanie programu (pętla while) dopóki do tabeli nie zostanie skopiowana odebrana wiadomość (to znaczy dopóki jej pierwszy element jest zerem).
    Kopiowanie z bufora do last_line odbywa się w przerwaniu, kopiowane są znaki do wystąpienia "\r" (ale bez niego), więc niby wszystko się zgadza.

    Na początku programu na wszelki wypadek czyszczę bufor i last_line, a więc na pewno winy nie ponoszą jakieś przypadkowe dane.

    Atmega otrzymuje dane napływające z terminalu, a więc albo coś dzieje się po drodze do tabeli last_line (tylko co?) albo mam jakiś problem z konfiguracją w HyperTerminal?

    Tylko w tym drugim przypadku co mogłoby być nie tak? Atmega reaguje na odebranie "\r" w momencie naciśnięcia klawisza "Enter", a więc sytuacja powinna być prosta: program wykrywa "\r", kopiuje ciąg przechwyconych znaków do last_line, funkcja usart_response zauważa wypełnienie tabeli i sprawdza czy zgadza się z oczekiwaną odpowiedzią. Tak - przechodzi dalej. Nie - zgłasza numer błędu...

    Im dłużej na to patrzę, tym bardziej wydaje mi się, że wszystko jest w porządku. :)

    Ok, mały update. Zamieniłem pętlę while w funkcju usart_response (oczekiwanie na pojawienie się danych w tabeli last_line) na zwykłe opóźnienie _delay_ms().

    Zadziałało.

    Ktoś wie co mogło być nie tak?

    0
  • #4 08 Gru 2012 14:52
    zumek
    Poziom 39  

    Mi w Twoim kodzie, brakuje jednego zaklęcia :D

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #5 08 Gru 2012 15:22
    Atlantis86
    Poziom 19  

    W którym miejscu konkretnie? ;)

    0
  • #6 08 Gru 2012 15:25
    mi14chal
    Poziom 28  

    Tam gdzie zmienne używasz w przerwaniu, wtedy jeszcze musisz dodać volatile

    0
  • #7 08 Gru 2012 15:44
    Atlantis86
    Poziom 19  

    Może jednak więcej szczegółów? Powinienem wstawić volatile przed każdym wystąpieniem nazwy tabel rx_buffer i last_line? Gdy to robię w przypadku operacji przypisania albo sprawdzenia wartości, kompilator zwraca błąd.
    Chyba coś innego miałeś na myśli. ;)

    0
  • #9 08 Gru 2012 16:27
    Atlantis86
    Poziom 19  

    W porządku, ustawiłem:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Program się skompilował, ale kompilator zwrócił następujące uwagi, których nie było wcześniej:

    Cytat:

    telefon.c: In function 'usart_response':
    telefon.c:91: warning: passing argument 1 of 'string_compare' discards qualifiers from pointer target type
    telefon.c: In function 'main':
    telefon.c:332: warning: passing argument 1 of 'string_compare' discards qualifiers from pointer target type


    To coś ważnego? Powinienem coś jeszcze poprawić? Ma to coś wspólnego z tym, że dane do funkcji operujących na tekstach przekazuję przez tabele, a nie wskaźniki?

    0
  • #10 08 Gru 2012 21:37
    GSM
    Poziom 25  

    Atlantis86 napisał:
    warning: passing argument 1 of 'string_compare' discards qualifiers from pointer target type

    Przeczytaj uważnie ostrzeżenie od kompilatora, spójrz na deklarację string_compare i na miejsca gdzie korzystasz z tej funkcji (typy przekazywanych parametrów, a dokładnie ich kwalifikatory). Powinno ci się rozjaśnić na co zwraca twoją uwagę kompilator.

    Pozdrawiam,
    GSM

    0
  • #11 08 Gru 2012 22:20
    Atlantis86
    Poziom 19  

    Gdyby samo przeczytanie miało mi coś wyjaśnić, to nie zadawałbym tego pytania. ;)
    Jak już pisałem w tej chwili dopiero uczę się programowania w C, a do programowania jako takiego (wcześniej miałem do czynienia z Pascalem i Delphi) wróciłem po kilkuletniej przerwie. Tak więc proszę o wyrozumiałość.

    Swoją drogą może ktoś z Was orientuje się, czy w takich modułach jak Motorola D15 można na stałe zmienić sposób komunikacji po rs232?
    Konkretnie chodzi mi o dwie kwestie:
    - Wyłączenie echa - powracające znaki mieszają w komunikacji.
    - Wyłączenie wysyłania znaków następnej linii oraz wstawiania pustych linii
    Echo mogę wyłączyć komendą ATE0, sęk jednak w tym, że muszę to robić za każdym razem po włączeniu zasilania.

    Najlepiej byłoby, gdyby obowiązywał prosty schemat komunikacji, w którym na "KOMENDA\r" moduł odpowiadałby po prostu
    "ODPOWIEDŹ\r". Da się uzyskać taki efekt czy jedyną opcją jest programowe wyłuskiwanie potrzebnych informacji po stronie uC?

    0