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

ATMega162 i problem z eeprom AT24C08AN

scyt 19 Maj 2010 08:12 1133 2
REKLAMA
  • #1 8093314
    scyt
    Poziom 11  
    Witam,
    Od kilku dni nie mogę dojść dlaczego nie działa mi odczyt z AT24C08AN.
    Za każdym razem ATMega162 odczytuje mi wartość FF.

    Funkcje I2C_start2(), I2C_stop2(), I2C_write2(), I2C_read2() na pewno są poprawne bo bez problemu obsługuję nimi PCF8583. Podłączenie elektryczne na pewno OK.
    Próbowałem na 3 różnych sztukach eepromu AT24C08AN i zawsze to samo.

    Zapisuję i następnie odczytuje AT24C08 w ten sposób:

    
    void EE_write(void)
    {
    u08 ack=0;
    I2C_start2();
    ack=I2C_write2(0xA0); //adres urządzenia - tryb zapis
    rsSend(ack);  --> ack=0 czyli ok
    ack=I2C_write2(0x00); //adres komórki
    rsSend(ack);  --> ack=0 czyli ok
    ack=I2C_write2(0x77); //wartość do zapisania
    rsSend(ack);  --> ack=0 czyli ok
    I2C_stop2();
    _delay_ms(15);
    }
    
    void EE_read(void)
    {
    u08 ack=0, buf=0;
    I2C_start2();
    ack=I2C_write2(0xA0); //adres urządzenia - tryb zapis
    rsSend(ack);   --> ack=0 czyli ok
    ack=I2C_write2(0x00); //adres komórki
    rsSend(ack);  --> ack=0 czyli ok
    I2C_start2();
    ack=I2C_write2(0xA1); //adres urządzanie - tryb odczyt
    rsSend(ack);  --> ack=0 czyli ok
    buf=I2C_read2(1); //odczyt bez ack
    rsSend(buf); --> buf=FF czyli nie ta wartość, której oczekiwałem
    I2C_stop2();
    }


    Dla pewności wrzucam jeszcze funkcje programowej obsługi I2C.

    
    void I2C_start2(void)
    {
      I2C_SCL_H2();
      I2C_SDA_H2();
      I2C_SDA_WR2();
      I2C_SCL_WR2();	//inicjalizacja kierunków portów
      _delay_us(10);
      I2C_SDA_L2();
      _delay_us(10);
      I2C_SCL_L2();
      _delay_us(10);
    }
    
    void I2C_stop2(void)
    {
      I2C_SDA_WR2();		// SDA na zapis
      I2C_SCL_H2();
      _delay_us(10);
      I2C_SDA_H2();
      _delay_us(10);
    }
    
    
    u08 I2C_write2(u08 b)
    {
      u08 i;
      I2C_SDA_WR2();		// SDA na zapis
      for (i=0; i<8; i++)	// zapis 8 bitów
      {
        if (b & 0x80)
          I2C_SDA_H2();
        else
          I2C_SDA_L2();
        _delay_us(10);
        I2C_SCL_H2();
        _delay_us(10);
        I2C_SCL_L2();
        b <<= 1;		// przesuń o 1 bit
      }
      I2C_SDA_RD2();		// włącz czytanie SDA
      I2C_SDA_H2();		// podciągnij SDA
      _delay_us(10);
      I2C_SCL_H2();		// SCL=1
      _delay_us(10);
      i=0xFF;
      do
      {
        if (bit_is_clear(I2C_PORT_I2,I2C_SDA2)) break;	// jeżeli jest potwierdzenie
        _delay_us(10);
      }
      while(--i>0);
      I2C_SCL_L2();		// SCL=0
      _delay_us(10);
      return(i);
    }
    
    u08 I2C_read2(u08 ack)
    {
      u08 i;
      u08 b = 0;
      I2C_SDA_RD2();		// SDA na odczyt
      I2C_SDA_H2();		// podciąganie SDA
      _delay_us(10);
      for (i=0; i<8; i++)	// czytanie 8 bitów
      {
        I2C_SCL_H2();	// SCL w stan wysoki
        _delay_us(10);
        b <<= 1;		// przesuń o 1 bit
        if (bit_is_set(I2C_PORT_I2,I2C_SDA2)) // jeśli SDA=1 
          b |= 1;		// dodaj odczytany bit z magistrali
        I2C_SCL_L2();	// SCL w stan niski
        _delay_us(10);
      }
      I2C_SDA_WR2();		// SDA na zapis
      if (ack == 0)	// ustaw bit ACK na określoną wartość
        I2C_SDA_L();
      else
        I2C_SDA_H2();
      _delay_us(10);
      I2C_SCL_H2();
      _delay_us(10);
      I2C_SCL_L2();
      _delay_us(10);
      I2C_SDA_L2();
      _delay_us(10);
      return(b);
    }
    


    Bardzo proszę o pomoc bo to jest prosta sprawa a nie mogę sobie poradzić. Pozdrawiam
  • REKLAMA
  • #2 8093677
    Robewit
    Poziom 26  
    Czy pin7 (Write Protect) pamięci masz podłączony do minusa zasilania?
  • #3 8095166
    scyt
    Poziom 11  
    Tak jest podłączony. Wyprowadzenie WP do GND.
    Chyba coś jest nie tak z tymi procedurami obsługi I2C bo jak zmienię adres fizyczny AT24C08 (PIN A2 do Vcc) to po zmianie adresu urządzenia na 0xA8 eeprom nie odpowiada.. Te procedury pochodzą z biblioteki RKlibAVR z strony http://avr.elektroda.eu/index.php?q=node/4.

    Fakt, że eeprom odpowiada bitem ACK to chyba jakiś przypadek.

    Wykorzystałem inną bibliotekę pana Petera Fleury http://homepage.hispeed.ch/peterfleury/index.html i zaczęło działać.

    Temat zamykam i proponuje nie korzystać z rozwiązania I2C dla eeprom z biblioteki RKlibAVR.

    Dziękuję i pozdrawiam.
REKLAMA