82464 Image224 (3)

82464 Image224 (3)



Programowanie

Unię tworzymy tyczny sposób jak strukturę. zamiast słowa kluczowego struet używając słowa anion. Do poszczególnych pól unii dostajemy się tak samo jak do pól struktury- Zohac7 przykładowy listing w tej ramce. Na tym jednak podobieństwa się


ABC... C unia

Czym jest unia

w :den-


“ Nm

; - *

(...l

a c

l '3'

uie

>13

u32

57305565

— O

(...)

*

1 '3'

b

2 '31

H c

[0] l '3'

[1] 2 '31

[2] 3 '3'

tn * n-


|b«« d

[o»ioo

000100 01 02 03 04 TT TT .. .W

ś

000100 rr rr rr rr n rr yyrm

oooioc rr rr rr rr rr tr yym?

000112 rr rr rr rr rr rr ww

zi


kończą Unia umieszcza wszystkie swoje składowe elementy tak. ic norzystają cne zc wspólnego obszaru pamięci. Rozmiar całej unii równy jest rozmiarowi największego pola.

Częstym przeznaczeniem unii jest przechowywanie danych, o których wiemy, źc będziemy korzystać tylko z jednej z nich, a to z której, uzależnione jest od jakichś zdarzeń w programie. Jednak możliwości są szersze - w przykładowym programie w ramce za pomocą tablicy możemy dostać się do poszczególnych bajtów zmiennej 32-bitowej.


Rozmieszczenie danych w pamięci

Niektórych interesuje, jak dokładnie rozmieszczane są w pamięci dane znajdujące się w unii. Zamiast odpowiadać teoretycznie na to pytanie, proponuję Ci przeprowadzenie symulacji ba nalnego programu widocznego obok.

Po zakończeniu symulacji powinieneś otrzymać wynik widoczny na dołączonych obrazkach. Jednak aby dobrze zrozumieć sprawę, najle- }

piej zobaczyć, co się dzieje ze wszystkimi polami, krok po kroku, przy wpisywaniu kolejnych wartości do tablicy unii

Inicjacja unii

Jeśli zechcemy zainicjować unię początkową wartością, natkniemy się na pewien problem: standard pozwala nam na inicjację tylko pierwszego pola. Jest to sporym utrudnieniem, jeśli chcemy korzystać z unii


#include <inttypes.h>


union

{


char c;

ulncie z uint32 t struet {

char a

>5;

uint8 t t[4]


ui6; u32;


b:


int nain(void)

{

u.t[0] * 1 u.t[l] - 2 u.r[2] * 3 u.t[3] - 4

return 0;


umieszczonej w pamięci programu. Istnieją aktualnie dwie możliwości rozwiązania tego problemu:

1.    Jako pierwszy umieszczamy element największy

i podczas inicjacji zawsze dokonujemy rzutowania. Rozwiązanie to uia tę zaletę, żc jest zgodne zc standardem Jednak me zawsze możemy łatwo określić, który element jest nąjw iększy. Ponadto, samo rzutowanie czasami powoduje przekształ-    union

cenie danej - przykładowo    j

zrzutowanie wartości    int i;

zmiennoprzecinkowej na    float f;

całkowitą. W zapisie    }” "    {(int)l( :J

Dane w unii zostaną ustawione tak, że pole i przyjmie wartość 10, natomiast pole J będzie zupełnie inne od oczekiwanego.

2.    Drugie rozwiązanie wiąże się bezpośrednio z możliwościami, jakie daje AYR-GCC. Nasz kompilator umożliwia jawne podanie pola, które chcemy zainicjować:

Teraz uzyskamy dokładnie to, o co nam chodziło. Mimo tego, że korzystanie z tego zapisu może sprawić, że nasz kod stanie się nudniejszy do przeniesienia, jest na tyle wygodne, że warto z tego rozw iązania czasem skorzysta:.

Na stronie www umieszczam opisane programy przeznaczone do badania zachowania unii.

Przykład: listing 133


union

ł

i nt i.; float f;

}u - {.r-10.0};


l isting 141 - obsługa komunikatu OK oraz ESC w menu

case tdm_men:j_esc:

goto cleanupj case i DM_MEN'J_OK:

1

// Wczytanie do pamięci ram aktualnej pozycji menu

MENUITEM menuj

neroepy ?(4naenu, pnenu+iiideK-tcurpcs, sizeof(menu)); // Sprawdzenie z czym mamy do czynienia 1f (rrenu. type «= MENUT_POPUP)

sy3tem menu(nenu.data.pSubmenu); else if(rrenu.type MENUT_FUMC)

1

i f (rrenu. data. OnSelectProc !■ NULL)

1

if (menu .data .OnSelent.Proc(miirpos)) goto cleanupj

// Przywracanie parametrów które mogły

oy3tcra_lcbdSetRepeótSpccd(8) ;

system timerSet(0, SYSTEM TIMER MODEONE

0);

)

być zmienione CIIOT, 100,

1

break;


Listing 143 - funkcje, do których odnosi się menu 1 listingu 141

void app menuLightCraw(FILE* stream, uintlS t idNarr.e)

{

fprintf P(stream, langsys_GetText(idName), (int)oyotcn_LcdLightCct())»

}

uintu t app menuLight(uint8_t curpos)

{

(...)

return 0; // Nie kończ nenu

)

z dodatkowym opisem będzie można znaleźć na stronie Elportalu. Dzisiejszy opis starałem się prowadzić przede wszystkim tak, aby sama idea była jasna.

Listing 142 - menu z podmenu oraz wywołaniem funkcji

MENUITEM_P a?p_submer.u [] -

V

{MENUT FUNC, IDS Subl, system menuBaseDzaw,

{NULL}},

{menut FUNC, ids Sub2, system menuBaseoraw, (MENUT END, 0, NULL, {NULL}}

);

{NULL}},

MENUITEM_P app_nainmenu[] -1

(

(MENUT FUNC, IDS Light, app mcnuLięhtDraw,

(.OnSelectFroc«app menuLight}},

(MENUT PCPUP, IDS 2Suo, system nenuBaseCraw (...)"

, {(MENUITEM_P*)app_safcmenu}},


Zaproponowałem napisanie dużego programu, jednak jak miałem okazję pokazać pod koniec, programu ten sprawia, że rzeczy złożone stają się łatwe. Rozdzieliliśmy dość wyraźnie elementy aplikacji oraz czegoś, co można nazwać systemem. To duży krok naprzód.

Na stronie www zostanie także umieszczony bardziej rozbudowany przykład pracy z menu.

Na tym etapie skończymy zajmowanie się wyświetlaczem alfanumerycznym.

Radosław Koppel

radoslaw. koppcl@clportal.pl

89CXX 90SXX 74XX 40XX p|C AJ M£GA PCFXX DSXX

t mm©C30@[?oavp0oU)0

Elektronika dla Wszystkich Sierpień 2006 47


Wyszukiwarka

Podobne podstrony:
Image219 (3) Programowanie 1. Nie tworzymy komunikatu o kodzie 0 - ten kod został zarezerwowany do o
Image216 ProgramowanieKoniec pierwszej tury W ten oto sposób kończymy prostą obsługę wyświetlacza. N
Obraz40 równocześnie tekst programowany z tekstem konwencjonalnym. W ten sposób „wzbogacony" p
Image216 ProgramowanieKoniec pierwszej tury W ten oto sposób kończymy prostą obsługę wyświetlacza. N
Image245 Programowanie ABC... C Jak działają strumienie? Pamiętasz, jak do tej pcry obsługiwaliśmy n
Image272 licznika (rys. 4.304c) w taki sposób, żeby uzyskać prawie równomierny rozkład impulsów w cz
czyną jest nieprawidłowe naświetlenie (niewłaściwe żarzenie). W ten sposób, jak przy negatywie

więcej podobnych podstron