Różnice w sposobach zapisu wewnętrznych pamięci EEPROM AT89S8252 i T89C51RD2

Czasami zaczyna brakować pamięci na program puchnący wraz z wymaganiami klienta, który już nauczył się, że można od mikrokontrolera oczekiwać czegoś więcej i zaczynamy się rozglądać za mikrokontrolerami alternatywnymi. Czasami również jest konieczne zwiększenie szybkości wykonywania programu. Tak było i w moim wypadku: stanąłem przed obiema tymi kwestiami jednocześnie. Używałem AT89S8252 i kod wynikowy programu przekroczył rozmiar pamięci FLASH. Potrzebowałem mikrokontrolera o większej ilości pamięci lub zewnętrznej pamięci programu. Potrzebowałem również większej szybkości CPU, ponieważ niebezpiecznie rozrosły się funkcje realizowane w obsłudze przerwania jednego z Timer’ów.

Mój wybór padł na P89C51RD2, gdyż wiedziałem od kolegi, że model RD2 ma 2 kB wewnętrznej pamięci EEPROM (której to bardzo potrzebowałem do przechowywania danych), 6-taktową jednostkę CPU oraz 64 kB na program. Niestety, podczas zakupu nie uwzględniłem jednego, oczywistego faktu: kolega mówił o TEMIC’u, a ja kupiłem PHILIPS’a. Przecież RD2 to RD2! Okazało się, że są pomiędzy nimi różnice i że polegają one na przykład na braku pamięci EEPROM w produkcie firmy PHILIPS.
Oba mikrokontrolery mają możliwość zapisu własnej pamięci programu, ale to nie jest to samo. Podstawową różnicą jest liczba cykli zapisu: FLASH przeznaczony na kod programu można zapisać około 1000 razy, a EEPROM 100 tysięcy razy. Jest to istotna różnica, jeśli przechowywane dane często ulegają zmianie. Ponadto, aby zapisać pamięć programu trzeba posługiwać się funkcjami bootlader’a i zapisywać dane blokami. Nie jest to zbyt wygodne przy konstrukcji prostej, małej bazy danych bez bufora i systemu plików.
Dla odmiany przeniesienie programu z AT89S8252 do T89C51RD2 a następnie do AT89C51RD2 (Atmel) odbyło się „bezboleśnie”. Oprócz drobiazgów związanych z nastawami rejestrów konfiguracyjnych, jedyna, najważniejsza różnica, polegała na obsłudze zapisu i odczytu danych w wewnętrznej pamięci EEPROM. RD2 TEMIC’a czy ATMEL’a ma jej tyle samo, co AT89S8252, czyli 2 kB. Funkcje obsługi pamięci EEPROM, wraz z przykładami ich użycia w języku C, prezentują poniższe listingi. Dosyć jest dodać, że sprawują się bez zarzutu.

Jacek Bogusz
j.bogusz@easy-soft.net.pl
 

Listing 1. Podstawowe funkcje obsługi pamięci EEPROM mikrokontrolera AT89S8252

//*************************************
// AT89S8252, obsługa pamięci EEPROM
//*************************************
pdata char * ee2addr = 0;            //wskaźnik do pamięci eeprom
;Odczyt bajtu danych z pamięci EEPROM,16-bitowy adres w ADDRESS

char EE_GetByte(unsigned int ADDRESS)
{
    char B;
    WMCON |= 0x08;               //załączenie trybu odczytu eeprom
    B = *(ee2addr+ADDRESS);      //odczyt bajtu
    WMCON &= 0xE7;               //wyłączenie pamięci eeprom
    return (B);
}

;Zapamiętanie bajtu danych w pamięci EEPROM,16-bitowy adres w ADDRESS, bajt w X
void EE_StoreByte(char B, unsigned int ADDRESS)
{
    WMCON |= 0x18;               //włączenie trybu zapisu
    *(ee2addr + ADDRESS) = B;    //zapis bajtu
    while (WMCON & 0x02);        //testowanie stanu zajętości
    WMCON &= 0xE7;               //wyłączenie eeprom
}

 

Listing 2. Podstawowe funkcje obsługi pamięci EEPROM w T/AT89C51RD2

//*************************************
// T89C51RD2, obsługa pamięci EEPROM
//*************************************
//odczyt bajtu z eeprom; adres bajtu w eeprom zawiera parametr ADDRESS
char EE_GetByte(unsigned int ADDRESS)
{
    char B;
    EECON = 0x02;                //załączenie trybu odczytu eeprom
    B = *(e2addr+ADDRESS);
    EECON = EECON & 0xFD;
    return (B);
}

//zapis bajtu do eeprom, bajt przekazywany w parametrze B, adres w ADDRESS
void EE_StoreByte(char B, WORD ADDRESS)
{
    EETIM = 0xDC;                //ustawienie czasu programowania (Vss=5V)
    EECON = 0x02;                //załączenie eeprom
    *(e2addr+ADDRESS) = B;       //zapis bajtu do bufora
    EECON = 0x50;                //zapis bajtu do eeprom
    EECON = 0xA0;
    while (EECON & 0x01);        //testowanie flagi zajętości
}

 

Listing 3. Przykłady użycia funkcji zapisu / odczytu pamięci EEPROM

//odczyt statusu rekordu w eeprom; wartość "1" oznacza, że pozycja jest zajęta
bit EE_PosActive(unsigned int ADDRESS)
{
    return (EE_GetByte(ADDRESS) != 0xFF);
}

//zapis COUNT bajtów obszaru pamięci RAM pod adres wskazywany przez argument
//ADDRESS w eeprom
void EE_SaveBUF(unsigned int ADDRESS, char COUNT)
{
    data char *ptrb = (data char*)(&BUF);
    char i;
    for (i=0; i < COUNT; i++) EE_StoreByte(*ptrb++, ADDRESS++);
}

//przepisanie COUNT bajtów z pamięci EEPROM do RAM spod adresu ADDRESS
void EE_ReadBUF(WORD ADDRESS, char COUNT)
{
    data char *ptrb = (data char*)(&BUF);
    char i;
    for (i=0; i < COUNT; i++) *ptrb++ = EE_GetByte(ADDRESS++);
}

http://www.tomaszbogusz.blox.pl/

Dodaj nowy komentarz

Zawartość pola nie będzie udostępniana publicznie.