Skocz do zawartości

Jak odczytać w C bajt z zmiennej INT ?


Pomocna odpowiedź

Napisano

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.

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;
......
}

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

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.

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.

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;

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.

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.

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...