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

Prośba o sprawdzenie kodu obliczeń pewnej funkcji

lukash90 09 Lis 2012 19:17 1050 5
  • #1 11509183
    lukash90
    Poziom 16  
    Witam, od jakiegoś czasu walczę z obsługą czujnika ciśnienia HP03s. Odczyt ciśnienia z niego polega na odczytaniu kilku parametrów z pamięci, dwóch wartości z przetwornika a następnie obliczeniu skomplikowanym wzorem.

    Poniżej przedstawiam kod fukncji obliczającej. W matlabie wychodzą prawidłowe wyniki, po symulacji samego kodu funckji w Visual Studio też wszystko ładnie a w ATmedze śmieci.
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod

    Przy czym wartości Cal[0..6] to odpowiednio C1..C7 ze wzoru. Wynoszą one u mnie:
    C1 = 15547;
    C2 = 3173;
    C3 = 260;
    C4 = 705;
    C5 = 33125;
    C6 = 5974;
    C7 = 2500;
    A = 7;
    B = 33;
    C = 6;
    D = 8;

    przykładowo dla wartości:
    D1 = 46542;
    D2 = 32871;

    powinienem wg matlaba oraz Visual Studio otrzymać takie wyniki:
    dUT =

    -256.0304


    OFF =

    1.2712e+004


    SENS =

    1.5482e+004


    X =

    2.4494e+004


    P =

    1.0154e+004

    niestety program wywala się przy obliczeniu SENS, X oraz P.

    Wzór z dokumentacji:
    Prośba o sprawdzenie kodu obliczeń pewnej funkcji

    To na pewno jest jakaś drobnostka, niedoaptrzenie moje albo coś. Bardzo proszę o pomoc.

    p.s wiem, że mógłbym wrzucić kod do AVRStudio i mieć bardziej wiarygodny symulator niż VS ale skompilowanie w nim czego kolwiek przerasta moje kompetencje
  • Pomocny post
    #2 11509351
    szulat
    Poziom 23  
    troszkę zajeżdża leniem, bo skoro już uruchamiasz w VS i na atmedze to wystarczy sprawdzać wyniki cząstkowe po każdej linii i będzie widać gdzie pojawia się różnica... ;)

    a przyczyną jest pewnie inny rozmiar inta, przy czym chodzi nie tylko o rozmiar zmiennych ale na przykład mnożenie dwóch 16 bitowych intów w AVR da wynik 16 bitowy, nawet jeżeli go potem wpisujesz do long int, bo wtedy już jest za późno.
    w takich sytuacjach potrzebujesz rzutowania na long lub unsigned long przed pomnożeniem.
  • #3 11509425
    lukash90
    Poziom 16  
    Tak tak, ja sobie zdaję z tego sprawę. Wyniki cząstkowe z ATmegi wyświetlam na wyświetlaczu i na chwile obecną dobrze jest tylko dUT obliczana. Reszta jest źle i wiem to. Wiem też że trzeba uważać na rozmiary zmiennych tylko nie wiem w którym momencie to przegapiłem w moim kodzie i o to właśnie proszę, o wskazanie gdzie gubię bity / przekraczam zakres
  • Pomocny post
    #4 11509475
    stanleysts
    Poziom 27  
    Przecież jak już wyświetlasz sobie dane na wyświetlaczu to lepszego debugera mieć nie będziesz. Możesz ograniczyć poszukiwania bo jak ci SENS nie działa to znaczy że tam może być jedyny błąd który się potem ciągnie.
    Kilka linijek do przeanalizowania...
  • #5 11509572
    szulat
    Poziom 23  
    lukash90 napisał:
    tylko nie wiem w którym momencie to przegapiłem w moim kodzie i o to właśnie proszę, o wskazanie gdzie gubię bity / przekraczam zakres

    prawie w każdym mnożeniu, zwłaszcza jeżeli tablica Cal[] też jest 16 bitowa.

    dUT ci się "cudem" uratowało bo tam jest przesunięcie przed pomnożeniem :) i mnożą się liczby tylko 9 bitowe, w innych miejscach wynik nawet jeżeli trafia do zmiennej 16 bitowej to po drodze jest 32 bitowy i dopiero potem przesuwany, i to właśnie jest miejsce gdzie kompilator avr utnie bity.

    możesz to wszystko zobaczyć na własne oczy rozbijając wyrażenia na pojedyncze operacje, nawet tylko w VS, i wyświetlać wartości.

    edit:
    hmm... widzę że próbowałeś tak robić? (zmienna tmp?)
    no i biorąc pierwszy z brzegu przykład, tmp=Cal[2]*dUT, mnożenie dwóch liczb 16bit, wynik przekracza 16 bit, jest obcinany a dopiero potem przesuwasz >>10 i wynik oczywiście nieprawidłowy.
    zamiast tego proponuję
    Kod: C / C++
    Zaloguj się, aby zobaczyć kod
  • #6 11509765
    lukash90
    Poziom 16  
    ok, kod już działa, dziękuję za podpowiedź z tym rzutowaniem, to był rzeczywiście powód
REKLAMA