Skocz do zawartości

Jak odczytać w C bajt z zmiennej INT ?


BlackJack

Pomocna odpowiedź

Jak w temacie. Chce z zmiennej typu Unsigned INT PWM; odczytać odpowiednio młodszy i starszy bajt do zmiennej unsigned char temp;

Myślałem nad wskażnikami, ale jestem ciekaw czy jest jakaś funkcja do tego, ewentualnie czy da się zadeklarować zmienne aby były pod konkretnym adresem w pamięci ?

Kodu na razie nie wklejam bo jest dla PICa, interesuje mnie na razie tylko metodyka wykonania takiej operacji w C.

Link do komentarza
Share on other sites

Kolega mówi o bajcie, więc raczej

u8 templow = u16 & 0xFF;

u8 temphigh = u16 >> 8;

A co do innego rozwiązania w C to możesz stworzyć unię (możesz stworzyć zmienną do której odwołujesz się na kilka sposobów np. zarówno jako do jednej liczby 16bitowej jak i do dwóch liczb 8 bitowych), więcej pod adresem http://pl.wikipedia.org/wiki/Unia_(programowanie)

  • Lubię! 1
Link do komentarza
Share on other sites

Czyli należało by zrobić coś takiego ?

struct{
 union{
  unsigned int Rej;
  unsigned char lo;
  unsigned char Hi;
 }
} PWM;
unsigned char temp;

Void main(void)
{ 
 PWM.Rej = 123;
 temp = PWM.Lo;
......
}

Link do komentarza
Share on other sites

Zarejestruj się lub zaloguj, aby ukryć tę reklamę.
Zarejestruj się lub zaloguj, aby ukryć tę reklamę.

jlcpcb.jpg

jlcpcb.jpg

Produkcja i montaż PCB - wybierz sprawdzone PCBWay!
   • Darmowe płytki dla studentów i projektów non-profit
   • Tylko 5$ za 10 prototypów PCB w 24 godziny
   • Usługa projektowania PCB na zlecenie
   • Montaż PCB od 30$ + bezpłatna dostawa i szablony
   • Darmowe narzędzie do podglądu plików Gerber
Zobacz również » Film z fabryki PCBWay

Z najmłodszym jest bardzo prosto poprzez rzutowanie:

unsigned int zmienna_int;
unsigned char bajt_L;

bajt_L = (unsigned char) zmienna_int;  //rzutowanie na unsigned char

i takie polecam jako najbardziej eleganckie i pewne dla każdego kompilatora.

Dla starszego bajtu wystarczy przesunięcie bitowe jak podał MirekCz. Razem więc bedziesz miał tak:

unsigned int zmienna_int;
unsigned char bajt_L;
unsigned char bajt_H;

zmienna_int = 56789;

bajt_L = (unsigned char) zmienna_int;
bajt_H = zmienna_int>>8;

Z młodszym wystarczy zrobić tak:

bajt_L = zmienna_int;

ale odradzam, bo może się to zemścić.

  • Lubię! 1
Link do komentarza
Share on other sites

Nie. Unia to taka struktura danych, w której kolejne elementy umieszczone są w tym samym miejscu pamięci, tzn wszystkie zaczynają się od tego samego adresu. Musisz zrobić unię dwóch składników: zmiennej typu int oraz struktury składającej się z dwóch zmiennych typu char. Wtedy oba "char-y" będą umieszczone w ramach struktury jeden po drugim i dopiero to zostanie wstawione w to samo miejsce co int.

EDIT: Ups, nie zdążyłem. To początkowe "Nie" dotyczy oczywiście postu BlackJacka.

EDIT2: Zamiast struktury dwóch char'ów może być oczywiście tablica 🙂 ale na pewno nie dwie osobne zmienne.

Link do komentarza
Share on other sites

Może jakiś przykład z tą unią ? Tzn. rozumiem o co ci chodzi tylko nie wiem jak to zapisać.

Pytam tak z ciekawości, może kiedyś się przyda do czegoś. Ogólnie porady Dondu i Mireczka się sprawdziły. Teraz mogę dalej pisać funkcję przypisującą wartość do PWMa dla PICa.

Ogólnie twórcy PICów, trochę zmaścili ten PWM, bo trzeba robić takie klocki trochę aby przypisać do niego dane o wypełnieniu.

Link do komentarza
Share on other sites

najlepiej wymieszać unię z polem bitowym

union liczba {
   struct {
       unsigned int starsze :8;
       unsigned int mlodsze :8;
   } rozbicie;
   unsigned int calosc;
} PWM;

Potem zapisujesz do

PWM.calosc=costam;

A czytasz

x=PWM.rozbicie.starsze;
y=PWM.rozbicie.mlodsze;
Link do komentarza
Share on other sites

Myślałem o tym sposobie:

union
{
 int two_bytes;
 struct
 {
   char lo_byte;
   char hi_byte;
 } char_access;
} pwm;
......
char a, b;
pwm.two_bytes = 2012;
a = pwm.char_access.lo_byte;
b = pwm.char_access.hi_byte;

albo o tym:

union
{
 int two_bytes;
 char arr[2];
} pwm;
....
char a, b;
pwm.two_bytes = 2012;
a = pwm.arr[0];
b = pwm.arr[1];

Powinno się korzystać raczej z odpowiednio zdefiniowanych struktur danych, "pasujących" jak najlepiej do samej postaci danych. Jeśli masz potrzebę traktowania pewnego pola pamięci na kilka sposobów i są do tego w języku odpowiednie mechanizmy (a są), to z nich korzystaj. Unia int'a i struktury lub inta i tablicy char'ów lub też inta i pól bitowych jest właśnie taką reprezentacją. Operatory przesuwania niosą niebezpieczeństwo tego, że optymalizator nie wychwyci idei używania "starszego" bajtu i w kodzie będziesz wykonywał rzeczywiste przesunięcia. Mój stary AVRGCC "załapuje" kontekst, kod jest krótki i szybki ale kompilator do PICów - nie wiem.

Link do komentarza
Share on other sites

Ja bym z tymi strukturami i uniami bardzo uważał. To zależy od kompilatora i potrafi wysypać się bardzo niespodziewanie. Kiedyś miałem taką niespodziankę - ten sam program w nowszej wersji środowiska przestał działać. Wystarczyło, że optymalizator zaokrąglił wielkości pól do 32 bitów.

Jest jeszcze jedna opcja - wskaźniki.

Ale najbardziej polecam wersję z przesunięciami. Jest najpewniejsza.

Link do komentarza
Share on other sites

Dołącz do dyskusji, napisz odpowiedź!

Jeśli masz już konto to zaloguj się teraz, aby opublikować wiadomość jako Ty. Możesz też napisać teraz i zarejestrować się później.
Uwaga: wgrywanie zdjęć i załączników dostępne jest po zalogowaniu!

Anonim
Dołącz do dyskusji! Kliknij i zacznij pisać...

×   Wklejony jako tekst z formatowaniem.   Przywróć formatowanie

  Dozwolonych jest tylko 75 emoji.

×   Twój link będzie automatycznie osadzony.   Wyświetlać jako link

×   Twoja poprzednia zawartość została przywrócona.   Wyczyść edytor

×   Nie możesz wkleić zdjęć bezpośrednio. Prześlij lub wstaw obrazy z adresu URL.

×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.