Elektroda.pl
Elektroda.pl
X
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

[atmega8][c][winavr] odbiór kilku bajtów danych przez rs

puntigamer 29 Jul 2009 14:10 2250 11
  • #1
    puntigamer
    Level 13  
    Siema
    Wiem, że uart atmegi8 ma 3 bajtowybufor odbioru.
    Czyli jeśli wyślę 3 bajty do qC to będę mógł na raz odebrać je za pomocą instrukcji np
    double dana = UDR;
    ?
    Lub jak to zrobić najlepiej?

    Bo chodzi mi o to, aby potem z tej danej wyłuskać informacje zapisane na określonych bitach. Np 3 pierwsze bity to nr_serwa, 10 następnych to pozycja, itp.

    pozdrawiam
  • #3
    puntigamer
    Level 13  
    Dobra... Twój program po umieszczeniu znaku w buforze leci do przerwania i zapisuje znaki po kolei w tablicy. Funkcja unsigned char uart_getc (void) pobiera te znaki z tablicy cyklicznie :)

    Wynika z tego, że całego buforu zapisać do zmiennej int nie można, tak? Trzeba to robić bajtami. Dobrze rozumiem?

    Bo mój problem jest tego rodzaju, że te 3 bajtysą tak jakby całością w której mam ważne informacje zapisane na polach bitowych. I dopiero po odebraniu wszystkich 3 muszę zająć się "odcedzaniem" informacji. Ta reszta, która dostaje się do bufora mnie na razie nie interesuje. Powiedzmy, że qC dostaje tylko jednorazowo 3 bajty.

    Jak te 3 bity zapisać znowu jako "jedność"?

    Już mam pomysł aby wykorzystać unie jak w poście https://www.elektroda.pl/rtvforum/topic1381689.html. A dokładnie:

    
    serwo[8];
    
    struct slowo
    {
    insigned int synchro : 8;
    unsigned int polozenie : 10;
    unsigned int  :3 ;
    unsigned int nr_serwomechanizmu : 3;
    };
    
    struct bajty
    {
    insigned int bajt1 : 8;
    unsigned int bajt2: 8;
    unsigned int bajt3  :8;
    };
    
    union
    {
    slowo sl;
    bajty bj;
    };


    i to wrzucić do unii abym mógł odwoływać się do tego jako do bajtów (które przecież dostanę z rs'a), oraz jako innych, znanych mi pól bitowych z różnymi informacjami

    Będę mógł zapisać coś takiego (oczywiście nie tak banalnie):
    bj.bajt1 = UDR;  //czy takim sposobem pobiorę 3 bajty danych z bufora przyjmując, że one tam są?
    bj.bajt2 = UDR;
    bj.bajt3 = UDR;    //teraz bufor jest juz pusty


    a potem wyłuskać:
    serwo[sl.nr_serwomechanizmu] = sl.polozenie;
    


    Tylko, że kurczę w winavr tak zdefiniować unii nie mogę :(, wrzucić struktury w ciało unii?
  • #4
    Freddie Chopin
    MCUs specialist
    Najpierw musisz poczytać o składni C, to wtedy bedziesz mógł tak zadeklarować unię. Gwarantuję ci, że ani na AVR, ani na ARM, ani na PC taka deklaracja nie będzie działać.

    Potem musisz przeszukać forum, bo temat taki był poruszany conajmniej raz i padła już odpowiedź conajmniej raz. Wiem o tym, bo sam jej udzieliłem. Nie było to też 100 lat temu, że nie da się tego teraz znaleźć.

    EDIT: Nawet będę taki miły: https://www.elektroda.pl/rtvforum/topic1310189.html

    4/3!!
  • #5
    puntigamer
    Level 13  
    Widzisz. Robię to zgodnie z książką do C++ i nie wiem czego ubogie C nie potrafi pojąć. Problem jest z anonimowością unii czy dać konkretny obiekt tej unii i będzie ok?

    union skarbiec
    {
    struct slowo
    {
    unsigned int synchro : 8;
    unsigned int polozenie : 10;
    unsigned int  :3 ;
    unsigned int nr_serwomechanizmu : 3;
    };
    
    struct bajty
    {
    unsigned int bajt1 : 8;
    unsigned int bajt2: 8;
    unsigned int bajt3  :8;
    };
    
    };


    Zresztą to jest odrębna sprawa. Ciekawi mnie jak odczytywane są bajty z bufora. Czy tak jak użyłem w trzecim poście? Bo zapis do struktury jest możliwy (nie wnikając, żę napisałem ją w C++)
  • #6
    Freddie Chopin
    MCUs specialist
    Skoro robisz coś w C, to chyba powinieneś czytać książki o C, a nie o C++. Jest wiele rzeczy które można zrobić w C++ a nie można w C - dziedziczenie, przeładowanie, enkapsulacja, klasy, metody... Dlatego C++ to nie jest C.

    To co zdefiniowałeś jest kiepskie nawet w C++ i nie wiem co to by niby miało być. Unia która nic nie zawiera... Uwierz - to że masz tam literki nie znaczy, że zadeklarowałeś tak naprawde cokolwiek zajmujacego pamięć.

    Napisanie class Klasa {...}; też nie rezerwuje pamięci, tak samo jak pisanie struct Struktura {...}.

    4\/3!!
  • #7
    puntigamer
    Level 13  
    to co wyżej napisałem to definicja.
    w c napisać program na procka trzeba (niestety).

    void spi_send_float(float f) {
        union {
            float f;
            uint8_t u8[sizeof(float)];
        } temp;
        unsigned i;
    
        temp.f = f;
        for (i = 0; i < sizeof(temp); ++i)
            spi_send(temp.u8[i]);
    }


    czym się różni moja unia od tej np? tym, że ja po prostu na razie nie podałem dalszej części? pytam jak zdefiniować strukturę w unii, bo po obiektowemu nie można.

    Dzięki Freddie Chopinza tamtego linka do tematu

    pzdr
  • #8
    Freddie Chopin
    MCUs specialist
    przyjrzyj się jak:

    tutaj masz:

    union {
    typ NAZWA;
    typ NAZWA;
    } NAZWA;

    a ty chcesz:
    union {
    typ;
    typ;
    };

    chyba czegoś tu brakuje.

    Pozatym nie wiem czemu uparłeś się na unie, wcale nie jest to najlepsze rozwiązanie jakie istnieje. Najlepsze z podanych to funkcja przyjmująca wskaźnik void* i rozmiar danych wskazywanych przez owy wskaźnik.

    Programu wcale nie trzeba pisać w C, możesz sobie go napisać w czym chcesz, włącznie z C++, choć to co napisałeś powyżej jest też błędne w C++, więc żadna różnica pod tym względem.

    4\/3!!
  • #9
    puntigamer
    Level 13  
    u mnie zamiast typ nazwa (float f) jest struktura czyli typ złożony. a nazwa za nawiasem jedynie definiuje konkretny egzemplarz obiektu tej unii. coś pominąłem?

    dlaczego to co napisałem w moim 2 poście odnośnie C++ jest błędne?
  • #10
    Freddie Chopin
    MCUs specialist
    puntigamer wrote:
    u mnie zamiast typ nazwa (float f) jest struktura czyli typ złożony. a nazwa za nawiasem jedynie definiuje konkretny egzemplarz obiektu tej unii. coś pominąłem?

    No i niby gdzie masz tą nazwe? Bo jakbym nie patrzał, to jej tam nie widzę...

    Quote:
    dlaczego to co napisałem w moim 2 poście odnośnie C++ jest błędne?

    W twoim drugim poście nie ma słowa o C++

    4\/3!!
  • #11
    puntigamer
    Level 13  
    Dobra. Wszystko super. Powiedz mi, jeśli masz pomysł jak spakować te informacje w sposób abym później mógł wysłać to porcjami po 1 bajcie (i w qC rozkodować). Bo z wysłaniem kilku bajtów sobie już poradzę, ale do tej pory zmienną int (4bajty) wpisywałem ręcznie.