Forum: Mikrocontroller und Digitale Elektronik I2C / M24M01 EPROM an ATMEGA


von Ralf D. (dreilira)


Angehängte Dateien:

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
}

von beo bachta (Gast)


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.

von beo bachta (Gast)


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.

von Ralf D. (dreilira)


Lesenswert?

OK, Pull-Up und Vss auf E1 und E2 haben nichts geändert, aber mit 
Entkoppel-Kondensator funktioniert das Adressieren des Bausteines.
Ich gelobe Besserung :-) Danke für die Tipps!

von jo mei (Gast)


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.

von H.Joachim S. (crazyhorse)


Lesenswert?

Ralf D. schrieb:
> Ich gelobe Besserung :-)

Sehr gut :-)
Es gibt auch andere, nennen sich Profis, verdienen ganz viel Geld mit 
dem Einsparen dieser Kondensatoren. Und wir sind alle neidisch, dass wir 
da nicht selber drauf gekommen sind...
Beitrag "Was soll der Quatsch mit den Abblock C's?"

von jo mei (Gast)


Lesenswert?

H.Joachim S. schrieb:
> Sehr gut :-)

Vorbildlich!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.