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



Teraz jest 28 mar 2024, o 17:23


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 ]
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 1 gość


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