Może na przykładzie:
https://elportal.pl/tasza/lxt/led_tree_avr.zip (
https://elportal.pl/index.php?module=Co ... y&ceid=145 )
led_tree.h pisze:
Kod: Zaznacz cały
typedef struct {
unsigned char b0: 1;
unsigned char b1: 1;
unsigned char b2: 1;
unsigned char b3: 1;
unsigned char b4: 1;
unsigned char b5: 1;
unsigned char b6: 1;
unsigned char b7: 1;
} TBits;
typedef union {
TBits bits;
unsigned char uchar;
} TByte;
Zdefiniowałam dwa typy danych:
TBits - pole bitowe (8 sztuk po 1 bit)
TByte - unia, która zapewnia dostęp do bajtu jako takiego (składnik uchar), lub
do jego poszczególnych bitów (składnik bits)
z tej unii (typ TByte) korzysta taka zabawna funkcja CorrctPcb(),
która służy do "prostowania ścieżek" na płytce - po prostu ścieżki poprowadziłam
jak leci, aby odpowiednie dane trafiały tam gdzie trzeba - należy je przepuścić właśnie
przez wspomnianą funkcyjkę....
led_tree.c pisze:Kod: Zaznacz cały
unsigned char CorrectPcb ( unsigned char b ) {
TByte o,i;
i.uchar = b;
// rewrite as is
o.bits.b7 = i.bits.b7;
o.bits.b6 = i.bits.b6;
o.bits.b5 = i.bits.b5;
o.bits.b4 = i.bits.b4;
// fix tracks ( see PCB layout )
o.bits.b3 = i.bits.b0;
o.bits.b2 = i.bits.b1;
o.bits.b1 = i.bits.b2;
o.bits.b0 = i.bits.b3;
return ( o.uchar );
}
Jak działa powyższa?
Dostaje na wejście jako parametr jeden bajcik (unsigned char)
Zapisuje go na chwilkę w zmiennej lokalnej i ( od input ), ale ponieważ
to unia i dostaje unsigned char - wpisujemy daną do pola 'uchar'
Potem wykonujemy przemieszanie bitów (najmłodszych) i przepisanie na wprost najstarszych
(to operacje na polach bits.b0....bits.b7 )
potem zwracamy wynik wyciągając do z drugiej zmiennej lokalnej o (od out).
To taki przykład....inne zastosowanie pól bitowych i unii...
wyobraź sobie, że chcesz w np. EEPROM zachowywać takie rekordy danych:
numer kanału (zakres 0..3), wartość z jakiegoś przetwornika A/C (0...63).
Pierwsze zajmie 2 bity, drugie - 6 bitów - razem 8 czyli bajcik
robimy tak:
Kod: Zaznacz cały
typedef struct {
unsigned char channelNum: 2;
unsigned char adcData : 6;
} TBits;
typedef union {
TBits bits;
unsigned char uchar;
} TByte;
możesz wtenczas zadeklarować sobie zmienną:
wypełnić jej pola przykładowo tak:
Kod: Zaznacz cały
dataRecord.bits.channelNum = 3;
dataRecord.bits.adcData = 29;
Zakładając, że masz funkcję do zapisu do EEPROM (czy gdziekolwiek) o takiej sygnaturze:
Kod: Zaznacz cały
void writeToEEprom (unsigned char address, unsigned char data);
wywołujesz ją np. tak:
Pytanka?
N.