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

[C] Odczytywanie kolejnych bajtów z UART

meehowk3 23 Paź 2011 16:20 1619 14
  • #1 23 Paź 2011 16:20
    meehowk3
    Poziom 10  

    Cześć,
    w związku z tym, że nie mam na razie możliwości sprawdzenia poprawności kodu, który napisałem, pytam was programistów. Czy jest on poprawny? Mianowicie: do UDR co chwila napływa 8 bitów danych, funkcja ma za zadanie wychwycić każdy bajt z osobna i wpisać go do tablicy 'ramka'. Tzn. wychwytywania bitów tutaj jeszcze nie ma (chyba) ale jest zapisywanie do tablicy. Czy poprawne? Proszę o weryfikację.

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0 14
  • Arrow Multisolution Day
  • Pomocny post
    #2 23 Paź 2011 16:44
    Slkkk
    Poziom 14  

    Ten kod nie jest poprawny pod absolutnie żadnym względem :). To to on robi, to odczytuje spod adresu (8-bitowego) zapisanego w zmiennej UDR wartość i wpisuje ją do pierwszego z pięciu bajtów ramki. Funkcja zwraca osiem najmłodszych bitów adresu zmiennej UDR.

    Domyślam się, że UDR to rejestr uC AVR. Weryfikację kodu robi już kompilator wyświetlając dla niego 4 ostrzeżenia, co można uznać za wynik "wybitny" zważywszy na ilość instrukcji w kodzie. Po pierwsze: włączyć ostrzeżenia! Po drugie: wcięcia nie wpływają na to ile instrukcji wchodzi w skład pętli :). Dalej: należy jakoś kontrolować kiedy można z UDR coś odczytać -- inaczej każdy bajt zostanie odczytany setki albo i tysiące razy.

    0
  • #3 23 Paź 2011 17:22
    meehowk3
    Poziom 10  

    Poprawiłem trochę kod. Ustawiłem kontrole odczytywania UDR. Czy zostanie zapisana cala tablica? Tym razem wklejam cały kod a nie tylko fragment:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Cytat:
    Po drugie: wcięcia nie wpływają na to ile instrukcji wchodzi w skład pętli

    Szczerze mówiąc nie rozumiem:)

    0
  • Arrow Multisolution Day
  • Pomocny post
    #4 23 Paź 2011 17:43
    Slkkk
    Poziom 14  

    Nadal polecam włączyć wyświetlanie ostrzeżeń przez kompilator i je wszystkie wyeliminować. Dokładniej to w taki sposób:
    1) Pierwszy warning: jeśli odbiór ramki ma coś zwracać, to niech zwraca coś z sensem, a jak nie to niech nie zwraca w ogóle (void).
    2) Drugi warning: odbior_ramki(d, ramka, a) -- bez gwiazdki przed d.
    3) Pętla w odbior_ramki: użyć { klamerek } (to odnośnie tego co wcześniej pisałem o wcięciach)
    4) Nadal pętla w odbior_ramki czyta wielokrotnie z UDR i nie czeka na pojawienie się nowych danych.
    5) Do obliczania wartości UBRR lepiej posługiwać się <util/setbaud.h> (http://www.nongnu.org/avr-libc/user-manual/group__util__setbaud.html) -- unikniemy magicznych stałych i ewentualnych błędów w ich liczeniu.

    Dodano po 8 [minuty]:

    A tak naprawdę to najlepsze rozwiązanie to najprostsze:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #5 23 Paź 2011 17:48
    meehowk3
    Poziom 10  

    Na prawdę to wszystko co napisałem o odbiorze ramki można zastapić tymi dwiema linijkami co podałeś? No to podcięło mi to trochę skrzydła. Na swoja obronę mogę powiedzieć tyle że C sie dopiero uczę a wskaźniki poznałem wczoraj. Muszę zmienic tok myślenia. Do Warszawy nie przez Tokio tylko przez Sochaczew.
    Dzięki kolego za poświęcony czas.

    0
  • #6 23 Paź 2011 18:00
    Slkkk
    Poziom 14  

    meehowk3 napisał:
    Czyli jeżeli zrobię tą funkcję bez zwracania to będzie poprawnie? Tzn. zapisze ten bajt do tablicy?

    Nie rozumiem. To co zwraca funkcja odbior_ramki nie ma nic wspólego z tym, co zapisuje do tablicy.
    meehowk3 napisał:
    No to mam problem bo nie mam pomysłu na razie. Jakieś sugestie? Czego brakuje?

    Pisząc funkcję odbior_USART kolega jakoś miał pomysł jak poczekać na dane :). Trzeba i tutaj wstawić takie samo czekanie. Albo pozbyć się tych wszystkich wskaźników na UDR (jeśli nie są potrzebne w innych fragmentach programu, których tutaj nie widać) i zamiast *a używać odbior_USART().

    0
  • #7 25 Paź 2011 18:40
    meehowk3
    Poziom 10  

    Witam ponownie
    Rozbudowałem program o kolejną funkcję, która wyłuskuje z tablicy drugi element i wykonuje zadanie które było zapisane w tym elemencie. Czy rzeczywiście tak się dzieje? Dodałem również pętle 'do while'. Czy jeżeli warunek tej pętli nie jest spełniony to program wykonuje znowu pętlę 'for'?
    Program wyrzuca taki warning:

    Code:
    mbus.c:49: warning: passing argument 1 of ‘funkcja’ makes pointer from integer without a cast
    

    Chodzi o tę linię: funkcja(ramka[1]);

    Niestety nie mam możliwości załadowania programu jak również nie mam kontaktu z żadnym programistą dlatego szukam porady tutaj.
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Pozdrawiam

    0
  • #8 25 Paź 2011 19:15
    Slkkk
    Poziom 14  

    Funkcja zupełnie niepotrzebnie pobiera wskaźnik na wartość, powinno to chyba być tak:

    Kod: c
    Zaloguj się, aby zobaczyć kod
    -- to załatwi też sprawę warninga.

    Pętla do..while robi coś takiego: jeśli w pierwszym elemencie ramki najmłodszym bitem jest 0, to wywołuje funkcję funkcja(ramka[1]) raz, zaś w przeciwnym przypadku nieskończenie wiele razy.

    0
  • #9 25 Paź 2011 19:28
    meehowk3
    Poziom 10  

    Slkkk napisał:

    Pętla do..while robi coś takiego: jeśli w pierwszym elemencie ramki najmłodszym bitem jest 0, to wywołuje funkcję funkcja(ramka[1]) raz, zaś w przeciwnym przypadku nieskończenie wiele razy.


    To jak to zrobić żeby działało tak: gdy wartośc 0x01 jest równa wartości w ramka[0] to wykonuje się funkcja(ramka[1) a jeżeli nie to program ma ponownie sprawdzać ten warunek? Może etykieta tak jak się to robi w asemblerze? Albo If?

    0
  • #10 25 Paź 2011 19:31
    Slkkk
    Poziom 14  

    Ponownie sprawdzać ten sprawdzony już warunek? Czyli zawiesić się?

    0
  • #11 25 Paź 2011 19:41
    meehowk3
    Poziom 10  

    Czekać (nic nie robić) aż ten warunek będzie w końcu poprawny.

    0
  • #12 25 Paź 2011 19:47
    Slkkk
    Poziom 14  

    Ale bez odebrania kolejnej ramki sam z siebie poprawny się nie stanie :). Czyli chodzi pewnie o taki prosty kod, przy okazji pozwoliłem wprowadzić sobie kilka drobnych modyfikacji:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0
  • #13 25 Paź 2011 19:58
    meehowk3
    Poziom 10  

    Jeżeli warunek jest nie poprawny to program wraca do pętli for? Program będzie docelowo wgrany na mikrokontroler. Czy taki warunek jaki podałeś w If'ie ma swoje odzwierciedlenie w pamięci mikrokontrolera? Nie powinno być (0x01 & ramka[0]) ?

    0
  • #14 25 Paź 2011 20:04
    Slkkk
    Poziom 14  

    Program wykonuje w kółko to, co jest w pętli while, czyli na przemian fora i ifa. Warunek mówi, że ramka[0] ma być równe 1. (0x01 & ramka[0]) oznacza, że tylko najmłodszy bit ma być równy 1 (czyli że ramka[0] ma być nieparzysta).
    Tak ogólnie to nie polecam zaczynać nauki od programowania, tylko od przeczytania choć kawałeczka jakiejś książki albo kursu w sieci, gdzie na pewno będzie pokazanych i omówionych kilka prostych programów :).

    0
  • #15 25 Paź 2011 20:15
    meehowk3
    Poziom 10  

    Niestety nie mam czasu na czytanie całych książek bo terminy mnie gonią, do końca tygodnia muszę oddać ten program. Kursy przerobiłem ze dwa. Wiem, że nie dysponuje zbyt imponującą wiedza ale jeszcze niedawno nie znałem C kompletnie.

    Dorzuciłem kilka funkcji:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    0