Kanał - ATNEL tech-forum
Wszystkie działy
Najnowsze wątki

KURS HOME ASSISTANT

Chcesz zautomatyzować swój dom bez skomplikowanego kodowania?
Zastanawiasz się nad wyborem sprzętu, oprogramowania i aplikacji?
Od czego zacząć przygodę z HA w 2025? Co będzie najlepsze na start?

Nasz kurs Home Assistant nauczy Cię krok po kroku, jak łatwo zautomatyzować swój dom i oszczędzić na rachunkach za prąd i ogrzewanie. Bez chmur, bez zbędnych abonamentów. Twoja przygoda z Home Assistant zaczyna się tutaj!

↓↓↓

    Szanujemy Twoją prywatność. Możesz wypisać się w dowolnym momencie.




    Teraz jest 19 maja 2025, o 02:58


    Strefa czasowa: UTC + 1





    Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 7 ] 
    Autor Wiadomość
    PostNapisane: 26 gru 2016, o 19:00 
    Offline
    Nowy

    Dołączył(a): 20 sty 2013
    Posty: 12
    Pomógł: 0

    Witam,

    Zapoznaję się aktualnie z treścią świeżo otrzymanej nowej książki - yellowbook'a. Zacząłem od początku i muszę przyznać że różne interesujące smaczki programistyczne szybko się pojawiły. Dotarłem do obsługi czujnika ciśnienia i temperatury BMP180. Oczywiście pobrałem sobie notę katalogową by samemu przyjrzeć się jak ten czujnik obsłużyć. No i podczas analizy pojawiła się pewna wątpliwość przy funkcjach pobierających temperaturę i ciśnienie. Pokażę na czym polega wątpliwość bez wpisywania kodu.
    Liczby 16 bitowe przekazywane są z czujnika w kolejności MSB i LSB czyli oczywiste jest że trzeba je skonwertować do little endian. Na początku obsługi czujnika pobierane są parametry kompensacyjne do tablicy np. uint8_t bmp[22]. Mamy więc po kolei:
    bmp[0] <- MSB parametru1
    bmp[1] <- LSB parametru1 itd dla kolejnych parametrów

    czyli proces konwersji 1-szego parametru na little endian wygląda tak że do bmp[1] przypisujemy wartość z bmp[0] a do bmp[0] przypisujemy wartość z bmp[1]. Czyli po konwersji mam
    bmp[0]=LSB parametru 1
    bmp[1]=MSB parametru 1

    I to jest zrozumiałe.

    Teraz pojawia się funkcja do odczytu temperatury. I znów mamy tablicę nazwijmy ją uint8_t temp[2] do której odczytywane są poszczególne bajty z fubckji odczytu TWI. Czyli wydaje się że te bajty będą wczytywane do bufora również w kolejności jak wyżej:
    temp[0] <- MSB temperatury
    temp[1] <- LSB temperatury

    W związku z tym konwersja do little endian powinna wg mnie wyglądać tak że przesuwamy LSB "w lewo" a MSB zostawiamy:
    temp[1]<<8 | temp[0] i wtedy mamy znów układ bajtów LSB MSB począwszy od nizszego adresu.
    W książce jest jednak inaczej, czyli tak jakby w temp[0] był LSB a w temp[1] MSB:
    temp[0]<<8 | temp[1]

    Gdzie popełniam błąd w rozumowaniu?

    Pozdrawiam



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 26 gru 2016, o 20:38 
    Offline
    Użytkownik

    Dołączył(a): 07 cze 2016
    Posty: 563
    Pomógł: 143

    kremir napisał(a):
    Gdzie popełniam błąd w rozumowaniu?

    Traktujesz zmienną 16-bitową jako tablicę bajtów.

    Przecież kiedy zadeklarujesz zmienną 16-bitową, to nie przypisujesz do niej bajtów w kolejności odpowiedniej do endianness, tylko wartość, czyli bajt MSB przesunięty o 8 bitów w lewo OR bajt LSB, lub inaczej MSB*256+LSB. Kiedy przypiszesz wartość do zmiennej, to już dalej kompilator dba o poprawną kolejność bajtów w pamięci, Ty nie musisz się o to martwić.

    Twój tok rozumowania byłby poprawny np. w przypadku unii tablicy bajtów i zmiennej 16-bitowej:
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 26 gru 2016, o 21:24 
    Offline
    Nowy

    Dołączył(a): 20 sty 2013
    Posty: 12
    Pomógł: 0

    Dzięki za odpowiedź. Twoje wyjaśnienie do mnie trafia, ale ... Ten przykład z unią (podobną unię zastosował Mirek w książce i potem zamieniał bajty miejscami) jest dla mnie zrozumiały. Ale potem już nie, dlatego że Mirek w dalszej części rozdziału, w opisie funkcji odczytu temperatury napisał
    Cytuj:
    Pamiętajmy jednak że tutaj także najpierw odczytywany jest starszy bajt słowa, a więc w ostatniej linijce szybko zamieniamy bajty miejscami...

    a ostatnia linijka wygląda tak (biorąc za przykład tablicę temp a nie nazwy zmiennych z książki):

    zmienna = (temp[0]<<8 | temp[1]);

    A tu nie ma zamiany bajtów miejscami tak jak to miało miejsce w przykładzie z unią.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 26 gru 2016, o 21:38 
    Offline
    Użytkownik

    Dołączył(a): 07 cze 2016
    Posty: 563
    Pomógł: 143

    kremir napisał(a):
    zmienna = (temp[0]<<8 | temp[1]);

    A tu nie ma zamiany bajtów miejscami tak jak to miało miejsce w przykładzie z unią.

    Jest, tylko tego nie widzisz.
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 26 gru 2016, o 22:09 
    Offline
    Nowy

    Dołączył(a): 20 sty 2013
    Posty: 12
    Pomógł: 0

    Nadal nie widzę :D bo jeśli jedna z operacji to zamiana bajtów to druga już nie.
    Cytuj:
    // zauważ taką zależność
    zmienna.wartosc = zmienna.bajt[1]<<8 | zmienna.bajt[0];
    zmienna.wartosc = temp[0]<<8 | temp[1];


    Przypadek pierwszy:
    zmienna.bajt[0] zawiera MSB odczytanego int'a, zmienna.bajt[1] zawiera LSB. Po zamianie zmienna.wartosc jest zapisana w kolejności LSB MSB, czyli tu jest zamiana.

    W drugim przypadku:
    temp[0] też zawiera MSB odczytanego int'a a temp[1] też zawiera LSB i zapisuję to w zmienna.wartosc jako zwykły int MSB LSB.
    Upieram się więc, że w drugim przypadku zamiany nie ma :) ale może to jest kwestia nazewnictwa? W każdym razie proces jest dla mnie jasny i za to dziękuję.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 27 gru 2016, o 10:21 
    Offline
    Użytkownik

    Dołączył(a): 07 cze 2016
    Posty: 563
    Pomógł: 143

    kremir napisał(a):
    andrews napisał(a):
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

    Przypadek pierwszy:
    zmienna.bajt[0] zawiera MSB odczytanego int'a, zmienna.bajt[1] zawiera LSB. Po zamianie zmienna.wartosc jest zapisana w kolejności LSB MSB, czyli tu jest zamiana.

    W drugim przypadku:
    temp[0] też zawiera MSB odczytanego int'a a temp[1] też zawiera LSB i zapisuję to w zmienna.wartosc jako zwykły int MSB LSB.

    Nie, nie. W pierwszym przypadku założyłem, że do elementów tablicy już zostały przypisane wartości bajtów w odpowiedniej kolejności, czyli:
    Składnia: [ Pobierz ] [ Ukryj ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

    Jeszcze inaczej, bez użycia unii:
    Składnia: [ Pobierz ] [ Ukryj ] [ Zaznacz wszystko ]
    język c
    Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    PostNapisane: 27 gru 2016, o 18:47 
    Offline
    Nowy

    Dołączył(a): 20 sty 2013
    Posty: 12
    Pomógł: 0

    Cytuj:
    W pierwszym przypadku założyłem, że do elementów tablicy już zostały przypisane wartości bajtów w odpowiedniej kolejności

    ale oczywiście tak nie było. Wyjściem do rozważań był kod z ksiązki.
    Własnie w kodzie z książki jest najpierw przyklad z odczytem danych do tablicy która jest zawarta w unii złożonej z tej zmiennej tablicowej (22 elementów 8-bitowych) i 11 liczb 16-bitowych a później już inny przykład z bezpośrednim przypisaniem odczytanych dwóch bajtów do zmiennej 16 bitowej.
    W pierwszym przypadku, jako że jest to unia to żeby poprawnie liczba 16 bitowa była zinterpretowana następuje zamiana bajtów tak że układają się w kolejności LSB i MSB. I po to ta unia została jak mniemam zastosowana aby łatwo to było zrobić na większej liczbie danych.
    W drugim przypadku zapisana liczba 16 bitowa ma zapisane bajty w kolejności MSB LSB bez zamiany.

    Twoje wyjaśnienia jak najbardziej mnie przekonują. Sam zresztą napisałeś:
    Składnia: [ Pobierz ] [ Ukryj ]
      Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.

    W unii muszę dbać o kolejność bajtów i dlatego zamieniam ją a przypisując bezpośrednio do zmiennej już nie. Zmyłką było dla mnie zdanie w książce, że przy przypisywaniu bezpośrednio do zmiennej 16-bitowej też
    Cytuj:
    szybko zamieniamy bajty miejscami


    Jeszcze raz dzięki za poświęcony czas



    Góra
     Zobacz profil  
    cytowanie selektywne  Cytuj  
    Wyświetl posty nie starsze niż:  Sortuj wg  
    Utwórz nowy wątek Odpowiedz w wątku  [ Posty: 7 ] 

    Strefa czasowa: UTC + 1


    Kto przegląda forum

    Użytkownicy przeglądający ten dział: Brak zidentyfikowanych użytkowników i 2 gości


    Nie możesz rozpoczynać nowych wątków
    Nie możesz odpowiadać w wątkach
    Nie możesz edytować swoich postów
    Nie możesz usuwać swoich postów
    Nie możesz dodawać załączników

    Szukaj:
    Skocz do:  
    cron
    Sitemap
    Technologię dostarcza phpBB® Forum Software © phpBB Group phpBB3.PL
    phpBB SEO