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

ATmega16 [C] [AVRStudio5] - Przerwanie od odbieranej danej UART

shoko 15 Kwi 2013 13:26 2112 22
  • #1 12201230
    shoko
    Poziom 10  
    Witam,

    Od samego rana próbuje skłonić mojego AVR do współpracy, chcę mianowicie, aby odebrał znak (slowo) w przerwaniu, a nastepnie wyswietlił go na wyświetlaczu LCD i odesłał odpowiedź.

    I problem jest nastepujący. Jeśli odbieram dane znak(słowo) bez przerwania (po prostu funkcją USART_Receive), to działa, ale jak dodam instrukcje obsługi przerwań to już niekoniecznie.
    Kod: text
    Zaloguj się, aby zobaczyć kod


    I plik UART.h
    Kod: text
    Zaloguj się, aby zobaczyć kod


    Programik jest naprawdę prosty, a ja juz nie mam pomysłu co moge robić źle...

    Up. Może jeszcze dodam że:
    1) na pewno po stronie sprzętowej jest ok (wszystkie kabelki są poprawnie połączone) bo bez przerwania komunikacja działa
    2) na pewno fusy są dobrze na 16MHz, bo bez przerwań komunikacja działa.
  • #2 12201260
    excray
    Poziom 41  
    Zarówno "temp" jak i "i" powinny być volatile.
  • #3 12201268
    tmf
    VIP Zasłużony dla elektroda
    temp powinno być volatile. Inaczej się optymalizuje w pętli głównej, spójrz na wygenerowany kod asemblerowy.

    Dodano po 1 [minuty]:

    excray napisał:
    Zarówno "temp" jak i "i" powinny być volatile.


    i nie musi. Jest wykorzystywane tylko w przerwaniu. Za to powinno być zadeklarowane jako static w funkcji obsługi przerwania.
  • #4 12201289
    BlueDraco
    Specjalista - Mikrokontrolery
    Co robisz źle:

    1. To, co napisał excray.
    2. Umieszczasz kod w pliku .h - tego się nie robi
    3. Włączasz transmisję UART przed skofigurowaniem parametrów transmisji.
    4. źle zaplanowałeś odbiór danych w przerwaniu i przetwarzanie ich przez program główny - to prowizorka, która nie nadaje się do dalszego wykorzystania (wychodzenie z błędów).
    5. Niepotrzebnie czekasz na gotowość odbiornika w przerwaniu odbiornika - jeśli zgłosił przerwanie, to znaczy, że jest gotowy.
    6. funkcja zero() zeruje o jeden bajt za mało.
    7. Nie zerujesz zmiennej i - indeksu odbieranych danych - jest inkrementowany w nieskończoność.
    8. Definiujesz F_CPU w programie, a nie w ustawieniach projektu.
  • #5 12201292
    shoko
    Poziom 10  
    tmf napisał:
    temp powinno być volatile. Inaczej się optymalizuje w pętli głównej, spójrz na wygenerowany kod asemblerowy.

    Dodano po 1 [minuty]:

    excray napisał:
    Zarówno "temp" jak i "i" powinny być volatile.


    i nie musi. Jest wykorzystywane tylko w przerwaniu. Za to powinno być zadeklarowane jako static w funkcji obsługi przerwania.


    Dzięki za szybką odpowiedź, ale to chyba nie jest problemem...
    Jeśli użyję kodu
    Kod: text
    Zaloguj się, aby zobaczyć kod


    To wszystko działa. Wyłączam przerwania i jest ok.
  • #6 12201318
    tmf
    VIP Zasłużony dla elektroda
    Przeczytaj o co chodzi z tym volatile bo właśnie to jest problemem. Jeśli w pętli zmieniasz wartość temp to kompilator o tym wie, ale jeśli temp się zmienia niezależnie od programu, to skąd ma o tym wiedzieć? Prosty test, skompiluj program z -O0 i zobaczysz, że nagle magicznie zadziała.
  • #7 12201355
    shoko
    Poziom 10  
    Ok, po zapoznaniu się z Waszymi pomysłami, zmienilem nieco kod. Teraz wszystko jest w jednym pliku.

    tmf, dałem brak optymalizacji, niestety bez zmian...

    Kod: text
    Zaloguj się, aby zobaczyć kod
  • #8 12201367
    snnaap
    Poziom 25  
    W przerwaniu ustawiaj tylko flage (zmienną) która będzie przyjmował 1 lub zero, gdy przerwanie zostanie zgłoszone ustawa felgę na 1.
    Czyli :

    volatile uint8_t flaga;

    w przerwaniu

    Kod: text
    Zaloguj się, aby zobaczyć kod



    A w pętli głównej powinieneś mieć coś takiego:

    Kod: text
    Zaloguj się, aby zobaczyć kod
  • #9 12201400
    shoko
    Poziom 10  
    snnaap, thx, niestety dalej nie działa.

    Ja w petli main mam instrukcję wyświet("cos",7,1) to mi wyswietla na LCD wlasnie napis cos. W momencie wysłania do uP wiadomości (i prawdopodobnie wejściu w przerwanie) uP jakby się zwieszał, czyści się ekran (chociaż nigdzie w kodzie nie mam takiej instrukcji), tak jakby przy wywołaniu przerwania poszedł w krzaki...
  • #11 12201425
    shoko
    Poziom 10  
    No.... Nic sie nie wyswietla... Tak jakby nie mógł wejśc w to przerwanie...
  • #12 12201495
    BlueDraco
    Specjalista - Mikrokontrolery
    Jak dokładnie to testujesz? Co wysyłasz i w jaki sposób?
  • #13 12201513
    shoko
    Poziom 10  
    Uzywam RealTerma, w zakładce port ustawiam 19200, odpowiedni port, reszta juz jest.

    Następnie w send wpisuje co chce wyslać i już... Dla obsługi bez przerwań działa.(wiem, powtarzam się)
  • #15 12201641
    BlueDraco
    Specjalista - Mikrokontrolery
    Tzn. co wpisujesz i ile tego jest?
    Jaki masz rozmiar stosu?
  • #16 12201689
    shoko
    Poziom 10  
    Próbuje wpisywać tylko 1 litere, ("N"), ale bez zmian.

    Gdzie moge sprawdzić ten stos? Aczkolwiek 1 znakiem (8bit) raczej go nie przepełniam, nie?
  • #17 12201879
    BlueDraco
    Specjalista - Mikrokontrolery
    Nie przepełniasz go jednym znakiem, a składowaniem kontekstu przy przerwaniu - być może.

    Zacznij od prostego echa - co odbierzesz, to natychmiast nadawaj z powrotem. Zwykle tak się właśnie uruchamiało transmisję, kiedy nie było możliwości debugowania. Najpierw zrób to w pętli, potem w przerwaniu - będziesz wiedział, że przerwania działają.
  • #18 12204756
    shoko
    Poziom 10  
    Próbowalem tez robić echo... I jesli zrobie go tak:

    while(1){
    temp[i++]=USART_Receive();
    String_trans(temp[i]);
    }

    To nawet działa, ale jeśli tylko dodam obsługę przerwań (sei()) i próbuje to tam zrobić, to odmawia. Czy jest możliwa sytuacja, ze to wina uP? Sam klocek jest już troche sfatygowany i nie wiem, może już dochodze do 100 000 programowań?
  • #19 12204764
    BlueDraco
    Specjalista - Mikrokontrolery
    Echo - to odsyłanie znak po znaku. Odsyłaj pojedynczy znak, na początek w procedurze obsługi przerwania. Równocześnie możesz zmieniać stan diody, żeby coś Ci migało, kiedy przyjmujesz znaki.
    Pokaż to najprostsze echo i je przetestuj.

    Nie bardzo wiem, co ma robić String_trans(), ale Twoja maniera robienie wszystkiego na łańcuchach, a nie na znakach jest dziwnawa.

    I raczej nie szukaj winy w mikrokontrolerze. Ja stawiam na operacje na łańcuchach, nad którymi być może nie panujesz.
  • #20 12204811
    shoko
    Poziom 10  
    No ok, to naprościej jak mogłem wymyślić, port B (pin 1) ustawiam jako wyjście (DDRB=0x01), a w przerwaniu takie cos:

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


    W przerwaniu próbuje ustawić pin, odebrać znak i wysłać go spowrotem... Niestety nic sie nie dzieje, po sprawdzeniu, nóżka w dalszym ciągu jest w stanie niskim...
  • #21 12204990
    BlueDraco
    Specjalista - Mikrokontrolery
    Pokaż cały kod tego testu. Czy na pewno masz ustawiony właściwy typ procesora?
  • #22 12205078
    shoko
    Poziom 10  
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    No... tak mi sie wydaje, że ustawiony jest poprawny. Przy programowaniu mam wybrany ATMega16A, dokładnie taki jaki posiadam...

    Up. Zmienilem troche kod, uprościłem już do granic możliwości... jest tylko USART i obsługa GPIO, ale nadal nie ma tego echa na które liczę...

    Dodano po 1 [godziny] 39 [minuty]:

    Dobra... Chyba mam źródło problemu... Chyba wina Windowsa, zaniosłem wszystko do kumpla, on ma se7en 64bit, ja 32... Po zaprogramowaniu u Niego działa wsio elegancko, u mnie nie... Winda aż tak krzaczy? :O
REKLAMA