Forum: Mikrocontroller und Digitale Elektronik EEPROM read, 16-Bit Adresse, TWI


von Jürgen H. (misteret)


Lesenswert?

Hallo,

ich habe einen EEPROM Baustein und versuche ihn mit dem ATmega16 zu 
beschreiben und auszulesen.

Es handelt sich um einen EEPROM von Microchip:
http://www.reichelt.de/?;ACTION=3;LA=444;GROUP=A324;GROUPID=4511;ARTICLE=96564;START=0;SORT=artnr;OFFSET=76;SID=27aJIvtawQARsAAF7nYZU8422fdf6726e64be5077242d8881e3bf

Ich denke, das Beschreiben hat funktioniert. Jedenfalls bekam ich immer 
die korrekten Status Codes im TWSR Register.


Das Lesen bereitet mit noch Probleme.
Im datasheet des 24LC512 finde ich auf Seite 14 folgenes Schema fürs 
Auslesen:

Write Start Condition - ACK - Write ControlByte - Write HighByte_address 
- ACK - Write LowByte_address - ACK - Write Start Condition - ACK - 
Write Control Byte - ACK - READ data

So, nach dem Schreiben des LowBytes der Adresse steht in TWSR der Code 
$28. Jetzt sende ich erneut eine Start Conditon, das ist dann eine 
repeated Start conditon, also erwarte ich den Statuscode $10. Danach 
wird 0xA1 für Auslsen an TWDR gesendet, allerdings wird kein Wert dort 
reingeladen aus dem EEPROM. Ich kann euch ja mal einen Code schicken von 
meinem C-Quelltext.

Ich glaube, der ATmega16 erwartet nach dem SSchreiben der Adresse ein 
Auslesen des Bytes im EEPROM, und nicht eine erneute Start-Condition. So 
ist es auf Seite 190/191 des ATmega16 datasheets.

von Jürgen H. (misteret)


Lesenswert?

1
#define START     0x08
2
#define MT_SLAW_ACK  0x18
3
#define MT_DATA_ACK  0x28
4
#define MT_SLAR_ACK     0x40
5
#define RSTART    0x10

1
int TWI_send(void)
2
{
3
  
4
  // START
5
  TWI_start();
6
  // Warten, bis START-condition übermittelt ist
7
  if ( (TWSR & 0xF8) != START) return(0);    
8
    
9
  // Control-Code + Adresse + Schreibbit  
10
  TWDR = 0xA0;
11
  // Control-Code + Adresse des EEPROMS und Schreibbit
12
  // in Datenregister laden
13
  TWCR = (1<<TWINT) | (1<<TWEN);
14
  // senden
15
  while( !(TWCR&(1<<TWINT)) ){;}
16
  // warten auf ACK    
17
18
  if( (TWSR & 0xF8) != MT_SLAW_ACK ) 
19
  {
20
    TWI_stop();
21
    return 0;
22
  }
23
24
  
25
  
26
  // High-Byte der Adresse
27
  
28
  TWDR = 0x00;
29
  // High-Byte der Adresse in Datenregister laden
30
  TWCR = (1<<TWINT) | (1<<TWEN);
31
  // senden
32
  while( !(TWCR&(1<<TWINT)) ){;}
33
  // warten auf ACK 
34
35
  if( (TWSR & 0xF8) != MT_DATA_ACK ) return (0); 
36
  // Übermittlung prüfen
37
38
  // Low-Byte der Adresse
39
  TWDR = 0x0A;
40
  // Low-Byte der Adresse in Datenregister laden
41
  TWCR = (1<<TWINT) | (1<<TWEN);
42
  // senden
43
  while( !(TWCR&(1<<TWINT)) ){;}
44
  // warten auf ACK 
45
46
  if( (TWSR & 0xF8) != MT_DATA_ACK ) return(0);       
47
  // Übermittlung prüfen
48
49
  
50
  
51
  // Daten
52
    
53
  TWDR = 0x55;
54
  // 0x55 in Datenregister laden
55
  TWCR = (1<<TWINT) | (1<<TWEN);
56
  // senden
57
  while( !(TWCR&(1<<TWINT)) ){;}
58
  // warten auf ACK   
59
60
61
  if( (TWSR & 0xF8) != MT_DATA_ACK ) return(0); 
62
  // Übermittlung prüfen
63
64
65
66
  // STOP
67
  TWI_stop();
68
  return(1);
69
  
70
}

1
unsigned char TWI_read(void)
2
{
3
  unsigned char test = 0;
4
  // START
5
  TWI_start();
6
  if ( (TWSR & 0xF8) != START) return(0);
7
  // Prüfen, ob START korrekt übermittelt wurde
8
9
10
  
11
  // Control-Code + Adresse + Schreibbit
12
  TWDR = 0xA0;
13
  // Control-Code + Adresse des EEPROMS und Schreibbit
14
  // in Datenregister laden
15
  TWCR = (1<<TWINT) | (1<<TWEN);
16
  // senden
17
  while( !(TWCR&(1<<TWINT)) ){;}
18
  // warten auf ACK
19
20
  if( (TWSR & 0xF8) != MT_SLAW_ACK ) 
21
  {
22
    TWI_stop();  
23
    return(0); 
24
    // Übermittlung prüfen
25
  }
26
27
  
28
  
29
  // High-Byte der Adresse
30
  TWDR = 0x00;
31
  // High-Byte der Adresse in Datenregister laden
32
  TWCR = (1<<TWINT) | (1<<TWEN);
33
  // senden
34
  while( !(TWCR&(1<<TWINT)) ){;}
35
  // warten auf ACK
36
 
37
  if( (TWSR & 0xF8) != MT_DATA_ACK ) return(0); 
38
  // Übermittlung prüfen
39
40
  
41
  
42
  // Low-Byte der Adresse
43
  TWDR = 0x0A;
44
  // Low-Byte der Adresse in Datenregister laden
45
  TWCR = (1<<TWINT) | (1<<TWEN);
46
  // senden
47
  while( !(TWCR&(1<<TWINT)) ){;}
48
  // warten auf ACK 
49
50
  if( (TWSR & 0xF8) != MT_DATA_ACK ) return(0); 
51
  // Übermittlung prüfen
52
53
  
54
  
55
  // START
56
  TWI_start();
57
  if ( (TWSR & 0xF8) != RSTART) return(0);
58
  // Prüfen, ob START korrekt übermittelt wurde
59
  
60
61
62
  // Control-Code + Adresse + Lesebit
63
  TWDR = 0xA1;
64
  // Control-Code + Adresse des EEPROMS und Schreibbit
65
  // in Datenregister laden
66
  TWCR = (1<<TWINT) | (1<<TWEN);
67
  // senden
68
  while( !(TWCR&(1<<TWINT)) ){;}
69
    // warten auf ACK 
70
71
  if( (TWSR & 0xF8) != MT_SLAR_ACK ) return(0); 
72
  // Übermittlung prüfen
73
74
  
75
  
76
  // Auslesen
77
  test = TWDR;
78
79
  
80
  // STOP
81
  TWI_stop();
82
  // STOP-Condition
83
84
  return(test);
85
86
}

von Jürgen H. (misteret)


Lesenswert?

ok ich habs gefunden

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.