Elektroda.pl
Elektroda.pl
X
Elektroda.pl
Please add exception to AdBlock for elektroda.pl.
If you watch the ads, you support portal and users.

AVR i odwieczny problem z EEPROM

02 Apr 2009 20:59 2743 6
  • Level 14  
    Ten temat pojawia się tu od czasu do czasu ale żadna z porad nie jest skuteczna w moim przypadku. Od paru godzin już męczę się z wpisaniem czegokolwiek pod EEPROM. I udało mi się to ale jedynie w asemblerze w którym mam już pewne doświadczenie. Próbowałem zarówno EEMEM jak i inne funkcje z nagłówka eeprom.h ale nic z tego.

    Najbardziej obiecujący lecz także niedziałający listing w C:

    Code:
    #include <avr/io.h>
    
    #include "config.h"
    #include <avr/eeprom.h>

    int main(void)
    {
    int bOFdat;
    int bOFdat1;
    unsigned char B1 = 0b00001111;
    unsigned char B2 = 0b01010101;
    unsigned int A1 = 0x03;
    unsigned int A2 = 0x02;

    EEPROM_write(A1,B1);
    EEPROM_write(A2,B2);

    bOFdat = EEPROM_read(A1);
    bOFdat1 = EEPROM_read(A2);
    }

    Gdzie plik config.h

    Code:
    void EEPROM_write (unsigned int uiAddres, unsigned char ucData)
    
    {
    while(EECR &(1<<EEWE));
    EEDR=ucData;
    EEAR=uiAddres;
    EECR=(1<<EEMWE);
    EECR=((1<<EEMWE)|(1<<EEWE));
    }

    unsigned char EEPROM_read(unsigned int uiAddress)
    {
    while(EECR & (1<<EERE));
    EEAR = uiAddress;
    EECR = (1<<EERE);
    return EEDR;
    }


    Po wywołaniu debugera daję na podgląd rejestrów EEPROM no i widzę że ładnie się rejestry przestawiają ale jak dochodzi do linijki:

    Code:
    EECR=((1<<EEMWE)|(1<<EEWE));


    To AVR Studiu za cholerę nie chce zmienić bitu EEWE. W asemblerze się wszystko udaje i bit zmienia swoją wartość ale w C nie chce. Dokładnie taka sama reakcja następuje kiedy program dochodzi do linijki:

    Code:
    EECR = (1<<EERE);


    I flaga nie chce zmienić wartości.

    Problem dotyczy tylko tych dwóch flag i niczego więcej. Czy to jakiś błąd AVR Studio ? No bo przecież wszystko robię dobrze.

    Na koniec dodam że stosowane funkcje eeprom.h kompilowały się bez błędów ale również nie działały i to nie ważne jaki ustawiłem parametr optymalizacji, próbowałem wszystkich.

    Pomóżcie bo możliwe że sam nie dam rady.

    Proszę umieszczać listingi programów w znacznikach "Code". [c_p]
  • Level 32  
    Testujesz tylko w symulatorze? Mnie osobiście funkcje z avr/eeprom.h działają dobrze.
  • Level 18  
    skoro programujesz w C to dlaczego robisz to w taki sposób jak w assemblerze? Przecież są gotowe funkcje które używasz nie martwiąc się jak to się dzieje wewnątrz.
    w skrócie:
    Code:
    //zapis:
    
    eeprom_busy_wait();
    eeprom_write_byte();
    eeprom_busy_wait();
    //odczyt:
    eeprom_busy_wait();
    eeprom_read_byte()
    eeprom_busy_wait();
  • MCUs specialist
    kaktus_c++ wrote:
    skoro programujesz w C to dlaczego robisz to w taki sposób jak w assemblerze? Przecież są gotowe funkcje które używasz nie martwiąc się jak to się dzieje wewnątrz.

    Gdyby wszyscy tak myśleli, to po pierwsze nie miałby kto tych funkcji napisać, a po drugie ogólnie nic by nie powstawało, bo przecież nie do wszystkiego są gotowce.

    4\/3!!
  • Level 26  
    To nie tak. Jak chcesz używać AVR Studio to musisz używać ich funkcji do zapisu / odczytu EEPROM-u. Funkcje kompilatora są napisane jako inline assembler i zapewniają, że opóźnienie między wystawieniem bitu Write Enable i zapisem (lub odczytem) będzie mniejsze niż 4 cykle. Jeżeli sam robisz taki zapis w C, to kompilator generuje ci więcej kodu i warunek nie jest już spełniony.
    Kiedyś też napotkałem ten problem, obszedłem go używając biblioteki eeprom.h z AVR studio. Po jakimś czasie pomyślałem, że nie spróbowałem pokombinować z ustawieniami optymalizacji, żeby uruchomić moje funkcje - być może wygenerowany kod byłby dość szybki żeby zadziałać. Jak masz ochotę, to możesz spróbować włączyć maksymalną optymalizację i zobaczyć, czy twoje funkcje nie zaczną działać. Ale po co wyważać otwarte drzwi... Bierzesz eeprom.h i wszystko OK. Aha, eeprom.h działa dobrze przy optymalizacji -0s. Przy innej nie sprawdzałem, nie wiem - ale może być różnie.
  • Level 23  
    Na 100% działają na mojej ATmega169p, optymalizacja -Os

    Code:

    void eeprom_write(unsigned int uiAddress, unsigned char ucData)
    {
       /* Wait for completion of previous write */
       while(EECR & (1<<EEWE));
       /* Set up address and Data Registers */
       EEAR = uiAddress;
       EEDR = ucData;
       /* Write logical one to EEMWE */
       EECR |= (1<<EEMWE);
       /* Start eeprom write by setting EEWE */
       EECR |= (1<<EEWE);
    }


    unsigned char eeprom_read(unsigned int uiAddress)
    {
       /* Wait for completion of previous write */
       while(EECR & (1<<EEWE));
       /* Set up address register */
       EEAR = uiAddress;
       /* Start eeprom read by writing EERE */
       EECR |= (1<<EERE);
       /* Return data from Data Register */
       return EEDR;
    }
  • Level 14  
    Przyszedłem właśnie do pracy i szykuję się na kolejne starcie z gcc-AVR i AVRStudio. Dzięki za niektóre posty bo podniosły mnie trochę na duchu. Wprawdzie próbowałem jak już napisałem, funkcji z eeprom.h ale wczoraj mogłem być już zmęczony i coś mi mogło umknąć.

    Co do pana który mówił że programuję C w asm. Jeśli zna się więcej niż jeden język programowania to czasem trudno nie używać starych nawyków. Zwłaszcza ze z wszystkich książek które do tej pory czytałem, wynika że nawet jak się zna C to w przypadku AVRów programowanie asm jest bardzo użyteczne. Jak programuję w C++ na von Neumanna to w ogóle nie muszę używać asm (ale to tak na marginesie).

    Dodano po 27 [minuty]:

    Słuchajcie, musiałem zrobić jakąś wyjątkowo lamowatą pomyłkę. Wszystko mi teraz działa bez mruknięcia. Predefiniowane funkcje i zdefiniowane funkcje. Przepraszam za zawracanie głowy, dla mnie temat jest zamknięty. Dziękuję za pomoc.