AVR: I2C Write in EEPROM nicht möglich

OP #3627768
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
}
Gast #3627982
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.
OP #3628010
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!!!

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