Forum: Mikrocontroller und Digitale Elektronik AVR: I2C Write in EEPROM nicht möglich


von Timo E. (tetra)


Lesenswert?

Hallo zusammen,

Ich verwende die Fleury I2C-Routinen und greife über den AVR ATmega 
328PU auf ein EEPROM 24LC64 zu.
Der Pin WriteProtect des EEPROMS liegt an GND.
Als Returnwert bekomme ich bei den Schreib- und Leseversuchen jeweils 
(korrekterweise) eine "0" (read/write successful).
Auf einem LCD und parallel 2 LEDs lasse ich mir diese Rückgabewerte 
jeweils anzeigen.

Aber: Obwohl scheinbar ohne Fehlermeldung der Wert 0x75 an Adresse 0x05 
geschrieben wird, erhalte ich als Rückgabewert beim Lesen nur 0.
Vermutlich habe ich irgendwo einen Programmfehler übersehen.
Benötigt ihr noch weitere Infos?

Hier der Programmcode:
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include <stdint.h>
4
#include <stdlib.h>
5
#include "lcd-routines.h"
6
#include "i2cmaster.h"
7
unsigned char ret;
8
uint8_t GREEN = PB1; //die grüne LED
9
uint8_t RED = PB2; //die rote LED
10
uint8_t LED_ON = 1; //LED einschalten
11
uint8_t LED_OFF = 0; //LED ausschalten
12
13
#define Dev24C64  0xA0      // device address of EEPROM 24C02, see datasheet
14
15
void LED(uint8_t LED_COLOR , uint8_t STATUS)   //Bsp: LED(GREEN, LED_ON)
16
{
17
  if (LED_COLOR == GREEN  && STATUS == LED_ON)
18
  {
19
    DDRB = ( 1 << GREEN );        // PB1 an PORTB als Ausgang setzen (GRÜN)
20
    PORTB = (1 << GREEN );  //  PB1 grüne LED einschalten
21
    _delay_ms(500);        // 1/2 Sekunde  warten...
22
    PORTB &= ~(1<<GREEN); // löscht Bit 2 in PORTB und schaltet LED an PB1 aus
23
  }
24
  if (LED_COLOR == GREEN  && STATUS == LED_OFF)
25
  {
26
    PORTB &= ~(1<<GREEN); // löscht Bit 2 in PORTB und schaltet LED an PB1 aus
27
  }
28
  if (LED_COLOR == RED  && STATUS == LED_ON)
29
  {
30
    DDRB = ( 1 << RED );        // PB2 an PORTB als Ausgang setzen (RED)
31
    PORTB = (1 << RED );  //  PB2 rote LED einschalten
32
    _delay_ms(500);        // 1/2 Sekunde  warten...
33
    PORTB &= ~(1<<RED); // löscht Bit 2 in PORTB und schaltet LED an PB2 aus
34
  }
35
  if (LED_COLOR == RED  && STATUS == LED_OFF)
36
  {
37
    PORTB &= ~(1<<RED); // löscht Bit 2 in PORTB und schaltet LED an PB2 aus
38
  }
39
}
40
41
int main(void)
42
{
43
  lcd_init();
44
  LCD_CLEAR_DISPLAY;
45
    
46
  lcd_setcursor( 0, 1 );
47
  lcd_string("Kontrollanzeige:");
48
  
49
   i2c_init(); // initialize I2C library 
50
                              
51
   if(!(i2c_start(Dev24C64+I2C_WRITE))) //--> OK 
52
   {
53
    i2c_write(0x05);  // write address = 5      
54
   i2c_write(0x75);  // write value 0x75 to EEPROM !
55
   i2c_stop();       // set stop conditon = release bus
56
   LED(GREEN, LED_ON);
57
     }
58
      else
59
     {
60
        lcd_setcursor( 0, 2 );
61
        lcd_string("E: Write-Fehler");  /* Fehlermeldung ausgeben ... */
62
     LED(RED, LED_ON);  
63
     }
64
    
65
   _delay_ms(50);
66
   
67
   i2c_start_wait(Dev24C64+I2C_WRITE); //device address/write mode;        
68
   i2c_write(0x05);  
69
   i2c_rep_start(Dev24C64+I2C_READ); // set device address /read mode  
70
   ret=i2c_readNak();                // read one byte from EEPROM
71
   //
72
   // ===> Hier bekomme ich für ret immer den Wert 0 anstatt 0x75
73
   //
74
   lcd_setcursor( 0, 3 );
75
   lcd_string("ret: ");
76
   char Buffer[20]; 
77
   itoa( ret, Buffer, 10 );
78
   lcd_string( Buffer ); //ret als String ausgeben   
79
   if (ret == 0x75)
80
   {
81
     LED(GREEN, LED_ON);
82
   } 
83
   else
84
   {
85
     LED(RED, LED_ON);
86
   }
87
      
88
   i2c_stop();
89
      
90
91
  while(1)
92
  {
93
  }
94
  
95
  return 0;
96
}

von holger (Gast)


Lesenswert?

>Vermutlich habe ich irgendwo einen Programmfehler übersehen.

Vermutlich hast du das Datenblatt zu dem Chip nie gelesen.
Der benötigt zwei Byte für die Adressierung.

von Timo E. (tetra)


Lesenswert?

Hallo Holger,

danke für die schnelle Antwort. Das wird es bestimmt sein. Ich muss mich 
jetzt mal einlesen, wir man das Adressbyte in Low- und Hibyte 
aufsplittet und ans EEPROM übergibt (bin noch Anfänger).

Gruß,
Timo

von Ein Elektroniker (Gast)


Lesenswert?

Timo E. schrieb:

> Ich muss mich
> jetzt mal einlesen, wir man das Adressbyte in Low- und Hibyte
> aufsplittet und ans EEPROM übergibt (bin noch Anfänger).

Vor allem kann es aber sein, daß man im Internet Beispiele findet. Z.B. 
bei den µC- und Compilerherstellern. Das ist besser, als es selbst zu 
programmieren zu beginnen.

von Timo E. (tetra)


Lesenswert?

Hallo Zusammen,

nachdem ich nun holgers Tip gefolgt bin und die Adresse in Lo- und 
Hibate aufgeteilt habe funktioniert es- Den Code habe ich folgendermaßen 
geändert:
1
...
2
   i2c_init(); // initialize I2C library 
3
                              
4
   if(!(i2c_start(Dev24C64+I2C_WRITE))) //--> OK 
5
   {
6
    i2c_write(0x00);  // write address = 0x05 als 16-Bit-Wert übermitteln. Erst das HiByte     
7
   i2c_write(0x05);  // anschließend das LoByte
8
   i2c_write(0x75);  // write value 0x75 to EEPROM !
9
   i2c_stop();       // set stop conditon = release bus
10
   LED(GREEN, LED_ON);
11
...
Danke für die Hilfe!!!

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.