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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.