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

Dlaczego zapis do EEPROM na Atmega16 nie działa w AVR Studio?

futurenobel 29 Gru 2005 13:47 2540 10
REKLAMA
  • #1 2126283
    futurenobel
    Poziom 11  
    Posty: 20
    Ocena: 1
    Mam problem z zapisem danych do wewnętrznej pamięci EEPROM procesora Atmega16. Problem pojawia się już podczas symulacji w programie AVR Studio, więc pewnie wina leży po mojej stronie. Jednak do zapisu użyłem przykładowej funkcji z dokumentu atmelMega16complete.pdf ze strony Atmela, wcześniej niemal identyczną funkcję napisałem sam i w obu przypadkach zapis nie udaje się.
    Zapis do pamięci powinien odbyć sie po ustawieniu bitu EEMWE a następnie bitu EEWE w EECR. Z niewiadomych przyczyn komenda:
    EECR |= 1<<EEWE;
    nie działa.
    Czy ktoś miał już może podobny problem? Z góry dziękuję za pomoc.
  • REKLAMA
  • #2 2126335
    Samuraj
    Poziom 35  
    Posty: 2792
    Pomógł: 286
    Ocena: 619
    Ustaw w
    EEARL - adres
    EEDR - wartośc do wpisania
    w EECR ustaw bit EEMWE a potem natychmiast ustaw bit EEWE
    Pamiętaj ze ustawienie bitu EEWE powinno być zrobione w następnym cyklu zegara
    W przeciwnym wypadku EEMWE wyseruje się i dane sięnie zapiszą
  • REKLAMA
  • #3 2126360
    futurenobel
    Poziom 11  
    Posty: 20
    Ocena: 1
    Mój kod wygląda następująco:

    void writeEEPROM(byte* WriteBuffer, int Size){
    unsigned int WriteAddress = 0;
    byte El_Number = 0;

    EECR = 0; // EEPROM Control Register
    while(Size){ //Size - rozmiar tablicy do przeslania

    while(EECR & (1<<EEWE)) { asm volatile ("nop"::); } //Czekaj aż EEWE = 0;

    EEDR = WriteBuffer[El_Number++]; //Dane do wysłania, post-inkrementuj numer elementu
    EEAR = WriteAddress++ & 0x1FF; //Adres zapisu, max 511 (9 bitów)
    WriteAddress++; //inkrementuj WriteAddress
    EECR |= 1<<EEMWE; //Ustaw bit EEMWE w EECR (zezwolenie na zapis)
    EECR |= 1<<EEWE; //Ustaw bit EEWE (zapisz dane do EEPROM-u)

    Size--;
    }
    }

    Mam nadzieję że kod wyświetli się prawidłowo sformatowany. Ponadto EEWE powinno zostać zapisane w trakcie 4 cykli po ustawieniu EEMWE (nie natychmiast). Ale dziękuję.
  • Pomocny post
    #4 2126456
    genetix
    Poziom 24  
    Posty: 669
    Pomógł: 42
    a spróbuj, czy puści tak:
    EECR=(1<<EEMWE);
    EECR=((1<<EEMWE)|(1<<EEWE));

    a tak na marginesie, czemu 2x inkrementujesz WriteAddress ??
  • #5 2126473
    futurenobel
    Poziom 11  
    Posty: 20
    Ocena: 1
    WriteAddress oczywiście inkrementuję tylko raz (błąd przy wstawianiu).
    Bardzo dziękuję, teraz wszystko działa, co prawda dalej nie rozumiem czemu nie działało wcześniej, ale w tej chwili to najmniej istotne. Byćmoże po skompilowaniu odstęp między ustawieniem EEMWE i EEWE był większy niż 4 cykle, ale raczej nie, bo w AVR Studio wszystko, poza tym że nie działało, wyglądało ok. Pozdrawiam.
  • REKLAMA
  • #6 2894487
    djskomy
    Poziom 14  
    Posty: 104
    Pomógł: 4
    Ocena: 62
    To ciekawe ale mam identyczny przypadek.
    Bascom zapisywał poprawnie - czyli hardware ok.
    W C (avr-gcc) zgodnie z przykładem producenta nie szło nic zapisać, natomiast po poprawce jak wyżej śmiga... :|

    PS. Zmarnowałem na znalezienie rozwiązania dwie noce i pewnie myślałbym dalej nad tym, co jest nie tak gdyby nie ten post...

    Dzięki! :)
  • #7 3585613
    buajan
    Poziom 11  
    Posty: 16
    wyć mi się chce... tyle czasu nad tym spędziłem... eh! Ktoś może wytłumaczyć dlaczego akurat tak musi być??
    We wszystkich przypadkach działa przykładowo EECR|=(1<<EEMWE) dlaczego akurat teraz musi być bez tego plusa przed znakiem "="... czym różnią się te operacje?

    PS. Czy ktoś wie może czemu AVRStudio4 zawiesza mi się kiedy na samym początku dodaję:
    #include<avr/io.h>
    #include<avr/signal.h>
    #include<delay.h>
    #include<avr/eeprom.h>

    Kiedy tego ostatniego nie ma to śmiga jak marzenie. Między innymi dlatego nie mogłem użyc standardowych funkcji z WinAvr :(. Wersja WinAvr którą używam to 2006.04.21.
    Wielkie dzięki za odpowiedź :)
  • REKLAMA
  • #8 3586617
    genetix
    Poziom 24  
    Posty: 669
    Pomógł: 42
    buajan napisał:
    wyć mi się chce... tyle czasu nad tym spędziłem... eh! Ktoś może wytłumaczyć dlaczego akurat tak musi być??
    We wszystkich przypadkach działa przykładowo EECR|=(1<<EEMWE) dlaczego akurat teraz musi być bez tego plusa przed znakiem "="... czym różnią się te operacje?
    uuu, kolego, kłaniają się podstawy składni C.

    jak dasz EECR|=(1<<EEMWE) to zostanie zapalony bit EEMWE, bez modyfikacji reszty bajtu. Ponieważ przed operatrem przypisania ('=') masz operator sumy logicznej ('|');

    jak dasz EECR=(1<<EEMWE) to bajt EECR będzie zerami + 1 jedynka na pozycji EEMWE.

    Generalnie wyrażenie (a|=b) jest równoznaczne wyrażeniu a=(a|b)
    podobnie działają:
    a^=b
    a-=b
    a+=b
    a*=b
    a&=b
    a~=b

    jeśli chcesz 'zgasić' jakiś bit, piszesz tak:
    EECR&=~(1<<EEMWE);
    czyli wykonujesz AND na rejestrze EECR i zanegowanej wartości maski:
    1<<EEMWE to 0b00000100
    ~(1<<EEMWE) to 0b11111011

    operacja AND na bicie w rejestrze i bicie stałej =0 zwróci zero
    operacja AND na bibie w rejestrze i bicie stałej =1 nie zmieni wartości bitu.

    troche to zamotane, bo lepiej napisać:
    sbi EECR, EEMWE
    albo
    cbi EECR, EEMWE

    :D
  • #9 3586681
    buajan
    Poziom 11  
    Posty: 16
    Tak też mi się właśnie wydawało, bo tak też byłem tego nauczony. Wydawało mi się, że może jest jakiś jeszcze inny haczyk na to, którego nie znam. Jednak mimo, że, tak jak piszesz, a|=b jest równoznaczne a = a|b, to jednak w tym przypadku to pierwsze nie chciało działać... ciekawe czemu? :P
  • #10 3586719
    genetix
    Poziom 24  
    Posty: 669
    Pomógł: 42
    kompilator może inaczej interpretować:
    a|=1<<b; a inaczej:
    a|=(1<<b);
  • #11 3586755
    buajan
    Poziom 11  
    Posty: 16
    Na przyszłość sobie zapamiętam :) Jestem początkujący, więc czasami wszystkich haczyków nie znam :) ale człowiek na błędach się uczy :)
    Dzięki wielkie!!!
    A z tym zawieszaniem się to nie wiesz czemu tak jest?

Podsumowanie tematu

✨ Problem dotyczył zapisu danych do wewnętrznej pamięci EEPROM mikrokontrolera Atmega16 podczas symulacji w AVR Studio. Zapis wymaga ustawienia najpierw bitu EEMWE, a następnie bitu EEWE w rejestrze EECR. Kluczową kwestią było zachowanie odstępu czasowego między ustawieniem tych bitów – bit EEWE musi zostać ustawiony w ciągu 4 cykli zegara po EEMWE, inaczej zapis nie zostanie wykonany. Przykładowy kod pokazał, że bez odpowiedniego opóźnienia zapis nie działał. Dodatkowo zwrócono uwagę na poprawne użycie operatorów bitowych w C, gdzie operator |= ustawia bit bez kasowania pozostałych, a operator = nadpisuje cały rejestr. W dyskusji pojawiły się także problemy z kompilacją i zawieszaniem się AVR Studio przy dołączaniu standardowych bibliotek AVR, co utrudniało korzystanie z gotowych funkcji EEPROM. Ostatecznie poprawne ustawienie bitów i właściwa składnia operatorów bitowych rozwiązały problem zapisu EEPROM w symulacji AVR Studio.
Podsumowanie wygenerowane przez AI na podstawie treści dyskusji.
REKLAMA