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

[ATMEGA32][avrgcc] zapis i odczyt EEPROM

pmmisiek 16 Wrz 2008 23:13 12265 17
  • #1 5542330
    pmmisiek
    Poziom 15  
    Witam.

    Jak zapisuje się dane do eeprom w avrgcc?

    W bascomie wystarczyło zadeklarować zmienną jako zmienna typu ERAM, później zapis w programie wyglądał tak:
    zmienna_eeprom = zmienna
    analogicznie odczyt:
    zmienna=zmienna_eeprom

    Czy da się posługiwać zmiennymi tak jak powyżej w avrgcc?
    Wiem, że można użyć min.:
    eeprom_write_byte ( *adres, val) - zapisuje wartość val pod adres adres.
    eeprom_read_byte ( *adres ) - czyta zawartość pamięci spod adresu adres.

    ale w tym przypadku trzega samemu pilnować adresów pod którymi zapisuje się zmienne.

    W avrgcc zadeklarowanie zmiennej EEMEM a następnie posługiwanie się nią jak w bascomie nie działa.

    Proszę o opis najprostszej metody na zapisanie w trakcie działania programu zmiennej do EEPROMu.

    Pozdrawiam.
  • Pomocny post
    #2 5542459
    Dr.Vee
    VIP Zasłużony dla elektroda
    Witam,

    
    #include <stdint.h>
    #include <avr/eeprom.h>
    
    static EEMEM uint8_t zmienna_w_eepromie = 'a';
    /* po zaprogramowaniu eepromu zmienna ma wartość 'a' */
    
    int main(void)
    {
        eeprom_write_byte(&zmienna_w_eepromie, 'b');
    }
    


    Pozdrawiam,
    Dr.Vee
  • #3 5542485
    pmmisiek
    Poziom 15  
    Właśnie o to mi chodziło, dzięki.

    Napisz jeszcze jak odczytać później tą zmienną.

    Pozdrawiam.
  • #4 5542487
    Dr.Vee
    VIP Zasłużony dla elektroda
    Chyba przez podobieństwo funkcji powinieneś sam na to wpaść ;)

    uint8_t zmienna = eeprom_read_byte(&zmienna_w_eepromie);
    


    Jeszcze dla uściślenia dlaczego to działa - operator & (ampersand) zwraca adres zmiennej, a dzięki atrybutowi EEMEM kompilator wie, że chodzi o adres w eepromie, a nie w RAMie.

    Pozdrawiam,
    Dr.Vee
  • #5 5562348
    pmmisiek
    Poziom 15  
    Czy wszystko jest ok w poniższym kodzie:?

    deklaracja zmiennych:

    uint8_t l_minimow;
    uint8_t minimum[35];

    static EEMEM uint8_t l_minimow_ee;
    static EEMEM uint8_t minimum_ee[35];

    //zapis minimow:
    eeprom_write_byte(&l_minimow_ee, l_minimow);

    //odczyt minimow:
    l_minimow=eeprom_read_byte(&l_minimow_ee);

    //zapis w pętli:

    eeprom_write_byte(&minimum_ee[j], minimum[j]);

    //odczyt w pętli:

    minimum[j]=eeprom_read_byte(&minimum_ee[j]);


    Czy można tak postępować z tablicami?

    Pozdrawiam.
  • #6 5562417
    Dr.Vee
    VIP Zasłużony dla elektroda
    Kod jest w porządku (no może oprócz tego, że nie użyłeś znaczników [ code ] ;) )

    Mógłbyś zamiast pętli użyć funkcji:
    eeprom_read_block(minimum, minimum_ee, 35);
    eeprom_write_block(minimum_ee, minimum, 35);

    Jak widać, te dwie funkcje są bardzo wygodne do odczytu i zapisu tablic. Więcej szczegółów w dokumentacji avr-libc.

    Jeszcze żeby uprzedzić ewentualne pytanie - w języku C dla tablic zawsze jest spełnione:
    minimum == &minimum[0]

    Pozdrawiam,
    Dr.Vee
  • #7 5568458
    pmmisiek
    Poziom 15  
    Powyższego kodu używam w dłuższym programie (nie zamieszczam tutaj bo straszny bałagan mam w kodzie), zapis i odczyt nie działają poprawnie, z kolei testowałem ten kod w oddzielnym małym programiku i działa.

    Czytałem gdzieś, żeby w obszerniejszych programach do zapisu/odczytu zmiennych w eepromie stosować struktury. Czy kolega Dr. Vee (lub ktokolwiek inny) wie jak zapisuje/odczytuje się przykładową strukturę której elementami są tablice?

    Ps. Długość tablicy jest zdefiniowana wstępnie na [35] ale w zależności od danych pomiarowych zebranych w programie, tablica zapisana do eepromu może mieć mniejszą długość.

    Z góry dziękuję za pomoc.
    Pozdrawiam.
  • #8 5568966
    Dr.Vee
    VIP Zasłużony dla elektroda
    pmmisiek napisał:
    Powyższego kodu używam w dłuższym programie (nie zamieszczam tutaj bo straszny bałagan mam w kodzie), zapis i odczyt nie działają poprawnie, z kolei testowałem ten kod w oddzielnym małym programiku i działa.

    To znaczy, że coś robisz nie tak. Ostatnio był taki problem, zobacz ten temat.
    pmmisiek napisał:
    Czy kolega Dr. Vee (lub ktokolwiek inny) wie jak zapisuje/odczytuje się przykładową strukturę której elementami są tablice?

    Jeśli tablice mają stały rozmiar i w strukturze nie ma wskaźników, to można zrobić to np. tak:
    struct moja_struktura {
       uint8_t tablica1[5]; uint16_t tablica2[3]; /* i tak dalej */
    };
    
    static struct moja_struktura EEMEM ee_zmienna;
    static struct moja_struktura zmienna;
    
    void odczytaj(void) {
        eeprom_read_block(&zmienna, &ee_zmienna, sizeof(struct moja_struktura));
    }
    
    void zapisz(void) {
        eeprom_write_block(&ee_zmienna, &zmienna, sizeof(struct moja_struktura));
    }

    pmmisiek napisał:
    Ps. Długość tablicy jest zdefiniowana wstępnie na [35] ale w zależności od danych pomiarowych zebranych w programie, tablica zapisana do eepromu może mieć mniejszą długość.

    W takim razie albo musisz sam zapisać w strukturze ilość danych w tablicy i napisać własne funkcje zapisu/odczytu, albo pogodzić się ze zmarnowaniem pewnej ilości bajtów eepromu i zapisywać/odczytywać jak wyżej.

    Pozdrawiam,
    Dr.Vee
  • #9 7243406
    riddyk
    Poziom 20  
    Witam,

    mam pewien problem w jaki sposób zapisywać i odczytywać do pamięci EEPROM, zmienną typu double ?

    tak wygląda deklaracja zmiennej:

    static EEMEM double E_ax ; 


    odczyt:

    
    double ax;
    ax = eeprom_read_byte(&E_ax); 
    


    zapis:

    
    eeprom_write_byte(&E_ax, ax);
    


    przykładowe wartości ax:

    
    	ax=-0.00000047558118;
    	ax=0.00072714092;
    	ax=-0.5437692;
    	ax=310.9415814;	
    


    takich samych zmiennych mam 8 do zapisu.

    Coś mi zapisuje do pamięci EEPROM ale to nie jest to co bym chciał.

    Korzystam z WinAVR ( PN).
  • #10 7243445
    Dr.Vee
    VIP Zasłużony dla elektroda
    Użyj eeprom_read_block i eeprom_write_block.
  • #11 7244148
    tmf
    VIP Zasłużony dla elektroda
    Zmienna double zajmuje wiecej niz 1 bajt - dokladnie 4, a ty czytasz tylko 1 bajt. Nie ma prawa dzialac. Jak pisze Dr.Vee zainteresuj sie eeprom_read_block i eeprom_write_block, jako dlugosc bloku mozesz wykorzystac sizeof(double), albo sizeof(zmienna).
  • #12 7244844
    riddyk
    Poziom 20  
    A więc tak

    deklaruje poza mainem:

    static  EEMEM double E_ax ; 
    static double ax;
    


    odczyt:

    eeprom_read_block(&ax, &E_ax, sizeof(double)); 
    eeprom_busy_wait  	( );
    


    zapis:

    eeprom_write_block(&ax, &E_ax, sizeof(double)); 
    eeprom_busy_wait  	( );  	
    


    w ten sposób należy to wykonać z tym że w eeprom_write_block inaczej jak sugerują koledzy należy najpierw wpisać zmienną, a później zmienną w pamięci epprom:

    eeprom_write_block(&ax, &E_ax, sizeof(double));
  • #13 7356028
    wilk125
    Poziom 23  
    Witam
    Odświeżę temat

    Dr.Vee napisał:
    Chyba przez podobieństwo funkcji powinieneś sam na to wpaść ;)

    uint8_t zmienna = eeprom_read_byte(&zmienna_w_eepromie);
    


    Jeszcze dla uściślenia dlaczego to działa - operator & (ampersand) zwraca adres zmiennej, a dzięki atrybutowi EEMEM kompilator wie, że chodzi o adres w eepromie, a nie w RAMie.
    Dr.Vee

    A czy jesli zmienna nie była by typu EEMEM to zostala by zapisana w RAM? Czy sama funkcja eeprom_read_byte(..) nie powoduje zapisu do eeprom?
  • #14 7356037
    tmf
    VIP Zasłużony dla elektroda
    Gdyby zmienna byla w RAM to funkcja eeprom_read_byte() dostalaby nieprawidlowy adres, z ktorego mimo wszystko probowalaby odczytac z pamieci EEPROM, w efekcie otrzymalbys sieczke.
  • #15 7356125
    wilk125
    Poziom 23  
    A pod jakim adresem w eepromie bedzie sie znajdowac tak zadeklarowana zmienna
    static EEMEM uint8_t zmienna_w_eepromie ;
    Czy to będzie zawsze adres 0x0, w przypadku gdy jest to jedyna zmienna zadeklarowana w eepromie?

    Dodano po 17 [minuty]:

    chodzi mi o to że jak coś zapisze pod zmienna, później wyłączę mikrokontroler, następnie złlacze i odczytam wartość tej zmiennej, to czy zawsze ona będzie wskazywać ten sam adres w eeprom?
  • #17 7356254
    wilk125
    Poziom 23  
    jeszcce jedno pytanie czy taki zapis
    static EEMEM uint8_t zmienna_w_eepromie=0x10 ;

    spowoduje, że przy każdym uruchamianiu mikrokontrolera do eeprom bedzie zapisywana wartosc 0x10 czy tylko raz podczas programowania plikem *.epp?
REKLAMA