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

Zapis i odczyt EEPROM w AT89S52 - kod C dla Keila

mradowski 10 Lis 2004 12:23 2301 13
REKLAMA
  • #1 974979
    mradowski
    Poziom 14  
    Posty: 176
    Pomógł: 4
    Ocena: 21
    Czy wie ktoś jak zapisać dane do pamięci eeprom, i jak je z niej odczytać?
    Chodzi mi o to iż mój program ma monitować stan jednej nużki i kiedy na nużce zniknie sygnał to ma zapisac dane do pamieci a jak się pojaw to ma je wczytać spowrotem. Zapisywanie trwa bardzo ułamek sekundy wiec kobry kondensatorek powinien chuba wystarczyć na to aż zmienna będzie zapisana.
    Proszę o kawałek kodu źródłowego w C pod Keila - procek AT89s52.
  • REKLAMA
  • #2 978876
    natalia.
    Poziom 14  
    Posty: 65
    Pomógł: 2
    A procek AT89S52 (ATMEL) ma własny EEPROM?
  • #3 981920
    mradowski
    Poziom 14  
    Posty: 176
    Pomógł: 4
    Ocena: 21
    Oto jest pytanie, nie wiem a nie ma? Hmm... myślałem że wszystkie ATMELE mają, ale AT89s52 jest z rodziny 8051 więc może nie mieć.
    Więc tak jak dołączyć EEPROM jak go obsłużyć programowo? jaki ma być bo ma zapamiętać mi jedną liczbę w zakresie (-40;40); jeśli ma ktoś pomysł jak to zrobić to proszę o pomoc.
  • REKLAMA
  • #4 982015
    Dexter77
    Poziom 28  
    Posty: 889
    Pomógł: 134
    Ocena: 19
    89S52 nie ma wlasnego eeproma.89S8252 maja wlasny eeprom. Jezeli koniecznie sie upierasz to mozesz sostawic jakis niewileki eeprom na SPI.
    Pozdro
    Dexter
  • #5 983772
    natalia.
    Poziom 14  
    Posty: 65
    Pomógł: 2
    Dexter77 napisał:
    ...mozesz sostawic jakis niewileki eeprom na SPI.

    Lub na I²C.
  • #6 986568
    mradowski
    Poziom 14  
    Posty: 176
    Pomógł: 4
    Ocena: 21
    oki mam już AT89S8252 tylko jak zapisać w C konkretnie w Keilu polecenie zapisania zmiennej do pamięci eeprom i odczytania jej?
    proszę o kawałek kodu źródłowego w C, C++.
  • #7 987042
    jj
    Poziom 19  
    Posty: 145
    Pomógł: 42
    Aby uzyskać dostęp do odczytu eeprom, trzeba ustawić bit EEMEN w rejestrze WMCON. Wtedy eeprom widziany jest jako pamięć xdata (adresy 0x0000-0x07ff), i odczyt odbywa się tak, jak zmiennych z przestrzeni xdata, np:
    
    xdata char eep_var;
    data char x;
    
    (...)
    WMCON |= 0x08;	//wybor pamieci EEPROM jako XDATA
    x = eep_var;
    


    Dodatkowo aby móc zapisać EEPROM, trzeba ustawić bit EEMWE w tymże rejestrze. Trzeba jednak pamiętać, że zapis do eeprom trwa znacznie dłużej, i tutaj nie ma już tak łatwo. Poniżej masz funkcje zapisujące wartości zmiennych char i int do eeprom i czekające na koniec zapisu.

    
    //=================================================================================//
    //funkcja sprawdajaca stan pamieci EEPROM
    //zwraca "1" gdy pamiec zajeta zapisem (bit RDY/!BSY rejestru WMCON = 0)
    char EE_busy(void)
    {
    	if (WMCON & 0x02)	return 0;
    	else			return 1;
    }
    //=================================================================================//
    //funkcja zapisujaca liczbe int do pamieci EEPROM pod podany adres
    void EEWriteInt(int dat, xdata int* addr)
    {
    	xdata char *ptr;
    
    	WMCON |= 0x18;		//ustaw bity EEMWE i EEMEN w rejestrze WMCON
    	ptr = (char xdata *)addr;
    	*ptr++ = (dat>>8);	
    	while (EE_busy());	//czekaj na koniec zapisu
    	*ptr = dat;
    	while (EE_busy());	//czekaj na koniec zapisu	
    	WMCON &= 0xef;		//zeruj bit EEMWE w rejestrze WMCON
    }
    //=================================================================================//
    //funkcja zapisujaca liczbe char do pamieci EEPROM pod podany adres
    void EEWriteChar(char dat, xdata char* addr)
    {
    	WMCON |= 0x18;		//ustaw bity EEMWE i EEMEN w rejestrze WMCON
    	*addr = dat;
    	while (EE_busy());	//czekaj na koniec zapisu	
    	WMCON &= 0xef;		//zeruj bit EEMWE w rejestrze WMCON
    }
    
  • REKLAMA
  • #8 994545
    mradowski
    Poziom 14  
    Posty: 176
    Pomógł: 4
    Ocena: 21
    Takie pytanie jeszcze, przy odczycie użyłeś zmiennej "x" a przy zapisie "dat" czy zamiast dat mogę użyć x????
    Jak to powinno wyglądać dla jednej zmiennej zapis i odczyt?
  • REKLAMA
  • #9 994573
    LordBlick
    VIP Zasłużony dla elektroda
    Posty: 5438
    Pomógł: 549
    Ocena: 69
    Jak najbardziej, tylko pamietać trzeba, że dat jest zmienną wewnętrzną i w każdej procedurce zapisu ma różną wielkość(raz int, a drugi raz char), więc bezpieczniej bedzie stworzyć dodatkową procedurkę odczytu w klamerkach... ;)
    //trzeba pamietać, że "*dat" jest tu wskaźnikiem, a nie samą zmienną
    void EEReadChar(char* dat, xdata char* addr)
    	{
    	WMCON |= 0x08;   //wybor pamieci EEPROM jako XDATA
    	 *dat =*addr;
    	}
    

    Pozdrawiam, LightI
  • #10 994804
    mradowski
    Poziom 14  
    Posty: 176
    Pomógł: 4
    Ocena: 21
    Hmm... Keil wykazuje mi błąd w tym miejscu:

    void EEWriteInt (char dat, xdata char* addr)
    {
    WMCON |= 0x18;
    *addr = dat;
    while (EE_busy());
    WMCON &= 0xef;
    }

    Tak jest:
    compiling test8.c...
    TEST8.C(30): error C141: syntax error near 'xdata'
    TEST8.C(33): error C202: 'addr': undefined identifier
    test8.c - 2 Error(s), 0 Warning(s).

    Napisz mi jak możesz tą procedurę zapisu i odczytu z jedną zmienną x,
    np.
    sbit Klawisz1 = P2^0;
    sbit Klawisz2 = P2^1;
    char Delta;
    while(1)
    {
    if (Klawisz1 == 0);
    {
    zapis Delta;
    }
    if (Klawisz2 == 0);
    {
    odczyt Delta;
    }
    Delta = (jakaś funkcja);
    }
  • #11 1004128
    jj
    Poziom 19  
    Posty: 145
    Pomógł: 42
    witam

    Program, z którego pochodzą przedstawione funkcje był pisany pod Raisonance, w Keil spróbuj zamiast
    xdata char* addr
    wpisać
    char xdata * addr
    Nie mam Keila, nie sprawdziłem tego w programie, ale patrząc w helpa myślę, że zadziała.

    Poniżej masz przykład przypisania zmiennej x (z przestrzeni data) wartości zmiennej eep_var (z xdata - eeprom) - bezpośrednio, oraz operacji odwrotnej - poprzez funkcję EEWriteChar.
    
    xdata char eep_var; 
    data char x; 
    
    (...) 
    WMCON |= 0x08;   //wybor pamieci EEPROM jako XDATA 
    
    //odczyt z pamięci eeprom 
    x = eep_var; 
    
    (...) 
    //zapis do pamięci eeprom
    EEWriteChar(x, &eep_var) ;
    
  • #12 1014076
    mradowski
    Poziom 14  
    Posty: 176
    Pomógł: 4
    Ocena: 21
    Trzeba jeszcze pamiętać o jednej sprawie a mianowicie wybór panieci:

    np. zapis:


    xdata char eep_var;
    data char x;

    char wskaznik()
    {
    if (WMCON & 0x02) return 0;
    else return 1;
    }

    void zapis()
    {
    WMCON |= 0x04; //wybór pamięci
    WMCON |= 0x08; //aktywacja
    WMCON |= 0x04; //zapis
    eep_var = x;
    while (wskaznik());
    WMCON |= 0xef; //zerowanie bitu
    }

    Pod Keilem działa wyśmienicie.
    POZDRAWIAM!!!!
  • #13 1014077
    mradowski
    Poziom 14  
    Posty: 176
    Pomógł: 4
    Ocena: 21
    Pardom,

    WMCON |= 0x10; //zapis

    teraz oki.
  • #14 2000826
    silacoriolisa
    Poziom 11  
    Posty: 14
    Witam,
    A moze ktoś ma pomysł jak zaadresować zmienne typu char oraz int w całym zakresie pamięci EEPROM (2048bajtów). Podane procedury realizuja tylko zakres 8 bitów (256). Więc jest się o co bić.
    Poza tym podane procedury realizują zapis zmiennej typu int w formacie "little -endian" natomiast obecnie aktualnym formatem dla kompilatorów Raisonance jest "big-endian".

    Pozrawiam

Podsumowanie tematu

LABEL_AI_GENERATED
Dyskusja dotyczy zapisu i odczytu pamięci EEPROM w mikrokontrolerze AT89S52 przy użyciu języka C w środowisku Keil. Okazało się, że AT89S52 nie posiada wbudowanej pamięci EEPROM, natomiast model AT89S8252 już tak. W przypadku braku wbudowanego EEPROM sugerowano zastosowanie zewnętrznej pamięci EEPROM komunikującej się przez SPI lub I²C. Podano przykładowe fragmenty kodu w C do obsługi EEPROM w AT89S8252, wykorzystujące rejestr WMCON do wyboru pamięci EEPROM jako przestrzeni xdata oraz do kontroli zapisu i odczytu. Omówiono konieczność ustawiania bitów EEMEN i EEMWE w WMCON oraz oczekiwania na zakończenie zapisu poprzez sprawdzanie bitu RDY/!BSY. Wskazano na różnice składniowe w Keil, gdzie deklaracja wskaźnika do xdata powinna mieć formę "char xdata * addr". Przedstawiono funkcje do zapisu i odczytu pojedynczej zmiennej typu char, a także omówiono kwestie związane z obsługą zmiennych typu int i adresowaniem całej przestrzeni EEPROM (2048 bajtów). Zwrócono uwagę na format zapisu int (little-endian vs big-endian) w różnych kompilatorach. Podano przykładową implementację monitorowania stanu przycisków (sbit) i zapisu/odczytu zmiennej Delta w EEPROM. Dyskusja zawiera praktyczne wskazówki dotyczące programowania pamięci EEPROM w mikrokontrolerach rodziny 8051 z wbudowanym EEPROM oraz obsługi zewnętrznych pamięci EEPROM.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA