logo elektroda
logo elektroda
X
logo elektroda
Adblock/uBlockOrigin/AdGuard mogą powodować znikanie niektórych postów z powodu nowej reguły.

AVR-GCC - Dziwna rzecz w konwersji liczb 16 bitowych na dwie 8bitowe

bisz 28 Sty 2014 14:47 1548 9
  • #1 13230929
    bisz
    Poziom 18  
    Witam, borykam się z dość dziwnym problemem, zwłaszcza jako już nie początkujący programista w języku C, do rzeczy:
    Mam zmienną 16bitową i zapisuję ją w pamięci a następnie odczytuję.
    Zauważyłem że liczba którą odczytuję jest mniejsza zawsze o stałą wartosć, równą wartości starszego bajtu liczby 16 bitowej... Może podam przykład kodu.
    Logika nakazywałaby zrobić to tak:


    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    W efekcie gdy potem w analogiczny sposób czytam buffer:


    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Liczba voltage[i] jest mniejsza o wartość równą buffer[3+2*i]. Co prawda problem rozwiązuje dodanie w instrukcji zapisywania do pamięci wartości buffer[3+i*2] ale jest to pewne oszustwo, a chciałbym wiedzieć czemu się tak dzieje ?
  • #2 13230997
    2P
    Poziom 20  
    (255 * a) nie jest równe (a << 8).
    Także sam zapis jest dość niebezpieczny - działa tylko dlatego, że 255 domyślnie jest wartością typu int (16 bit ze znakiem dla AVR). Raczej wykorzystaj jawne rzutowanie przed obliczeniem:
    returnCell.voltage[i] = 256U*((uint16_t)buffer[3+2*i])+buffer[4+2*i];

    Albo lepiej:
    returnCell.voltage[i] = (((uint16_t)buffer[3+2*i])<<8)+buffer[4+2*i];
  • #3 13231017
    bisz
    Poziom 18  
    Sęk w tym że problem leży już na poziomie pisania do pamięci bo pisałem debugi.

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod


    Drukując potem zawartość buffer'a już na tym poziomie jest ten błąd.
  • #4 13231045
    mmacura
    Poziom 18  
    Moim zdaniem odtwarzanie powinno wyglądać tak:

    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #5 13231107
    BlueDraco
    Specjalista - Mikrokontrolery
    Jeśli nie pokażesz deklaracji zmiennych, możesz tylko pytać wróżki.

    bufor powinien być typu uint8_t, a zmienna typu np. uint16_t. Wtedy wyrażenie
    x = buf[i] | (buf[i+1] << 8);

    musi dać dobry wynik.
  • #6 13231117
    bisz
    Poziom 18  
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #7 13231173
    Konto nie istnieje
    Poziom 1  
  • #8 13231174
    BlueDraco
    Specjalista - Mikrokontrolery
    Deklaracji Cell nie pokazałeś, a tylko tam może leżeć problem.

    Nie zwraca się struktur jako wartości funkcji - niepotrzebna strata czasu procesora wynikający z kopiowania danych - przekaż do funkcji adres struktura jako argument i niech funkcja wypełni tę strukturę.
  • #9 13231228
    Konto nie istnieje
    Poziom 1  
  • #10 13231476
    bisz
    Poziom 18  
    Zgadzam się co do zwracania wartości poprzez wskaźniki.
    Nie umiem za bardzo teraz wyjaśnić problemu, ponieważ okazało się, że wyniknął z mojej korekcji wcześniejszej na poziomie zapisu do pamięci, choć wtedy robiłem to na atmedze16 a teraz 32... W każdym razie już działa OK. nie mniej dziękuję za pomoc bo kilka błędów i tak znalazłem
REKLAMA