Elektroda.pl
Elektroda.pl
X
Proszę, dodaj wyjątek www.elektroda.pl do Adblock.
Dzięki temu, że oglądasz reklamy, wspierasz portal i użytkowników.

Problem ze wskaźnikami w C

achilles 07 Mar 2005 18:32 833 3
  • #1 07 Mar 2005 18:32
    achilles
    Poziom 15  

    Zapisuje sobie ramki przesyłane po RS485 w pamięci zewn SRAM współpracującej z ATmega162. Program pisze w WINAVR. Ze wzgledu na to że współdzielony jest obszar wewn i zewn pamięci SRAM, oraz moja zewn pamięc ma pojemność 0.5 MB to podzieliłem ją sobie na 16 stronic po 32 kB każda. Wewn i zewn pamięć rozdziełam bitem A15. W ten sposób aby wpisać cos do zewn pamięci adres musi być >= 0x8000.
    Nad adresem musze mieć stałą kontrole, bo gdy dojdzie do 0xffff to zwiększam stronicę o jeden a adres ustawiam spowrotem na 0x8000 itd.
    Tak się ma sprawa z danymi. Ramki rozdzielam poprzez zapisywanie adresu początku ramki w pamięci od końca. Ze zględu na to że adres pamięci jest 19 bitowy potrzebuje zapamiętać aż trzy bajty. I tu pojawia sie problem.
    4 najstarsze bity przechowuje sobie w zmiennej x, zapisuja ją do pamięci. Natomiast pozostała część adresu wskazywana jest przez wskażnik.
    Jak zapisać wartość wskażnika 16-bitowego w pamięci?
    Ja zrobiłem to w ten sposób ale nie jestem pewny swego rozwiązania:

    #define OFFSET_DOWN 0x8000
    #define OFFSET_UP 0xFFFF
    .........
    unsigned int *write = (unsigned int *) (OFFSET_DOWN);
    unsigned int *write_tab = (unsigned int *) (OFFSET_UP);
    .........
    unsigned int tempadres, temp16;
    unsigned char temp8;
    ......

    *write_tab=writePB; //writePB to 4 najstarsze bity adresu (wybór stronicy)
    *write_tab--;
    tempadres=(unsigned int)write; //write to wskaźnik przechowyjący 2 bajty adresu - A0:A14 (A15 rozdziela zewn i wewn pamięć)
    temp16=(tempadres&0xFF00);
    temp16=(temp16>>8);
    temp8=(unsigned char)temp16;
    *write_tab=temp8; //średni bajt adres
    *write_tab--;
    temp16=(tempadres&0x00FF);
    temp8=(unsigned char)temp16;
    *write_tab=temp8; //młodszy bajt adresu
    *write_tab--;
    .................

    Czy ja mogę sobie tak kopiować wskaźnik do jakiejś zmiennej?

    0 3
  • #2 08 Mar 2005 10:14
    achilles
    Poziom 15  

    Nikt nie ma pomysłu czy to jest dobrze a jeśli nie to jak powinno wyglądać?
    Generalnie chodzi mi o pozyskanie adresu do jakiejś zmiennej ze wskaźnika i podzieleniu go na dwa bajty. Czy mogę to zrobic w taki sposób jak pokazałem wyżej?

    0
  • #3 10 Mar 2005 00:24
    krzkomar
    Poziom 25  

    W "normalnym" C byłoby tak:

    /* wskaznik -jakiś wskaźnik */

    lsb = (unsigned int)wskaznik &0xff;
    msb = ((unsigned int)wskaznik >> 8) & 0xff;

    mozna też stworzyć sobie typ:

    np:
    typedef union{
    char *wsk;
    short int adres;
    struct{
    unsigned char lsb;
    unsigned char msb;
    };
    } wskaznik;

    wówczas np:

    wskaznik w;

    w.wsk - wskaznik
    w.adres - wartosc wskaznika
    w.lsb - mlodszy bajt wskaznika
    w.msb - starszy bajt

    na mikrokontrolery to nie wiem czy to będzie poprawnie działać - może to zależeć od kompilatora

    lsb i msb mogą być odwrotnie - zależy to od typu maszyny (Big czy Little Endian)

    0
  • #4 10 Mar 2005 09:21
    fantom
    Poziom 31  

    Co ma wedlug ciebie znaczyc linijka *write_tab-- ? Oznacza to ze chcesz zmniejszyc wskaznik o 1 i odczytac spod tego nowego adresu bajt, ale do niczego go nie przyrownujesz lub przypisujesz ;-) aczkolwiek bledu to nie powoduje.Jesli chcesz tylko zmniejszyc wskaznik to wystarczy write_tab--.Generalnie mozna zrzutowac wskaznik do zmiennej tak jak robisz ale musisz wiedziec co robisz.

    0