Guten Abend zusammen
Ich versuche derzeit ein M24M01 EEPROM zum laufen zu bringen...
Es hängt an einem mit 3.3V betriebenen Atmega324p mit 10MHZ AVR
Frequenz...
Hier das Datenblatt:
http://www.stm8circle.com/resources/Datasheets/M24M01-HR.pdf
So ca. Seite 16
Das problem ist, wenn ich etwas schreibe, und dannach lese, bekomme ich
nach dem senden der Adresse für den Random Read kein ACK mehr.
Lese ich jedoch ohne vorher geschrieben zu haben, so bekomme ich ein
ACK.
Anbei mal die Logicanalyzer Daten...
Ich habe zwischen den einzelnen Byteblöcken pausen gemacht, damit es
übersichtlicher wird.
Ich hoffe jemand sieht einen fehler und kann mir helfen :)
Danke schonmal
Hier noch meine Routinen:
1 | #define set_output DDRA |= ( 1 << DDA4);
|
2 | #define set_input DDRA &= ~( 1 << DDA4 );
|
3 |
|
4 | // -> Delay für die Pausen beträgt 25us
|
5 |
|
6 | void I2C_Start(void)
|
7 | {
|
8 | set_output;
|
9 | SDA_1;
|
10 | SCL_1;
|
11 | _delay_us(I2C_Delay);
|
12 | SDA_0;
|
13 | _delay_us(I2C_Delay);
|
14 | SCL_0;
|
15 | }
|
16 |
|
17 | void I2C_Clock(void)
|
18 | {
|
19 | SCL_0;
|
20 | _delay_us(I2C_Delay);
|
21 | SCL_1;
|
22 | _delay_us(I2C_Delay);
|
23 | SCL_0;
|
24 | }
|
25 |
|
26 | //SCL = 1 SDA 0 -> 1
|
27 | void I2C_Stop(void)
|
28 | {
|
29 | set_output;
|
30 | SDA_0;
|
31 | SCL_1;
|
32 | _delay_us(I2C_Delay);
|
33 | SDA_1;
|
34 | _delay_us(I2C_Delay);
|
35 | SCL_0;
|
36 | }
|
37 |
|
38 | unsigned char i2c_rx(char ack)
|
39 | {
|
40 | char x, d=0;
|
41 | set_input;
|
42 | for(x=0; x<8; x++) {
|
43 | d <<= 1;
|
44 | SCL_1;
|
45 | _delay_us(I2C_Delay);
|
46 | if(SDA) d |= 1;
|
47 | SCL_0;
|
48 | _delay_us(I2C_Delay);
|
49 | }
|
50 | set_output;
|
51 | if(ack) SDA_0;
|
52 | else SDA_1;
|
53 | SCL_1;
|
54 | _delay_us(I2C_Delay); // send (N)ACK bit
|
55 | SCL_0;
|
56 | return d;
|
57 | }
|
58 |
|
59 | void I2C_Send_8(unsigned char ucData)
|
60 | {
|
61 | unsigned char ucCounter = 0;
|
62 | unsigned char ucTemp = 0;
|
63 | set_output;
|
64 | while(ucCounter != 8)
|
65 | {
|
66 | ucTemp = ucData & 0x80;
|
67 | if(ucTemp > 0) SDA_1;
|
68 | if(ucTemp == 0) SDA_0;
|
69 | ucData = ucData << 1;
|
70 | I2C_Clock();
|
71 | ucCounter++;
|
72 | }
|
73 | set_input;
|
74 | _delay_us(I2C_Delay);
|
75 | SCL_1;
|
76 | while(SDA);
|
77 | _delay_us(I2C_Delay);
|
78 | SCL_0;
|
79 | }
|
80 |
|
81 |
|
82 |
|
83 | void I2C_Write_17bit(unsigned char ucI2CAddr, unsigned long uiAddr, unsigned char ucData)
|
84 | {
|
85 | I2C_Start();
|
86 | _delay_us(200);
|
87 | I2C_Send_8((ucI2CAddr & 0xFC)| ((uiAddr >> 15) & 0x02) ); //Adresse ausgeben RW = 0 und A16 setzen (beachte das Datenblatt: Seite 11 http://cdn.shopify.com/s/files/1/0038/9582/files/m24m01-r.pdf?1271986432
|
88 | _delay_us(200);
|
89 | I2C_Send_8((uiAddr & 0xFF00) >> 8);
|
90 | _delay_us(200);
|
91 | I2C_Send_8(uiAddr & 0x00FF);
|
92 | _delay_us(200);
|
93 | I2C_Send_8(ucData); //nack
|
94 | _delay_us(200);
|
95 | I2C_Stop();
|
96 | }
|
97 |
|
98 |
|
99 | unsigned char I2C_Read_17bit(unsigned char ucI2CAddr, unsigned long uiAddr)
|
100 | {
|
101 | unsigned char temp = 0;
|
102 |
|
103 | I2C_Start();
|
104 | _delay_us(200);
|
105 | I2C_Send_8((ucI2CAddr & 0xFC) | ((uiAddr >> 15) & 0x02) );
|
106 | _delay_us(200);
|
107 | I2C_Send_8((uiAddr & 0xFF00) >> 8);
|
108 | _delay_us(200);
|
109 | I2C_Send_8(uiAddr & 0x00FF);
|
110 | _delay_us(200);
|
111 | I2C_Start();
|
112 | _delay_us(200);
|
113 | I2C_Send_8(((ucI2CAddr & 0xFD) | ((uiAddr >> 15) & 0x2)) | 0x01 ); //Lesen
|
114 | _delay_us(200);
|
115 | temp = i2c_rx(0); //NACK
|
116 | _delay_us(200);
|
117 | I2C_Stop();
|
118 | return temp;
|
119 | }
|