I2C / M24M01 EPROM an ATMEGA

OP #6188370
Lesenswert?

Hallo zusammen,
für ein Projekt habe ich einen Sensor Si7021 an einem Mega 
angeschlossen. Kommunikation damit klappt einwandfrei. Jetzt will ich 
die Daten auch noch speichern und habe dafür einen M24M01 EPROM verbaut. 
Es scheint mir aber so, als ob ich den entweder falsch verbaut habe, 
oder einen hartnäckigen Gedankenfehler habe.

Zur Hardware: ein MEGA328 mit 6MHz, ein LCD, UART, I2C mit Slave SI7021 
umd M24M01. Außer dem EPROM funktioniert alles, den EPROM hab ich 
'minimal' angeschlossen, also nur Versorgungsspannung und SDA/SCL, alle 
anderen Pins sind offen. Ich hab auch schon separat Pullups (10k) 
angeschlossen, ohne Änderung. Prinzipiell kommt der SI7021 aber damit 
klar.

Ich nutze zur Kommunikation den HW-I2C mit der Lib von Fleury.

Beim Lesen einer Adresse bekomme ich schon beim ersten Kontaktversuch 
(I2c_start) einen Fehler zurück, deswegen die Kontroll-Infos auf dem 
LCD. Ret=1, somit keine Antwort vom M24M01
Kontrollausgabe:

M24M01_ADR|I2C_WRITE|(adresse & 0x10000)>>15 = 160, 1010 0000b, das 
entspricht der Adresse des M24M01 mit Memory-Adresse A16=0 und 
Write-Mode. Also genau das, was laut meiner Meinung nach gesendet werden 
muß. Nur warum ist der M24M01 der Meinung, daß ihn das nicht 
interessiert?

Kann mir jemand die Gedanken ordnen?
1
void M24M01_read_byte(uint32_t adresse)
2
{
3
  int8_t Ret;
4
  char lcd_zeile[LCD_DISP_LENGTH+1];
5

6
  lcd_gotoxy(0,0);
7
  lcd_putc('§');
8
  
9
  Ret=i2c_start(M24M01_ADR|I2C_WRITE|(adresse & 0x10000)>>15); // Adressbit A16 kommt auf Device-Address Bit 1
10

11
  itoa(M24M01_ADR|I2C_WRITE|(adresse & 0x10000)>>15, lcd_zeile, 10);
12
  lcd_puts(lcd_zeile);                       // Erg: 160d=1010 0000b
13
  lcd_putc('$');
14
  itoa(Ret, lcd_zeile, 10);
15
  lcd_puts(lcd_zeile);                       // Erg: 1
16

17
  if (Ret){
18
    i2c_stop();
19
  } else {
20
  i2c_write((unsigned char) ((adresse & 0x00ff00) >> 8));  // Adressbits A15-A8
21
     lcd_putc('%');
22
  i2c_write((unsigned char) (adresse & 0x00ff));      // Adressbits A7-A0
23
     lcd_putc('&');
24
  i2c_rep_start(M24M01_ADR|I2C_READ|(adresse & 0x10000)>>16);
25
  
26
  Ret=i2c_readNak();        // das Letzte mit NACK beenden.
27
    itoa(Ret, lcd_zeile, 10);
28
    lcd_puts(lcd_zeile);
29
    _delay_ms(1000);
30

31
  i2c_stop();
32
  }
33
}
Angehängte Dateien:
Gast #6188500
Lesenswert?

Wie sind deine Konstanten I2C_READ und I2C_WRITE definiert?

Bei den beiden Zeilen
1
Ret=i2c_start(M24M01_ADR|I2C_WRITE|(adresse & 0x10000)>>15);
und
1
i2c_rep_start(M24M01_ADR|I2C_READ|(adresse & 0x10000)>>16);

sollten die beiden Shifts gleich sein, nicht wahr?

Ausserdem sollte die Konstante als 0x10000ul geschrieben
werden da sonst das höchste Bit verloren gehen könnte.

Ich empfehle dir dringend dein EEPROM vollständig zu beschalten
auch wenn es erlaubt ist die Eingänge offen zu lassen und sie
dadurch definiert sind.

Zuletzt brauchst du dringend ein Abblock C von Vcc nach Masse.

Alles nicht unbedingt kriegsentscheidend aber sehr emfpehlenswert.
Gast #6188514
Lesenswert?

Ralf D. schrieb:
> char lcd_zeile[LCD_DISP_LENGTH+1];

Dieses Array könnte überlaufen und andere Variablen könnten
dadurch überschrieben werden. Ausserdem sollte das Array
ausserhalb deiner Funktion definiert sein damit die Stack-
Grösse nicht überfordert wird.

Also mach es grösser und lege es global an.
Gast #6189118
Lesenswert?

Ralf D. schrieb:
> mit
> Entkoppel-Kondensator funktioniert das Adressieren des Bausteines.

Was lernen wir daraus (Erklärungsversuch)?

Beim Adressieren des Bausteins reagiert dieser in sehr kurzer
Zeit mit kleinen Stromaufnahme-Spitzen im Nanosekunden-Bereich.
Diese Stromaufnahme kann durch die vergleichsweise hochinduktiven
Versorgungsleitungen nicht geliefert werden und der Baustein
wird wahrscheinlich einen zu starken Spannungseinbruch erfahren
der einen internen Reset auslöst (aber nicht die gewünschte
Aktion). Dieser Effekt kann sowohl auf Vcc- wie auch auf Masse-
zuleitungen zutreffen.

Würde das EEPROM direkt über sehr kurze Versorgungsleitungen
direkt am Controller bzw. seinen Abblock-Kondensatoren hängen,
würde dies nicht passieren.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren