Elektroda.pl
Elektroda.pl
X

Search our partners

Find the latest content on electronic components. Datasheets.com
Elektroda.pl
Computer ControlsComputer Controls
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

[Stm32][Keil]EEprom i float

03 Oct 2011 11:40 2468 10
  • Level 17  
    Witam.
    Programując pod procesory avr miałem do dyspozycji pamięć eeprom i bez problemu mogłem magazynować dane zarówno int jak i float.
    Po przesiadce na cortex'y okazało się że nie ma tu eeprom i korzystać trzeba z jego emulacji. Chciałem do tego celu posłużyć się najlepiej jakimiś gotowymi przykładami więc znalazłem przykład ze strony "st" wszystko dobrze o ile posługuje sie typami int problem jest z plikami float . Czy jest jakiś sposób na zapisanie liczb z ułamkiem?
    Trendy 2021 w branży Internetu rzeczy [Webinar 02.07.2021, g.12.00]. Zarejestruj się za darmo
  • Computer ControlsComputer Controls
  • Helpful post
    Level 20  
    Jak już korzystasz z bibliotek ST to masz chociażby funkcje:
    Code:
    FLASH_Status FLASH_ProgramHalfWord(uint32_t Address, uint16_t Data)

    i
    Code:
    FLASH_Status FLASH_ProgramWord(uint32_t Address, uint32_t Data)


    Operując na wskaźnikach możesz tam zapisać zmienne dowolnego typu, czy całe struktury.
  • Computer ControlsComputer Controls
  • Level 17  
    Witam.
    Możliwość zapisu float do pamięci to tylko mała część większego projektu . Nie chciał bym też zbyt długo nad tym siedzieć tzn. pisać wszystko od początku. Więc biblioteki były by dla mnie dobrym rozwiązaniem ale przyznam szczerze że nawet nie wiem w tym momencie jak miałbym wykorzystać te funkcje. Domyślam się że nie wystarczy pozmieniać ich miejscami w ciałach funkcji "EE_ReadVariable", "EE_WriteVariable"?.
    A może są już gotowe biblioteki które to umożliwiają w sposób równie łatwy co te od st z dodatkiem obsługi typów float?
  • Helpful post
    Level 35  
    Ale... float to przecież bity w pamięci! To co one przedstawiają, powinno cię mało obchodzić, gdy chcesz to zapisać w pamięć nie ulotną...

    Jeśli float ma 4 bajty (a chyba ma), to wystarczy dobrać się do tych czterech bajtów intem...
    Code: C
    Log in, to see the code
  • Level 17  
    Próbowałem przetestować to rozwiązanie ale coś jest nie tak. Mianowicie gdy zostawiam odkomentowaną linie " *ple=(unsigned int)&ulamek;" nic się nie wyświetla natomiast po zakomentowaniu tej linii wszystko jest w porządku.Bez tego nie moge sprawdzić całości programu .
    Na razie funkcje zapisu i odczytu z eepromu operują na zmiennych 16 bit.

    Code: c
    Log in, to see the code



    Zmiana na :

    Code: c
    Log in, to see the code


    powoduje to że na wyświetlaczu znajduje sie wartośc po aktualizacji zmiennej czyli w tym wypadku 0;
    Czym jest to spowodowane?
  • Helpful post
    Level 35  
    Code: C
    Log in, to see the code


    Przy definicji unsigned int *ple=(unsigned int*)&ulamek; wszystko jest ok, bo to mówi mniej więcej tyle, co "postaw wskaźnik na unsigned int na adresie zmiennej ulamek".

    Jeśli tylko zadeklarowałeś 'ple' nie definiując go, to musisz zmienić wskaźnik (czyli samo ple), a nie to co pod nim jest (czyli *ple), i ten wskaźnik postawić na adresie zmiennej ułamek (czyli &ulamek).

    Dodatkowo, typy. &ulamek ma typ wskaźnika na float. Ty chcesz wskaźnik na float przypisać do wskaźnika na unsigned int, czyli musisz rzutować wskaźnik na float na wskaźnik na unsigned int:
    (unsigned int*)&ulamek
    Wynikiem tej operacji jest wskaźnik na unsigned int, pokazujący dokładnie na tą samą pamięć, którą zajmuje zmienna ułamek.
    Teraz dysponując wskaźnikiem (unsigned int *ple), możesz ten wskaźnik postawić na wyżej opisaną pamięć zajmowaną przez zmienną ulamek:
    ple=(unsigned int*)&ulamek

    Od tego momentu w 'ple' jest przechwywany adres zmiennej ulamek, a pod *ple widzisz zmienną ułamek, tyle, że bity są zinterpretowane jako unsigned int, a nie jako float...
  • Level 17  
    Troche się pogubiłem program pozmieniałem tak ale efekt ten sam co wcześniej czyli wartośc "0".

    Code: c
    Log in, to see the code




    W celu uproszczenia i tym samym wyeliminowania przypadkowych błędów okroiłem program efekt nadal ten sam 0.

    Code: c
    Log in, to see the code
  • Helpful post
    Level 35  
    Zupełnie naplątałeś...

    Po pierwsze, nie przejdzie *ple=99.1. Dlaczego? Bo 'ple' jest wskaźnikiem na unsigned int, więc kompilator nie będzie przypisywał ci wartości zmiennoprzecinkowych do typu całkowitego, więc otrzymujesz ekwiwalent przypisu *ple=99;...

    Po drugie, czy ty może dysponujesz debuggerem? Wypadałoby sprawdzić co dzieje się z pamięcią przydzieloną na zmienną 'ulamek', gdy ty zapisujesz tam liczbę 99...

    Po trzecie, co robi GUI_TEXT? Jeśteś w stanie podejrzeć pamięć zajmowaną przez tablicę 'txt'?

    Widać, że się pogubiłeś, bo nie rozumiesz wskaźników, a tylko wskaźniki pozwolą ci na osiągnięcie tego, co jest potrzebne.
    Czym są wskaźniki?

    Połuż sobie na biurku dwa elementy obok siebie: śrubkę i skrawek papieru. Przestrzeń twojego biurka, to pamięć.
    Efekt: na pustej przestrzeni biurka widzisz dwa oddzielne obiekty; czyli w pamięci widzisz dwie zmienne...
    Code:
    unsigned int a; 
    
    float ulamek;

    Teraz weź palec wskazujący
    Code:
    unsigned int *ple

    i skieruj go na śrubkę.
    Code:
    ple=&a;

    W tym momencie twój palec wskazujący wskazuje na śrubkę, czyli twój palec jest wskaźnikiem na jedną z zmiennych.

    Wyobraź sobie, że twój palec może wskazywać na dowolny obiekt w twoim pokoju, ale na co by nie wskazał, będzie widział tylko śrubki, tyle, że o różnych kształtach i kolorach. Twój monitor też jest śrubką...
    I to jest wskaźnik na typ. Skoro twój palec będzie zawsze wskazywać na śrubki, a ty go zmusisz, aby wskazywał na monitor, to palec zinterpretuje monitor jako śrubkę.
    Rozumiesz już?
    Teraz ten sam palec, który zawsze wskazuje na śrubki, skieruj na skrawek papieru.
    Code:
    ple=(unsigned int*)&ulamek;

    Co zobaczy palec? ŚRUBKĘ!, tyle, że trochę niekształtna i blada....

    Teraz: Twoje 'ple' jest wskaźnikiem na unsigned int. Jak palec na śrubkę. Gdzie byś nie kazał temu wskaźnikowi pokazywać, on zawsze będzie wskazywał na unsigned int, niezależnie, gdzie będzie wskazywał. Zgadzasz się?

    A teraz każ mu wskazywać w to samo miejsce, gdzie znajduje się zmienna 'ulamek' (tak jak palec wskazujący na śrubkę skierujesz na skrawek papieru).
    Code:
    ple=(unsigned int*)&ulamek;

    Czyli wskaźnik na unsigned int pokazuje na pamięć, w której tak naprawdę jest float (czyli palec wskazujący na śrubkę tak naprawde wskazuje na papier...)
    Więc ty poprzez wskaźnik 'ple' interpretujesz to, co jest pod adresem zajmowanym przez zmienną ulamek, jako unsigned int. (wskazujesz na papier narzucając sobie, że to jest śrubka).

    Do pamięci nieulotnej możesz zapisać tylko śrubkę (czyli unsigned int). Papieru już nie (czyli float). Teraz wystarczy, że zinterpretujesz papier jako śrubkę (czyli zinterpretujesz float jako unsigned int), i zapiszesz go....

    Przy odczycie występuje ten sam proces, tyle, że wstecz. Odczytujesz unsigned int (czyli śrubkę),i intepretujesz ją jako float...
  • Level 17  
    Dzieki za pomoc i wyjaśnienie.
    w końcu coś ruszyło zmienna _1 symuluje eeprom wszystko chodzi jak powinno .

    Code: c
    Log in, to see the code


    Teraz poważny problem z funkcjami bibliotecznymi zapisu i odczytu są napisane dla zmiennych 16 bitowych gdybym wiedział jak je pozmieniać by przystosować do pełnego INT był bym w domu .
  • Helpful post
    Level 35  
    ależ po co?

    Przecież...
    Code: C
    Log in, to see the code
  • Level 17  
    Wielkie dzięki.
    Musze posiedzieć nad wskaźnikami bo nie ogarniam ich jeszcze.
    Jeszcze raz dziękuje i pozdrawiam.