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

Jak zapisać 40 kB do pamięci Atmel 24C64? Adresowanie drugiej części 32kB

Geralt 22 Paź 2007 01:53 1467 11
REKLAMA
  • #1 4402284
    Geralt
    Poziom 14  
    Posty: 157
    Pomógł: 1
    Ocena: 3
    Witam

    Chce zapisać 40 kB do pamięci atmela 24C64. Pierwsze 32 kB zapisuje bez problemu, ale nie wiem jak się przełączyć do drugich 32. Jaki będzie początkowy adres kolejnych 32, i czy też będzie tam działała autoinkrementacja. Z datasheetu z moją zanjomością angielskiego nic nie mogę wyczytać :(
  • REKLAMA
  • #2 4402305
    autoservice
    Poziom 20  
    Posty: 516
    Pomógł: 7
    Ocena: 16
    ...jak wiesz, musisz wysłać dwa bajty adresu dla tej pamięci. Najpierw MSB potem LSB. Dla tego rozmiaru pamięci adres jest 16-bitowy więc jest postaci
    xxxDDDDD_DDDDDDDD, gdzie xxx to bity nic nie znaczące, wartość dowolna, a D to bity adresu. Najwidoczniej zapominasz o jednym bicie, tym najbardziej znaczącym, dlatego adresujesz tylko 32k
    Pzdr.
  • REKLAMA
  • #3 4402638
    Geralt
    Poziom 14  
    Posty: 157
    Pomógł: 1
    Ocena: 3
    hmmm no oki, ale jaki będzie w takim razie adres pierwszej komórki 2 połówki?

    Dodano po 52 [minuty]:

    Aj w sumie źle się wyraziłem , zapisuje jedna strone czyli 32 Byte, i nie wiem od jakiego adresy zaczyna się kolejna za cholere nie mogę sobie poradzić z przejściem do kolejnej
  • #4 4402837
    piti___
    Poziom 23  
    Posty: 623
    Pomógł: 67
    Ocena: 9
    Witam

    Przykładowy kod w C zapisujacy 32B strony do 24C64
    
    void write_page(byte dev_adr, byte page_number,byte *buffor, byte len)
    {
    	short mem_adr = (short)page_number << 5;
       i2c_start();
       i2c_out_byte(0xa0 | (dev_adr << 1));
       i2c_nack();
       i2c_out_byte((mem_adr >> 8) & 0xff);	// high byte of memory address
       i2c_nack();
       i2c_out_byte(mem_adr & 0xff);	// low byte of mem address
       i2c_nack();
    	while(len--)
    	{
       		i2c_out_byte(*(buffor++));			// and finally the data
    	   i2c_ack();
    	}
       i2c_stop();
       delay_ms(25); // allow for the programming of the eeprom
    }
  • #5 4402976
    olekewaagata
    Poziom 25  
    Posty: 638
    Pomógł: 64
    Ocena: 28
    Kolego , zapisywanie do starszych 32k pamięci bezwzględnie związane jest z nóżką WP (pin 7 pamięci) Jeśli jest ona na plusie , pisanie do tego obszaru jest zabronione, a co najciekawsze wykonujesz zapis i jesli jest zablokowany przez WP=1 to nic nie jest sygnalizowane. Tak więc jeśli chcesz pisać do końca tej pamięci ustaw WP=0.
    Jeśli chodzi o adresowanie to jest liniowe czyli adres pierwszego bajtu w tej dalszej pamieci to adres = 32768 i tak dalej.
    Dla ciekawości odczyt pamięci jest zawsze cały niezależny od stanu WP.
  • #6 4403345
    Geralt
    Poziom 14  
    Posty: 157
    Pomógł: 1
    Ocena: 3
    piti no właśnie nie czaje, ja zapisałem do tej pory jedna stronę 32 bajty. I patrząc na Twój algorytm adres kolejnej strony to 00h 20h. No i to jest logiczne ale jak tak adresuje to mi sie sypie i odczytuje potem FF wkoło

    Dodano po 18 [minuty]:

    chyba ze ja źle odczytuje pamięć, pierwsze 32 bajty ok lecą. później daje stopa, start z adresem urządzenia i już same FF a jak dam tak:

    stop_i2c();

    start_i2c();
    write_i2c(0xA0); //adres pamieci
    stop_i2c();

    start_i2c();
    write_i2c(0xA0 | 1);
    a = read_i2c();
    ....

    bez tego pierwszego startu nie działa , jak go dam to odczytuje dobrze ino nie rozumiem dlaczego on tam konieczny jest. próbowałem z nim i z podaniem adresu tam i też nie działało.
  • REKLAMA
  • #7 4403443
    piti___
    Poziom 23  
    Posty: 623
    Pomógł: 67
    Ocena: 9
    Pamięć możesz odczytać bez konieczności adresowania co 32B, wysyłasz adres komórki a nastepnie możesz czytać do końca pamięci.

    void read_seq(byte dev_adr, byte *buffor, byte mem_adr, byte len)
    {
    	
       byte y,i;
       i2c_start();
       i2c_out_byte(0xa0 | (dev_adr << 1));
       i2c_nack();
       i2c_out_byte((mem_adr >> 8) & 0xff);
       i2c_nack();
       i2c_out_byte(mem_adr & 0xff);
       i2c_nack();
       i2c_start();				// no intermediate stop
       i2c_out_byte(0xa1 | (dev_adr << 1));	// read operation
       i2c_nack();
    	
    	for(i = 0; i<len; i++)
    	{	
    		*(buffor+i) =i2c_in_byte();
    		i2c_ack();
    	}
    			i2c_stop();		
    }
    
  • REKLAMA
  • #8 4403905
    BoskiDialer
    Poziom 34  
    Posty: 1530
    Pomógł: 353
    Ocena: 42
    To ja tak zapytam nieśmiale: od kiedy 24c64 ma 64KB (kilobajty)? 24c64 to pamięć 64kilobity, czyli 8KB.
    piti___: czemu w twoim kodzie obok i2c_out pojawia się ack i nack? Przecież master wysyłając dane odbiera potwierdzenia (odbierając dane wysyła - tutaj rozumiem, ale i tak jest błąd, wypadało by przy odczycie ostatniego bajtu wysłać nack aby zakończyć odczyt).
  • #9 4403912
    Geralt
    Poziom 14  
    Posty: 157
    Pomógł: 1
    Ocena: 3
    hmm no to tak czytając po pierwszych 32 bajtach mam same FF

    Dodano po 15 [minuty]:

    Zerknijcie bo może ja jestem ślepy i czegoś nie widze

    Cytat:

    init_i2c();
    start_i2c();
    write_i2c(0xA0);
    write_i2c(0x00);
    write_i2c(0x00);
    //1
    write_i2c(0x3A);
    write_i2c(0x30);
    write_i2c(0x38);
    write_i2c(0x30);


    write_i2c(0x30);
    write_i2c(0x30);
    write_i2c(0x30);
    write_i2c(0x30);

    write_i2c(0x30);
    write_i2c(0x43);
    write_i2c(0x30);
    write_i2c(0x42);

    write_i2c(0x34);
    write_i2c(0x30);
    write_i2c(0x34);
    write_i2c(0x38);

    write_i2c(0x32);
    write_i2c(0x30);
    write_i2c(0x30);
    write_i2c(0x30);

    write_i2c(0x30);
    write_i2c(0x30);
    write_i2c(0x30);
    write_i2c(0x30);


    //4
    write_i2c(0x30);
    write_i2c(0x46);
    write_i2c(0x46);
    write_i2c(0x0D);

    write_i2c(0x0A);
    write_i2c(0x3A);
    write_i2c(0x30);
    write_i2c(0x30);



    stop_i2c();

    start_i2c();

    write_i2c(0xA0);
    write_i2c(0x10);
    write_i2c(0x00);

    //tego juz nie zapisuje
    write_i2c(0x30);
    write_i2c(0x30);
    write_i2c(0x30);
    write_i2c(0x30);

    write_i2c(0x30);
    write_i2c(0x31);
    write_i2c(0x46);
    write_i2c(0x46);

    write_i2c(0x0D);
    write_i2c(0x0A);

    stop_i2c();

  • Pomocny post
    #10 4403995
    BoskiDialer
    Poziom 34  
    Posty: 1530
    Pomógł: 353
    Ocena: 42
    eeprom to nie jest pamięć ram, po sekwencji wysyłania danych zapis następuje po otrzymaniu znaku stopu i trwa około 10ms.. musisz wstawić opóźnienie 10ms pomiędzy stopem jednego zapisu a startem kolejnego.
  • Pomocny post
    #11 4404007
    piti___
    Poziom 23  
    Posty: 623
    Pomógł: 67
    Ocena: 9
    Hej

    Niefortunne nazewnictwo, nack "czyta" ack ze slave'a, ack wysyla ack z mastera.
    
    void i2c_nack(void)
    {
       i2c_high_sda();	// data at one
       i2c_high_scl();	// clock pulse
       i2c_low_scl();
    }
    
    void i2c_ack(void)
    {
       i2c_low_sda();	// bring data low and clock
       i2c_high_scl();
       i2c_low_scl();
       i2c_high_sda();
    }
    


    Po ostatnim bajcie wysylam poprostu i2c_stop().
  • #12 4404035
    Geralt
    Poziom 14  
    Posty: 157
    Pomógł: 1
    Ocena: 3
    ja tam teraz znacznie więcej niż 10 ms i nei pomogło :(

    Dodano po 4 [minuty]:

    kurde potrzebuje zaprogramować pamięć żeby mi bootowała inny układ i tyle z tym problemu, wszystko stoi

    Dodano po 8 [minuty]:

    oki już mam , dzięki BoskiDialer i piti__

Podsumowanie tematu

✨ Dyskusja dotyczy zapisu 40 kB danych do pamięci EEPROM Atmel 24C64, która ma pojemność 64 kilobity (8 kB), a nie 64 kilobajty. Problem polega na adresowaniu pamięci powyżej pierwszych 32 kB (czyli 32 strony po 32 bajty każda). Pamięć 24C64 wymaga 16-bitowego adresowania, gdzie adres składa się z dwóch bajtów: MSB i LSB. Adresowanie jest liniowe, a druga połowa pamięci zaczyna się od adresu 32768 (0x8000). Autoinkrementacja działa w obrębie strony 32-bajtowej. Ważne jest, aby pin WP (Write Protect) był ustawiony na 0, aby umożliwić zapis do całej pamięci. Po zapisie konieczne jest odczekanie około 10 ms na zakończenie programowania pamięci przed kolejnym dostępem. Wskazano przykładowy kod w języku C do zapisu i odczytu danych z wykorzystaniem protokołu I2C, uwzględniający wysyłanie dwóch bajtów adresu oraz odpowiednie sekwencje start/stop i potwierdzeń (ACK/NACK). Podkreślono, że EEPROM nie jest pamięcią RAM i zapis następuje po sygnale stop. Problemy z odczytem po pierwszych 32 bajtach wynikały z błędów w sekwencji I2C i braku odpowiednich opóźnień. Ostatecznie rozwiązaniem było poprawne adresowanie, kontrola pinu WP oraz stosowanie opóźnień między operacjami zapisu.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA