Forum: Mikrocontroller und Digitale Elektronik EEPROM 24c16


von Florian idb (Gast)


Lesenswert?

Hi Leute,

hab mal eine kleine Frage an die C Profis unter euch.

Und zwar würde ich gerne ein EEPROM IC vom Typ 24c16 in C mit meinem 
Atmega8 ansprechen. Allerdings blicke ich bei den ganzen TWI Sachen 
nicht so richtig durch (von der Software her).

Meine Frage ist nun ob jemand von euch das schonmal gemacht hat und mir 
eventuell die Funktionen zum lesen und schreiben eines Bytes zur 
verfügung stellen könnte.Sitze nun schon 3 Wochen dran und bin echt am 
verzweifeln.

Danke im vorraus
Flo

von Falk B. (falk)


Lesenswert?

Ich kann dir meinen Q&D Entwurf geben. Ist aber noch nicht getetstet, 
weil ich noch keine Hardware dazu habe. Aber als Ideenspender sollte es 
reichen.

Header i2c.h

1
#define SDA_LOW DDRB |= (1<<PB0);    // low, open drain
2
#define SDA_HIGH DDRB &= ~(1<<PB0);    // high, Z
3
4
#define SCL_LOW DDRB |= (1<<PB1);    // low, open drain
5
#define SCL_HIGH DDRB &= ~(1<<PB1);    // high, Z
6
7
#define SDA (PINB & (1<<PB0))      // get SDA
8
9
void i2c_write_byte(uint16_t address, uint8_t data);
10
uint8_t i2c_read_byte(uint16_t address);
11
void i2c_read_block(uint16_t address, uint8_t *buffer, uint16_t count);
12
void i2c_write_cblock(uint16_t address, uint8_t cnt, uint8_t data);


Source i2c.c

1
/*
2
3
Quick and Dirty I2C Access
4
5
*/
6
7
#include <avr/io.h>
8
#include "i2c.h"
9
10
void i2c_start(void)
11
{
12
  SDA_LOW
13
  asm("nop");
14
  SCL_LOW
15
}
16
17
void i2c_stop(void)
18
{
19
  SDA_HIGH
20
  asm("nop");
21
  SCL_HIGH
22
}
23
24
uint8_t i2c_write(uint8_t data)
25
{
26
  uint8_t cnt=8;
27
  for (; cnt>0; cnt--) {
28
    if (data & 0x80)
29
      SDA_HIGH
30
    else
31
      SDA_LOW
32
    SCL_HIGH
33
    data <<= 1;
34
    SCL_LOW
35
  }
36
  SDA_HIGH
37
  SCL_HIGH
38
  asm("nop");              // WICHTG, wegen des Eingangsverzögerung!
39
  if (SDA) cnt=0; else cnt=1;      // check ACK
40
  SCL_LOW
41
  return cnt;
42
}
43
44
uint8_t i2c_read(uint8_t ack)
45
{
46
  uint8_t tmp=0, cnt=8;
47
48
  for (; cnt>0; cnt--) {
49
    SCL_HIGH
50
    tmp <<= 1;
51
    if (SDA) tmp |= 0x01;
52
    SCL_LOW
53
  }
54
  if (ack) SDA_LOW else SDA_HIGH
55
  SCL_HIGH
56
  SCL_LOW
57
  SDA_HIGH
58
  return tmp;
59
}
60
61
// ein Byte in den EEPROM per I2C schreiben
62
63
void i2c_write_byte(uint16_t address, uint8_t data) {
64
65
  i2c_start();
66
  i2c_write(0xA0);
67
  i2c_write(address>>8);
68
  i2c_write(address & 0xFF);
69
  i2c_write(data);
70
  i2c_stop();
71
}
72
73
// ein Byte aus dem EEPROM per I2C lesen
74
75
uint8_t i2c_read_byte(uint16_t address) {
76
77
  uint8_t tmp;
78
79
  // Adresse schreiben
80
81
  i2c_start();
82
  i2c_write(0xA0);
83
  i2c_write(address>>8);
84
  i2c_write(address & 0xFF);
85
  i2c_stop();
86
87
  // Byte lesen
88
  i2c_start();
89
  i2c_write(0xA1);
90
  tmp=i2c_read(0);
91
  i2c_stop();
92
93
  return tmp;
94
}
95
96
// einen Block aus dem EEPROM per I2C lesen
97
98
void i2c_read_block(uint16_t address, uint8_t *buffer, uint16_t count) {
99
100
  // Adresse schreiben
101
102
  i2c_start();
103
  i2c_write(0xA0);
104
  i2c_write(address>>8);
105
  i2c_write(address & 0xFF);
106
  i2c_stop();
107
108
  i2c_start();
109
  i2c_write(0xA1);
110
111
  while(count>1) {
112
    *buffer=i2c_read(1);
113
    buffer++;
114
  }
115
  *buffer=i2c_read(0);    // NACK für letztes Byte
116
  i2c_stop();
117
}
118
119
// einen Block konstanter Daten in den EEPROM scheiben
120
// Page Ausrichtung muss vom aufrufenden Programm geprüft werden
121
122
void i2c_write_cblock(uint16_t address, uint8_t cnt, uint8_t data) {
123
124
  // Adresse schreiben
125
126
  i2c_start();
127
  i2c_write(0xA0);
128
  i2c_write(address>>8);
129
  i2c_write(address & 0xFF);
130
131
  for(; cnt>0; cnt--) {
132
    i2c_write(data);
133
  }
134
  i2c_stop();        // Start des Schreibzugriffs
135
}

MFG
Falk

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.