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 odczytać bajt o adresie 200h z pamięci EEPROM 24C16?

centipede 14 Maj 2005 12:51 4545 19
REKLAMA
  • #1 1491595
    centipede
    Poziom 16  
    Posty: 234
    Pomógł: 1
    Ocena: 4
    Witam,
    nie będę mówił, w czym piszę i na jaki uP, bo to wg mnie nie ma żadnego znaczenia. Moje pytanko brzmi : Jak zaadresować (odczytać) bajt o adresie 200h z pamięci podanej w tytule?? Powiem szczerze, że już wiele razy czytałem notę i nie interesuje mnie porada typu, "przeczytaj jeszcze raz". Proszę o pomoc.
    Pozdrawiam.
  • REKLAMA
  • #2 1491657
    LordBlick
    VIP Zasłużony dla elektroda
    Posty: 5438
    Pomógł: 549
    Ocena: 69
    No więc poczytajmy razem notę :
    AT24C01/02/04/08/16 napisał:
    RANDOM READ: A random read requires a “dummy” byte write sequence to load in the data word address. Once the device address word and data word address are clocked in and acknowledged by the EEPROM, the microcontroller must generate another start condition. The microcontroller now initiates a current address read by sending a device address with the read/write select bit high. The EEPROM acknowledges the device address and serially clocks out the data word. The microcontroller does not respond with a zero but does generate a following stop condition (refer to Figure 5).
    Jakieś szczegółowe pytania ? ;)
    Pozdrawiam, Daniel
    Załączniki:
    • Jak odczytać bajt o adresie 200h z pamięci EEPROM 24C16? I2C EEPROM - Random Read.png (2.64 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • #3 1491730
    centipede
    Poziom 16  
    Posty: 234
    Pomógł: 1
    Ocena: 4
    Chyba mnie źle zrozumiałeś - ja już czytałem tą notę i wiem, że to się tak robi .. Konkretnie chodzi mi o to, co znaczy "WORD ADDRESS", i konkretnie proszę o przykład, jak odczytać bajt o adresie 200h. Taka:
    
    bitstartu;                         // inicjacja trancmisji
    i2cwrite(0xA0);                    // identyfikator + adres fizyczny, zapis
    i2cwrite(tutaj nie wiem co);       // proszę o wyjaśnienie tego ..
    bitstartu;
    i2cwrite(0xA0|0x01);               // identyfikator + adres fizyczny, odczyt
    temp=i2cread(0);                   // odczyt bajtu z i2c, bez ACK
    bitstopu                           // koniec transmisji
    

    składnia rozwiązania mojego problemu mnie zadowoli ..
  • #4 1491843
    LordBlick
    VIP Zasłużony dla elektroda
    Posty: 5438
    Pomógł: 549
    Ocena: 69
    Pamięć AT24C16 jest podzielona na strony, które ustawiasz w adresie urządzenia. Word addres to 8-bitowy adres w stronie pamięci. Ten kod jest uniwersalny dla wszystkich n/w pamięci :
    #define byte_address 0x200
    #define page_address ((byte_address>>7)&0b00001110)
    #define word_address (byte_address&0xFF)
    #define i2c_read 0x01
    #define i2c_write 0x00
    bitstartu(void);						// inicjacja transmisji
    i2cwrite(0xA0|page_address|i2c_write);	// identyfikator + adres fizyczny (i strony), zapis
    i2cwrite(word_address);					// teraz chyba jasne... ;)
    bitstartu(void);
    i2cwrite(0xA0|page_address|i2c_read);	// identyfikator + adres fizyczny (i strony), odczyt
    temp=i2cread(0); 					// odczyt bajtu z i2c, bez ACK
    bitstopu(void);							// koniec transmisji
    Albo używamy 24C16, albo 2 x 24C08, albo 4 x 24C04, albo 8 x 24C02 z fizycznie różnymi adresami. Kod będzie ten sam. 24C01 odpada, gwiazdka w rysunku wyżej (mój poprzedni post w tym temacie) oznacza, że ten bit jest dla niego nieistotny, możemy ze soba połączyć tylko 8 takich układów, więc algorytm dla tych układów będzie trochę inny.
    ----------------------
    Edit : Poprawka w obliczaniu adresu page_address
    Pozdrawiam, Daniel
    Załączniki:
    • Jak odczytać bajt o adresie 200h z pamięci EEPROM 24C16? I2C EEPROM - Device Addres.png (1.5 KB) Musisz być zalogowany, aby pobrać ten załącznik.
  • #5 1493212
    centipede
    Poziom 16  
    Posty: 234
    Pomógł: 1
    Ocena: 4
    Wielkie dzięki, dokładnie o to mi chodziło, poprostu nie wiedziałem, że w 24c16 piny adresu fizycznego nie mają znaczenia .. Wielkie dzięki .. :-) ..
    Pozdrawiam
  • #6 1494705
    centipede
    Poziom 16  
    Posty: 234
    Pomógł: 1
    Ocena: 4
    Dobra - NIE działa .. nie mam pojęcia czemu .. odczytuje się poprostu co chce, wpadłem na pomysł, żeby zrobić procedurę zapisu i sprawdzić jak to działa .. jeszcze ciekawiej ..
    
    bitstartu();
     zapiszB_i2c(0xAE);
     zapiszB_i2c(0xFF);
     zapiszB_i2c(0x31);
     bitstopu();
     bitstartu();
     zapiszB_i2c(0xAC);
     zapiszB_i2c(0xFF);
     zapiszB_i2c(0x32);
     bitstopu();
     bitstartu();
     zapiszB_i2c(0xAA);
     zapiszB_i2c(0xFF);
     zapiszB_i2c(0x33);
     bitstopu();
     bitstartu();
     zapiszB_i2c(0xA8);
     zapiszB_i2c(0xFF);
     zapiszB_i2c(0x34);
     bitstopu();
    

    Po odczytaniu JDM + ICPROG w pamięci jest dana 0x32 pod adresem 0x0005, oraz 0x33 pod adresem 0x05FF, nie mam pojęcia o co chodzi ..
  • REKLAMA
  • REKLAMA
  • Pomocny post
    #8 1494911
    BoskiDialer
    Poziom 34  
    Posty: 1530
    Pomógł: 353
    Ocena: 42
    centipede: powiedzmy że niezauważyłem (w twoim przykładzie) iż przy zapisie po sekwencji stopu niema oczekiwania 10ms.. po za tym wszystko wygląda na sprawne..
    0x33 pod adresem 0x05FF <- to by sie zgadzało..
    tak więc conajmniej 1 bajt sie poprawnie zapisał.. reszta nie gdyż widocznie eeprom był zajęty co również wskazuje na brak 10ms po sekwencji stop..
  • #10 1494957
    BoskiDialer
    Poziom 34  
    Posty: 1530
    Pomógł: 353
    Ocena: 42
    Light'I napisał:
    Warunek stopu wystarczy na końcu, warunek startu może się powtarzać.


    pojedynczy warunek stopu przy zapisie więcej niż jednego bajtu występuje tylko w sytuacji PageWrite.. wtedy dokonuje sie jednego adresowania układu.. jednego wyboru pierwszej komórki i wpisuje sie dane aż do końca aktualnej strony.. 24c16 ma strone o rozmiarze 16B więc tyle bajtów można zapisać w jednym cyklu - warunek: adres pierwszej komórki jest adresem pierwszej komórki strony.. nieda się w jednym cyklu zapisać np. połowy jednej strony i połowy kolejnej.
    tak więc w tym przypadku całość trzeba rozdzielić na 4 osobne cykle zakończone sekwencjami stopu + odczekaniem 10ms
  • #11 1495052
    LordBlick
    VIP Zasłużony dla elektroda
    Posty: 5438
    Pomógł: 549
    Ocena: 69
    No to jeszcze pytanie pomocnicze - BoskiDialer : Adresowanie w moim kodzie jest OK, zarówno dla byte write, jak i page write ? Bo już sam nie wiem... ;)
  • #12 1495424
    BoskiDialer
    Poziom 34  
    Posty: 1530
    Pomógł: 353
    Ocena: 42
    Light'I:
    według mnie twój kod jest poprawny.. adres komórki jako 8 bitów.. bity banku do adresu układu.. OK
    adresowanie dla obu trybów nieróżni się wcale.. wysyła sie sekwencje start, adres układu, adres (pierwszej) komórki i wysyła sie dane:
    w byte write wysyła sie jeden bajt zakończony sekwencją stop+10ms..
    w pagewrite wysyła sie wiele bajtów po koleji, dopiero potem wysyła sie stop+10ms
    w pagewrite jest taka pułapka:
    jeśli strona ma 16B a jako adres pierwszego bajtu podamy 29 to maksymalnie można zapisać 3 bajty (bo 16-(29 mod 16) = 3) .. wszystkie kolejne będą musiały być na kolejnej stronie więc niezostaną zapisane..
  • #13 1495838
    centipede
    Poziom 16  
    Posty: 234
    Pomógł: 1
    Ocena: 4
    proszę o znalezienie błędu i naprawy obsługi i2c (ewentualnej) oraz wyrzucenie niepotrzebnych delay'ów ..
    
    #include <avr/io.h>
    #include <avr/pgmspace.h>
    #include <avr/delay.h>
    
    typedef struct _bit_struct
    {
     unsigned char bit0: 1;
     unsigned char bit1: 1;
     unsigned char bit2: 1;
     unsigned char bit3: 1;
     unsigned char bit4: 1;
     unsigned char bit5: 1;
     unsigned char bit6: 1;
     unsigned char bit7: 1;
    }pole_bitowe;
    
    #define _i2c_write 0x00
    #define _i2c_read 0x01
    
    #define DAJ_BIT(adr) (*((volatile pole_bitowe*) (adr)))
    #define _PORTB 0x38
    #define _PINB 0x36
    #define _PORTD 0x32
    #define _DDRD 0x31
    #define _PIND 0x30
    #define sda_we DAJ_BIT(_PIND).bit3
    #define sda_wy DAJ_BIT(_DDRD).bit3
    #define scl_wy DAJ_BIT(_DDRD).bit4
    #define scl_we DAJ_BIT(_PIND).bit4
    #define lcd_rs DAJ_BIT(_PORTB).bit2
    #define lcd_e DAJ_BIT(_PORTB).bit3
    #define sw4 DAJ_BIT(_PIND).bit1
    #define sw1 DAJ_BIT(_PIND).bit0
    
    #define stan_0 1    
    #define stan_1 0
    
    void czekaj_i2c(unsigned char taui2c)  //pętla opóźnienia dla I2C
    {                       //opóźnienie jest równe t=(5+5*taui2c)*T
     do                     //T - cykl zegarowy MCU, taui2c - parametr procedury
     {
      asm("nop");
     }while(--taui2c!=0);
    }
    
    void bitstartu(void)    //bit startu na magistrali I2C
    {
     sda_wy=stan_1;
     czekaj_i2c(20);
     scl_wy=stan_1;
     czekaj_i2c(20);
     sda_wy=stan_0;
     czekaj_i2c(20);
     scl_wy=stan_0;
     czekaj_i2c(20);
    }
    
    void bitstopu(void)
    {
     sda_wy=stan_0;
     czekaj_i2c(20);
     scl_wy=stan_1;
     czekaj_i2c(20);
     sda_wy=stan_1;
     czekaj_i2c(20);
    }
    
    unsigned char zapiszB_i2c(unsigned char dana)
    {                       //wysłanie pojedynczego bajtu do Slave'a I2C
     unsigned char i;
    
     for(i=0;i<8;i++)       //będzie 8 bitów 
     {
      if(dana&0x80)         //badaj najstarszy bit wysyłanego znaku
      {
       sda_wy=stan_1;       //wyślij "1"
      }
      else
      {
       sda_wy=stan_0;       //wyślij "0"
      }
      czekaj_i2c(20);
      scl_wy=stan_1;
      czekaj_i2c(20);
      scl_wy=stan_0;
      czekaj_i2c(20);
      dana<<=1;        //przygotuj następny bit do wysłania
     }
     sda_wy=stan_1;    //zwolnij linię SDA dla Slave'a
     czekaj_i2c(20);
     scl_wy=stan_1; 
     while(!scl_we);   //czekaj, aż Slave będzie gotowy do przyjęcia następnego bitu
     czekaj_i2c(20);
     i=sda_we;         //czytaj potwierdzenie ACK od Slave'a
     scl_wy=stan_0;
     czekaj_i2c(20);
     return i;         //zwróć bit potwierdzenia ACK
    }
    
    unsigned char czytajB_i2c(unsigned char ack)
    {
     unsigned char dana=0,i;
    
     for(i=0;i<8;i++)  //będzie 8 bitów 
     {
      scl_wy=stan_0;
      czekaj_i2c(20);
      scl_wy=stan_1;
      czekaj_i2c(20);
      dana<<=1;             //przygotuj miejsce na kolejny odebrany bit
      dana|=sda_we==1?1:0;  //dopisz odebrany bit  
     }
     scl_wy=stan_0;
     if(ack)           //czy wysyłać potwierdzenie?
     {
      sda_wy=stan_0;   //wyślij ACK
     }
     else
     {
      sda_wy=stan_1;   //brak potwierdzenia sygnalizuje zakończenie bloku
     }
     czekaj_i2c(20);
     scl_wy=stan_1;
     while(!scl_we);   //czekaj, aż Slave będzie gotowy do przyjęcia następnego bitu
     czekaj_i2c(10);
     sda_wy=stan_1;    //zwolnij linię SDA
     scl_wy=stan_0;
     return dana;
    }
    
    unsigned char ext_epprom_read_byte(unsigned short address)
    {
     unsigned char temp;
     temp=address>>7;
     bitstartu();
     zapiszB_i2c(0xA0|temp|_i2c_write);
     zapiszB_i2c(address&0xFF);
     _delay_ms(10.1);
     bitstartu();
     zapiszB_i2c(0xA0|temp|_i2c_read);
     temp=czytajB_i2c(0);
     bitstopu();
     return temp;
    }
    
    void ext_eeprom_write_byte(unsigned short address, unsigned char data)
    {
     unsigned char temp;
     temp=address>>7;
     bitstartu();
     zapiszB_i2c(0xA0|temp|_i2c_write);
     zapiszB_i2c(address&0xFF);
     zapiszB_i2c(data);
     bitstopu();
    }
    
    int main(void)
    {
     unsigned char danadotestu;
     DDRB=0xff;
     PORTB|=0x02;
     DDRD=0x00;
     PORTD=0x07;
     scl_wy=stan_0;
    //>>>>>>>>>>>>>>>>>>               <<<<<<<<<<<<<<<<<<<<<<<<<
     danadotestu=ext_epprom_read_byte(0x04C0);
     ext_eeprom_write_byte(0x07FF,danadotestu);
     while(1);
    }
    
    
  • REKLAMA
  • #15 1497540
    BoskiDialer
    Poziom 34  
    Posty: 1530
    Pomógł: 353
    Ocena: 42
    w komentażach pozwole dodać swoje dopiski (będą one po znaku #)
    
    void bitstopu(void) 
    { 
    // # tu powinno być scl_wy = 0.. jeśli scl będzie równe 1 to sekwencja stop będzie poprzedzona sekwencją start (scl=1 a sda=1->0 więc start) a to może powodować konflikty..
     sda_wy=stan_0;
     czekaj_i2c(20); 
     scl_wy=stan_1;
     czekaj_i2c(20); 
     sda_wy=stan_1;
     czekaj_i2c(20); 
    }
    
    unsigned char zapiszB_i2c(unsigned char dana) 
    {                       //wysłanie pojedynczego bajtu do Slave'a I2C 
     unsigned char i; 
    
     for(i=0;i<8;i++)       //będzie 8 bitów 
     { 
      if(dana&0x80)         //badaj najstarszy bit wysyłanego znaku 
      { 
       sda_wy=stan_1;       //wyślij "1" 
      } 
      else 
      { 
       sda_wy=stan_0;       //wyślij "0" 
      } 
      czekaj_i2c(20); 
      scl_wy=stan_1; 
      czekaj_i2c(20); 
      scl_wy=stan_0; 
      czekaj_i2c(20); 
      dana<<=1;        //przygotuj następny bit do wysłania 
     } 
     sda_wy=stan_1;    //zwolnij linię SDA dla Slave'a 
     czekaj_i2c(20); 
     scl_wy=stan_1; 
     while(!scl_we);   //czekaj, aż Slave będzie gotowy do przyjęcia następnego bitu # według mnie slave niewymusza stanu niskiego na SCL więc to będzie blokować całość..
     czekaj_i2c(20); 
     i=sda_we;         //czytaj potwierdzenie ACK od Slave'a 
     scl_wy=stan_0; 
     czekaj_i2c(20); 
     return i;         //zwróć bit potwierdzenia ACK 
    }
    
    unsigned char czytajB_i2c(unsigned char ack) 
    { 
     unsigned char dana=0,i; 
    
     for(i=0;i<8;i++)  //będzie 8 bitów 
     { 
      scl_wy=stan_0; 
      czekaj_i2c(20); 
      scl_wy=stan_1; 
      czekaj_i2c(20); 
      dana<<=1;             //przygotuj miejsce na kolejny odebrany bit 
      dana|=sda_we==1?1:0;  //dopisz odebrany bit  
     } 
     scl_wy=stan_0; 
     if(ack)           //czy wysyłać potwierdzenie? 
     { 
      sda_wy=stan_0;   //wyślij ACK 
     } 
     else 
     { 
      sda_wy=stan_1;   //brak potwierdzenia sygnalizuje zakończenie bloku 
     } 
     czekaj_i2c(20); 
     scl_wy=stan_1; // SCL do potwierdzenia # ok.. (#1)
     while(!scl_we);   //czekaj, aż Slave będzie gotowy do przyjęcia następnego bitu # slave niewymusza 0 na scl! to będzie całość blokować
     czekaj_i2c(10); 
     sda_wy=stan_1;    //zwolnij linię SDA # skoro mamy panowanie nad magistralą (niebyło sekwencji stop) to nietrzeba zwalniać linii SDA.. a po za tym w #1 SCL=1 więc teraz SDA=1 to będzie sekwencja stop!! źle..
     scl_wy=stan_0;
     return dana; 
    }
    
    unsigned char ext_epprom_read_byte(unsigned short address) 
    { 
     unsigned char temp; // # ok
     temp=address>>7; // # temp=(address>>7)&0x0e;
     bitstartu(); // # ok
     zapiszB_i2c(0xA0|temp|_i2c_write); // # ok
     zapiszB_i2c(address&0xFF); // # ok
     _delay_ms(10.1); // # zbędne -> do odczytu nietrzeba oczekiwania
     bitstartu(); // # ok
     zapiszB_i2c(0xA0|temp|_i2c_read); // # ok
     temp=czytajB_i2c(0); // # ok jeśli 0 oznacza nack
     bitstopu(); // # ok
     return temp; // # ok
    }
    
    void ext_eeprom_write_byte(unsigned short address, unsigned char data) 
    { 
     unsigned char temp; // # ok
     temp=address>>7; // # tu jest błąd - brak maskowania bitów -> temp=(address>>7) & 0x0e;
     bitstartu(); // # ok
     zapiszB_i2c(0xA0|temp|_i2c_write); // # ok
     zapiszB_i2c(address&0xFF); // # ok
     zapiszB_i2c(data); // # ok
     bitstopu(); // # ok
     // # TU powinno być odczekanie 10ms..
    }
    


    po 5 minutach zrozumiałem dlaczego
    #define stan_0 1
    #define stan_1 0
    jest poprawne -> tu występuje sterowanie ddr'em a nie portem...

    po drobnych modyfikacjach kod będzie wyglądał mniej więcej tak:
    
    void bitstopu(void) 
    { 
     scl_wy=stan_0;  // SCL = 0
     czekaj_i2c(20); 
     sda_wy=stan_0;  // SDA = 0
     czekaj_i2c(20); 
     scl_wy=stan_1;  // SCL = 1
     czekaj_i2c(20); 
     sda_wy=stan_1;  // SDA = 1 (bit stopu)
     czekaj_i2c(20); 
    }
    
    unsigned char zapiszB_i2c(unsigned char dana) 
    {
     unsigned char i; 
     for(i=0;i<8;i++)
     { 
      sda_wy = ((dana&0x80)>0)?stan_1:stan_0;
      czekaj_i2c(5); 
      scl_wy=stan_1; // SCL = 1
      czekaj_i2c(20); 
      scl_wy=stan_0; // SCL = 0
      czekaj_i2c(20); 
      dana<<=1;
     } 
     sda_wy=stan_1; // zwolnienie SDA
     czekaj_i2c(5); 
     scl_wy=stan_1; // SCL = 1 
     czekaj_i2c(20); 
     i=sda_we;  // pobranie potwierdzenia -> 1=NACK 0=ACK
     scl_wy=stan_0; // SCL = 0
     czekaj_i2c(20); 
     return i;
    }
    
    unsigned char czytajB_i2c(unsigned char ack) 
    { 
     unsigned char dana,i;
     for(i=0;i<8;i++)
     { 
      scl_wy = stan_0;  // SCL = 0
      czekaj_i2c(20); 
      scl_wy = stan_1;  // SCL = 1
      czekaj_i2c(20); 
      dana = dana<<1 + (sda_we==1?1:0);  // zapisanie bitu
     } 
     scl_wy=stan_0; // SCL = 0
     czekaj_i2c(20); // odczekanie..
     sda_wy = (ack==0?stan_1:stan_0);  // wystawienie potwierdzenia lub jego braku..
     czekaj_i2c(5); 
     scl_wy=stan_1;  // SCL = 1 -> wpisanie bitu potwierdzenia
     czekaj_i2c(20); 
     scl_wy=stan_0;  // SCL = 0
     return dana; 
    }
    
    unsigned char ext_epprom_read_byte(unsigned short address) 
    { 
     unsigned char temp;
     temp=(address>>7)&0x0e;
     bitstartu();
     zapiszB_i2c(0xA0|temp|_i2c_write);
     zapiszB_i2c(address&0xFF);
     bitstartu();
     zapiszB_i2c(0xA0|temp|_i2c_read);
     temp=czytajB_i2c(0);
     bitstopu();
     return temp;
    }
    
    void ext_eeprom_write_byte(unsigned short address, unsigned char data) 
    { 
     unsigned char temp;
     temp=(address>>7) & 0x0e;
     bitstartu();
     zapiszB_i2c(0xA0|temp|_i2c_write);
     zapiszB_i2c(address&0xFF);
     zapiszB_i2c(data);
     bitstopu();
     // tu brakuje odczekania 10ms
    }
    
  • Pomocny post
    #16 1497575
    LordBlick
    VIP Zasłużony dla elektroda
    Posty: 5438
    Pomógł: 549
    Ocena: 69
    #define _PORTB 0x38
    #define _PINB 0x36
    #define _PORTD 0x32
    #define _DDRD 0x31
    #define _PIND 0x30
    Czy te wartości nie są zdefiniowane w odpowiednich plikach nagłówkowych ? Myślę, że nawyk definiowania ich tutaj jest niepoprawny, może to później skutkować problemami przy przenoszeniu kodu na innego AVR-a.
    Pozdrawiam, Daniel
  • #17 1499081
    centipede
    Poziom 16  
    Posty: 234
    Pomógł: 1
    Ocena: 4
    Dzięki za pomoc już działa,
    Light'I, dzięki za 2 obrazek jaki zamieściłeś oraz za to :
    Cytat:
    Albo używamy 24C16, albo 2 x 24C08, albo 4 x 24C04, albo 8 x 24C02 z fizycznie różnymi adresami. Kod będzie ten sam. 24C01 odpada, gwiazdka w rysunku wyżej (mój poprzedni post w tym temacie) oznacza, że ten bit jest dla niego nieistotny, możemy ze soba połączyć tylko 8 takich układów, więc algorytm dla tych układów będzie trochę inny.

    i to:
    Cytat:
    temp=((address>>7)&0b00001110)

    Aha, ten ostatni przypis o portach uważam za zbędny, ponieważ nie prosiłem o tego rodzaju optymalizację kodu, a temat wogóle nie dotyczył tego, z jaką estetyką piszę kod ..

    BoskiDialer, dzięki za info na temat delaya .., oraz wskazanie w których miejscach jest on zbędny ..

    Temat uważam za zamknięty ..
  • #18 2408007
    seba_x
    Poziom 31  
    Posty: 2071
    Pomógł: 29
    Ocena: 112
    mam problem z 24c16 : wiem że jest to 2048bx8 , zapisuję w kolejnych 30 komórkach liczbę np. 3 i w zasadzie jest ok , ale jak odczytuję zawartość pamięci (od 0 do 2074) to co 256 komórek powtarza się to co wpisałem na początku

    Dim A As Byte , B As Integer
    Const Adresw = 160
    Const Adresr = 161
    For B = 0 To 30
    I2cstart
    I2cwbyte Adresw
    I2cwbyte B
    I2cwbyte 3 'zapisz liczbe 3
    I2cstop
    Waitms 10
    Next
    End

    w jaki sposób w bascomie mogę wykożystać całe 2048 bajtów ?
  • #19 2411076
    elektryk
    Poziom 42  
    Posty: 11029
    Pomógł: 439
    Ocena: 241
    seba_x, strzelam że masz błąd gdzieś a algorytmie komunikacji.
  • #20 2415888
    seba_x
    Poziom 31  
    Posty: 2071
    Pomógł: 29
    Ocena: 112
    elektryk napisał:
    seba_x, strzelam że masz błąd gdzieś a algorytmie komunikacji.


    nie , błąd był w mojej głowie ;-) 24c16 to nie jest 16k bajtów tylki kilobitów więc jedna strona ma 2048 bitów czyli 256 bajtów , taki głupi błąd :oops:

Podsumowanie tematu

LABEL_AI_GENERATED
Dyskusja dotyczy odczytu bajtu o adresie 0x200 z pamięci EEPROM AT24C16 poprzez interfejs I2C. Wyjaśniono, że pamięć ta jest podzielona na strony, a adresowanie wymaga rozdzielenia adresu bajtu na adres strony (bity banku) i adres słowa (word address) w obrębie strony. Przykładowy kod pokazuje, jak skonstruować adres urządzenia I2C z uwzględnieniem strony oraz jak wykonać sekwencję start, zapis adresu, ponowny start i odczyt bajtu. Podkreślono, że piny adresowe fizyczne w 24C16 nie mają znaczenia dla adresowania. Omówiono także problemy z zapisem wielobajtowym (page write), gdzie konieczne jest stosowanie sekwencji stop i opóźnienia 10 ms po zapisie, aby EEPROM zdążył zapisać dane. Wskazano, że w page write nie można przekroczyć granicy strony (16 bajtów). W dyskusji pojawiły się także uwagi dotyczące implementacji funkcji I2C, optymalizacji kodu i poprawności sygnałów start/stop. Na koniec poruszono problem błędnego rozumienia pojemności pamięci 24C16 – jest to 2048 bajtów (16 kilobitów), a nie 16 kilobajtów, co wpływa na sposób adresowania i odczytu danych.
Podsumowanie AI na podstawie dyskusji. Może zawierać błędy.
REKLAMA