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.

[ATmega32] - nieskończone wartości zmiennej float wysłane po RS

Rakieta1 06 Wrz 2013 17:01 1902 17
  • #1 06 Wrz 2013 17:01
    Rakieta1
    Poziom 8  

    Witam,

    Wysyłam zmienną float po RS-232 do Labview. Wygląda na to że po stronie Labview wszystko jest w porządku. Natomiast ATmega wysyła ostro przekłamane dane począwszy od 16-tej przesłanej porcji danych. Wcześniej, do 15-tej przesłanej liczby float składającej się z 4 bajtów wszystko jest w porządku.

    Kod: c
    Zaloguj się, aby zobaczyć kod


    funkcja transmitująca:
    Kod: c
    Zaloguj się, aby zobaczyć kod


    Mnie to śmierdzi przepełnieniem zarezerwowanych komórek pamięci.

    Dodałem coś takiego po transmisji czwartego bajtu:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    lub

    Kod: c
    Zaloguj się, aby zobaczyć kod


    i to wcale nic nie zmieniło.

    Czemu jest więc cały ten problem?

    Jako ciekawostkę dodam, że wysyłanie tej samej wartości stałej [np. liczby 12.34] przebiega bez problemu i dane nie są przekłamane.

    0 17
  • Pomocny post
    #2 06 Wrz 2013 17:09
    tmf
    Moderator Mikrokontrolery Projektowanie

    Dziwne, że w ogóle coś sensownego robi. Instrukcja:

    Kod: c
    Zaloguj się, aby zobaczyć kod

    powoduje przepełnienie pamięci SRAM, której masz tylko 2 kB, a ta tablica potrzebuje 4000 bajtów.

    0
  • #3 06 Wrz 2013 17:22
    Rakieta1
    Poziom 8  

    Usunięcie tablicy nie przyniosło oszołamiających efektów, choć poprawiło sytuację. Dane są wysyłane poprawnie do mniej więcej 32 czy 64-tej próbki, a ja chciałbym wysłać ich 255. Kolejne próbki po bodajże 64-tej znów są przekłamane.

    0
  • Pomocny post
    #4 06 Wrz 2013 17:32
    Tomasz Gumny
    Poziom 27  

    Rakieta1 napisał:
    Usunięcie tablicy nie przyniosło oszołamiających efektów, choć poprawiło sytuację. Dane są wysyłane poprawnie do mniej więcej 32 czy 64-tej próbki, a ja chciałbym wysłać ich 255. Kolejne próbki po bodajże 64-tej znów są przekłamane.
    Nie wiem w czym piszesz, ale dziwnie działasz na wskaźnikach/adresach. Poza tym rzutując na unsigned char ograniczyłeś adresowanie do 255, co przy 4 bajtach na float ogranicza adresowany obszar do 64 elementów.
    Jeśli chcesz rozłożyć float na bajty, to zrób po prostu unię jednej zmiennej float z char[size of float] i wstawiaj tam liczbę do wysłania.

    0
  • #5 06 Wrz 2013 18:33
    Rakieta1
    Poziom 8  

    Działam w Eclipse. Zrobiłem z unią:

    Kod: c
    Zaloguj się, aby zobaczyć kod


    I tak nie działa. Do chyba 64-tej przesłanej liczby działa, a później nie. Wprowadzenie unii nic nie zmieniło, ale dzięki za pomoc.

    0
  • Pomocny post
    #6 06 Wrz 2013 18:47
    Tomasz Gumny
    Poziom 27  

    Wstawiasz do liczba, a wysyłasz kolejno unia1.bajt[], to podstawienie unia2=unia1 jest zbędne.
    Pokaż cały program. Czy jak wyślesz więcej niż 64 stałe, to LabView działa?

    0
  • #7 06 Wrz 2013 19:04
    Rakieta1
    Poziom 8  

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Oto cały program. Labview działa bez zarzutu. Na wykresie w Labview pokazują się ogromne wartości, a w tzw. indykatorach pojawia się zamiast liczby słowo "Inf", które wiadomo co oznacza...

    0
  • Pomocny post
    #8 06 Wrz 2013 19:07
    krru
    Poziom 32  

    1. Pokaż trochę większe kawałki kodu, bo nie bardzo wiadomo co jest zmienną lokalną w funkcji, co parametrem, co globalną itp.
    2. Jak wygląda sprawa liczby wysłanych/odebranych bajtów? Nic się nie gubi - bo Atmega nadaje na max, nie wiadomo czy PC jest w stanie odebrać takie ilości danych dostatecznie szybko. Jaki masz bitrate? Może spróbuj nadawać wolniej.
    Spróbuj też nadać o 1 liczbę wiecej niż odbiera się poprawnie - czy odbierasz kompletną liczbę?

    0
  • Pomocny post
    #9 06 Wrz 2013 19:08
    tmf
    Moderator Mikrokontrolery Projektowanie
  • #10 06 Wrz 2013 19:11
    Rakieta1
    Poziom 8  

    krru - właśnie dałem cały kod. N. Wcześniej kiedy działało do 15-tej liczby, to wyglądało tak: odebranie 15-tej liczby dawało wynik 2.015[czyli dobry], zaś 17-tej dawało wynik 2.144 [przekłamany]. Teraz działa do 56-tej jak usunąłem tę tablicę.

    0
  • Pomocny post
    #11 06 Wrz 2013 19:12
    tmf
    Moderator Mikrokontrolery Projektowanie

    Tomasz Gumny napisał:
    Rakieta1 napisał:
    Usunięcie tablicy nie przyniosło oszołamiających efektów, choć poprawiło sytuację. Dane są wysyłane poprawnie do mniej więcej 32 czy 64-tej próbki, a ja chciałbym wysłać ich 255. Kolejne próbki po bodajże 64-tej znów są przekłamane.
    Nie wiem w czym piszesz, ale dziwnie działasz na wskaźnikach/adresach. Poza tym rzutując na unsigned char ograniczyłeś adresowanie do 255, co przy 4 bajtach na float ogranicza adresowany obszar do 64 elementów.
    Jeśli chcesz rozłożyć float na bajty, to zrób po prostu unię jednej zmiennej float z char[size of float] i wstawiaj tam liczbę do wysłania.


    Z tym rzutowaniem nie masz racji. On nie rzutuje wartości tablicy na unsigned char, tylko stosuje wskaźnik na typ unsigned char, a to zupełnie coś innego. Wskaźnik na AVR ze swej natury jest 16-bitowy (lub 24-bitowy) i o żadnym ograniczeniu adresacji mowy nie ma. Także unsigned char *ptr=&tablica[i] jest zupełnie poprawne i kolejne dereferencje *ptr++ zwracają kolejne bajty składające się na float. Także użycie unii nie jest potrzebne, ale nie jest też błędem.

    0
  • #12 06 Wrz 2013 19:14
    BlueDraco
    Specjalista - Mikrokontrolery

    Jeszcze sformatuj ten kod sensownie, żeby było widać jego strukturę i wyrzuć bezsensowne goto.

    0
  • #13 06 Wrz 2013 19:17
    Rakieta1
    Poziom 8  

    Kod: c
    Zaloguj się, aby zobaczyć kod


    Oto ładnie sformatowany kod. Goto musi być bo niejako wysyłanie danych musi się synchronizować z pewnym "działaniami" Labview. Celem tego programu jest obliczanie na ATmedze pewnej funkcji f(t) i wysyłanie danych do wykresu w Labview.

    0
  • Pomocny post
    #14 06 Wrz 2013 19:22
    BlueDraco
    Specjalista - Mikrokontrolery

    Tego się nie daje czytać. Wyrzuć puste linie pomiędzy kolejnymi instrukcjami w procedurach, zrób poprawne wcięcia.

    0
  • #15 06 Wrz 2013 19:40
    tmf
    Moderator Mikrokontrolery Projektowanie

    Wywal to goto bo wygląda to co najmniej dziwnie. W ogóle zapomnij, że instrukcja goto istnieje. Napisz jakie obecnie otrzymujesz wartości, może to kogoś nakieruje na problem. No i zawsze możesz ten kod zasymulować w Atmel Studio i sprawdzić kiedy i w jakich okolicznościach problem się pojawia. Weź też pod uwagę, że operujesz na 32-bitowych floatach, operacja x*0,001 nie zawsze da ci spodziewany efekt, ze względu na błędy skończonej reprezentacji typu float.

    0
  • #16 06 Wrz 2013 19:45
    BlueDraco
    Specjalista - Mikrokontrolery

    Wypadałoby zauważyć, że w tej sytuacji liczenie czegokolwiek w zmiennym przecinku na ATmega to grube nieporozumienie - lepiej wysłać dane całkowitoliczbowe do PC, który w nanosekundę policzy to, na co ATmega potrzebuje przynajmniej paru milisekund.

    0
  • #17 06 Wrz 2013 20:06
    Tomasz Gumny
    Poziom 27  

    tmf napisał:
    Z tym rzutowaniem nie masz racji. On nie rzutuje wartości tablicy na unsigned char, tylko stosuje wskaźnik na typ unsigned char [...]
    Oczywiście masz racje - umknęła mi gwiazdka.
    tmf napisał:
    Wywal to goto bo wygląda to co najmniej dziwnie. W ogóle zapomnij, że instrukcja goto istnieje.
    Z tym się niezupełnie zgodzę. Warto pamiętać, że istnieje, ale nie stosować. Pierwszy raz użyłem jej jakieś 5 lat temu, czyli po kilkunastu latach programowania. Z tej okazji musiałem sobie przypomnieć deklarację etykiety i składnię instrukcji. Za to od razu użyłem jej w kilkudziesięciu miejscach - do szybkiej obsługi błędu. Pech chciał, że udostępniłem źródła i... dostało mi się, oj dostało. :D

    0
  • #18 06 Wrz 2013 21:05
    94075
    Użytkownik usunął konto