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.

ATMEGA8A - USART i odbieranie stringu

Dolby1337 26 Lut 2016 00:04 1080 15
  • #1 26 Lut 2016 00:04
    Dolby1337
    Poziom 4  

    Witam!
    Mam problem z odbieraniem stringów przez USART. Chcę, aby po wpisaniu do terminala na komputerze "abc", mikrokontroler odesłał "OK".

    Kod programu:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Gdzie jest błąd w moim rozumowaniu?

    0 15
  • Pomocny post
    #2 26 Lut 2016 00:24
    jnk0le
    Poziom 17  

    Kod: c
    Zaloguj się, aby zobaczyć kod

    Za mały bufor na 3 znaki - gdzieś trzeba zmieścić NULL.

    Kod: c
    Zaloguj się, aby zobaczyć kod

    warunek nigdy nie zostanie spełniony - porównujesz wskaźniki na tablice.
    Powinieneś użyć coś w rodzaju strcmp().

    0
  • #3 26 Lut 2016 15:03
    Dolby1337
    Poziom 4  

    Próbuję teraz tak:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Jednak w terminalu odpowiedź nie przychodzi od razu. Gdy wysyłam string "start", dopiero za którymś razem z kolei wyrzuca mi odpowiedź, ale nie wysyła "OK.
    ATMEGA8A - USART i odbieranie stringu

    0
  • Pomocny post
    #4 26 Lut 2016 15:42
    2675900
    Użytkownik usunął konto  
  • #5 28 Lut 2016 21:35
    Dolby1337
    Poziom 4  

    Poprawiłem kod:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    Po wpisaniu "tekst" do terminala dostaję odpowiedź "OK".

    Jednak chciałbym zrobić tak, aby funkcja receive() zwracała string i zapisywała go do zmiennej w funkcji głównej. Próbowałem tak:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    lecz dostaję błąd w kompilatorze: "error: incompatible types in assignment". Jakieś wskazówki co do tego problemu?

    0
  • Pomocny post
    #6 28 Lut 2016 21:58
    BlueDraco
    Specjalista - Mikrokontrolery

    Zadeklaruj bufor data[] na poziomie zewnętrznym. Bufor zadeklarowany wenątrz funkcji przestaje istnieć przy powrocie z funkcji.

    Błąd, o którym piszesz, jest sygnalizowany w konkretnej linii. Czy my mamy zgadywać, w której?

    No to zgadujemy: w tej:
    buffer = receive();

    buffer jest stałą adresową i nie można nic pod nią podstawić. Błąd zniknie, gdy będzeisz miał jeden bufor zadeklarowany na poziomie zewnętrznym.

    Jesteś kolejną ofiarą dziwnej maiery włączai UART przed skonfigurowaniem go - zmień kolejność instrukcji w funkcji init()

    0
  • Pomocny post
    #7 28 Lut 2016 22:15
    2675900
    Użytkownik usunął konto  
  • #8 28 Lut 2016 22:50
    Dolby1337
    Poziom 4  

    BlueDraco napisał:
    Zadeklaruj bufor data[] na poziomie zewnętrznym. Bufor zadeklarowany wenątrz funkcji przestaje istnieć przy powrocie z funkcji.
    BlueDraco napisał:
    buffer jest stałą adresową i nie można nic pod nią podstawić. Błąd zniknie, gdy będzeisz miał jeden bufor zadeklarowany na poziomie zewnętrznym.

    Chodzi o deklarację zmiennej data[] jako zmienna globalna? Próbowałem i ten sposób działa, ale czytałem dużo, aby nie używać zmiennych globalnych, bo można wiele namieszać. Pewnie chodzi o dużo większe projekty, ale jednak chciałem uniknąć użycia zmiennych globalnych.

    BlueDraco napisał:
    Błąd, o którym piszesz, jest sygnalizowany w konkretnej linii. Czy my mamy zgadywać, w której?

    No to zgadujemy: w tej:
    buffer = receive();

    Zgadza się :D

    BlueDraco napisał:
    Jesteś kolejną ofiarą dziwnej maiery włączai UART przed skonfigurowaniem go - zmień kolejność instrukcji w funkcji init()
    Piotrus_999 napisał:
    Podejrzewam ze gdzies w sieci jest taki kod, i do tego jest wysoko w google.

    ATMEGA8A - USART i odbieranie stringu
    W datasheecie najpierw jest konfiguracja prędkości, potem uruchomienie usarta i dopiero na końcu ustawienie formatu ramki. Jednakże słuszna uwaga i będę o niej pamiętał. :)

    0
  • Pomocny post
    #9 29 Lut 2016 08:31
    grko
    Poziom 32  

    Cytat:

    Chodzi o deklarację zmiennej data[] jako zmienna globalna? Próbowałem i ten sposób działa, ale czytałem dużo, aby nie używać zmiennych globalnych, bo można wiele namieszać. Pewnie chodzi o dużo większe projekty, ale jednak chciałem uniknąć użycia zmiennych globalnych.


    W tym przypadku wystarczy, że bufor data zadeklarujesz jako static. Masz tu jeszcze kilka błędów. Funkcja receive zwraca char a Ty próbujesz zwrócić char *. Dodatkowo w main próbujesz przypisać to co zwraca receive do tablicy buffer (co sie nie powinno skompilować). Spróbuj tak:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • Pomocny post
    #10 29 Lut 2016 08:57
    BlueDraco
    Specjalista - Mikrokontrolery

    Jaki sens ma funkcja, która zawsze zwraca tę samą wartość? Równie "obiektowe", co bezsensowne. Dzięki takiemu podejściu zmniejszamy szanse na optymalizację kodu przez kompilator.

    0
  • Pomocny post
    #11 29 Lut 2016 09:32
    grko
    Poziom 32  

    Cytat:

    Jaki sens ma funkcja, która zawsze zwraca tę samą wartość? Równie "obiektowe", co bezsensowne.


    Taki pomysł na funkcję miał autor tematu. Nie wnikam w sensowność tego rozwiązania. Naprawdę, masz dziwne rozumienie obiektowości.

    0
  • #12 29 Lut 2016 15:49
    Dolby1337
    Poziom 4  

    GrzegorzKostka napisał:

    Spróbuj tak:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    Faktycznie, nie zwracałem całego string'u, dziękuję za pomoc.

    BlueDraco napisał:
    Jaki sens ma funkcja, która zawsze zwraca tę samą wartość? Równie "obiektowe", co bezsensowne. Dzięki takiemu podejściu zmniejszamy szanse na optymalizację kodu przez kompilator.

    Nie bardzo rozumiem o co chodzi. Przecież funkcja receive() nie zwraca tej samej wartości przez cały czas.

    Dodano po 17 [minuty]:

    Czyli rozumiem, że nie ma różnicy czy zrobię to sposobem, który podał GrzegorzKostka czy zrobię to deklarując zmienną globalną?

    0
  • Pomocny post
    #13 29 Lut 2016 15:53
    BlueDraco
    Specjalista - Mikrokontrolery

    Wartością funkcji jest adres bufora data. Ten adres jest stały. To dobry powód, żeby zadeklarować bufor na poziomie zewnętrznym i odwoływać się do niego bezpośrednio w main(). Funkcja receive nie powinna w takim przypadku zwracać nic. ew. może zwracać liczbę znaków w buforze, jeśli miałoby to coś uprościć. Nie ma również sensu zapisywać '\r' do bufora; zamiast tego funkcja mogłaby wpisywać 0. Pętla w funkcji musi też sprawdzać, czy nie przekroczyliśmy rozmiaru bufora, inaczej program pójdzie w dość trudne do przewidzenia maliny z powodu zamazania jakichś danych,

    0
  • #14 29 Lut 2016 16:22
    Dolby1337
    Poziom 4  

    Kod po poprawkach:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    Czy teraz jest wszystko w porządku?

    0
  • Pomocny post
    #15 29 Lut 2016 17:34
    grko
    Poziom 32  

    Nie do końca.

    W funkcji receive możliwy jest zapis poza buforem (jak przyjdzie Ci BUFFER_SIZE znaków bez '\r'). Więc zadeklaruj bufor o jeden znak większy:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    albo w pętli w funkcji zrób inny warunek wyjścia:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Wszystkie zmienne globalne/funkcje używane tylko w jednym module powinny mieć atrybut static.
    Kolejna sprawa. Twój kod to nie C++ i zapis:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    nie jest równoważny z:
    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #16 29 Lut 2016 20:20
    Dolby1337
    Poziom 4  

    Dziękuję wszystkim za pomoc. :wink:

    0