Hallo, ich hab da ein Problem mit meinem Versuchsaufbau von 2 µC ( mega32 als Master, mega 8 als Slave) die per I2C daten austauschen sollen. Zum Betrieb der i2c(twi) schnittstelle nutze ich die libs von http://www.jtronics.de . Also ich habe es jetzt soweit hinbekommen das ich daten von master zum slave senden kann, diese kommen auch richtig an. Allerdings bekomm ich die Daten nicht wieder vom Master aus zurück gelesen bzw. die datenbytes haben immer den inhalt "0". Gedacht war es meinerseits so das (zu Testzwecken) der Master 3 Bytes an den Slave sendet und nach erfolgtem senden in ein defniertes Statusbyte das 1 Bit setzt. Dies klappt auch. Allerdings wenn der Master dieses Statusbyte ausliest erhällt der Master immer ne "0". Hoffe ihr könnt mir helfen hier mal der code vom master:
1 | |
2 | //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
3 | |
4 | // Hauptprogramm für den ClockClock Master
|
5 | |
6 | // µC :ATmega32
|
7 | |
8 | // CPU Takt : 16MHz
|
9 | |
10 | // Funktionsbeschreibung:
|
11 | |
12 | //------------------------------
|
13 | |
14 | // Version: V0.1
|
15 | // Datum: 07.08.12
|
16 | |
17 | |
18 | |
19 | //------------------------------
|
20 | |
21 | //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
22 | |
23 | #include <avr/io.h> |
24 | #include <avr/interrupt.h> |
25 | #include "uart.h" //Enthällt uart funktionen (Achtung uart.c muss in makefile eingetragen werden, wenn dies nicht von der ide gemacht wird) |
26 | #include <stdlib.h> // enthällt die Umwandlung von int zu char (itoa) |
27 | #include <util/delay.h> // Enthällt delay funktionen |
28 | #include <avr/wdt.h> // Enthält Watchdog Funktionen |
29 | #include <cc_com.h> // Definitionen für die I2C Kommunikation zwischen den Baugruppen |
30 | |
31 | #include <avr/pgmspace.h> |
32 | #include "i2cmaster.h" |
33 | |
34 | // Definitionen
|
35 | |
36 | #ifndef F_CPU
|
37 | #define F_CPU 16000000UL // CPU Takt in Hz
|
38 | #endif
|
39 | #define UART_BAUD_RATE 9600
|
40 | |
41 | |
42 | |
43 | //Deklaration der Variablen
|
44 | |
45 | volatile unsigned char count_100ms = 0; |
46 | volatile unsigned char count_500ms = 0; |
47 | volatile unsigned char count_1s = 0; |
48 | volatile unsigned char timestamp = 0; // Zeitstempel byte |
49 | //( Bit3 = 100ms; Bit4 = 500ms; Bit5= 1s)
|
50 | volatile unsigned char ccs_data = 0; // Buffer zur Speicherung der vom Slave emfpangenen Daten |
51 | int data =0; |
52 | |
53 | //Deklaration der Funktionsprototypen
|
54 | |
55 | void send_int_uart(int value); // Deklaration für UART INt SEND Unterfunktion |
56 | |
57 | |
58 | void I2CWrite_CCS(uint8_t ADDR, uint8_t CMD, uint8_t DATA) // Funktion zum senden von Daten an I2C Slave ( CCS = ClocClock Slave) |
59 | {
|
60 | i2c_start_wait(ADDR+I2C_WRITE); // set device address and write mode |
61 | i2c_write(CMD); // write command |
62 | i2c_write(DATA); // write data |
63 | i2c_stop(); // set stop conditon = release bus |
64 | }
|
65 | |
66 | |
67 | unsigned char I2CRead_CCS(uint8_t ADDR, uint8_t CMD) // Funktion zum lesen von Daten aus I2C Slave ( CCS = ClocClock Slave) |
68 | {
|
69 | int data; |
70 | i2c_start_wait(ADDR+I2C_WRITE); // set device address and write mode |
71 | i2c_write(CMD); // write command, sendet Startpostion der Leseadresse an Slave |
72 | i2c_rep_start (ADDR+I2C_READ); // Repeated Start |
73 | data = i2c_readNak(); // Liest akutelle Bufferposition vom Slave aus und schrebit sie in die variable "ccs_data" |
74 | i2c_stop(); // set stop conditon = release bus |
75 | return data; // Gibt das gelesene Byte an funktion zurück |
76 | }
|
77 | |
78 | |
79 | //Interrupts
|
80 | |
81 | |
82 | // Aktion bei Timer 1 Overflow (alle 100ms)
|
83 | ISR (TIMER1_OVF_vect) |
84 | {
|
85 | ++count_100ms; // Intervallzähler inkrementieren |
86 | TCNT1 = 40536; // Timer1 vorladen damit er nach 100ms überläuft |
87 | }
|
88 | |
89 | // Hauptschleife
|
90 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
91 | int main (void) // Start Hauptschleife |
92 | {
|
93 | |
94 | // Eingänge definieren
|
95 | |
96 | |
97 | |
98 | // Ausgänge definieren
|
99 | DDRD |=(1<< PD1); //UART Tx |
100 | DDRD |=(1<< PD5); //Test Led1 |
101 | DDRD |=(1<< PD6); //Test Led2 |
102 | |
103 | // UART initialisieren
|
104 | |
105 | uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); |
106 | |
107 | |
108 | // Startkonfig Timer 1
|
109 | |
110 | TCCR1B |= (1<<CS10); // Prescaler /64 = Overflow alle 100ms und Timer starten |
111 | TCCR1B |= (1<<CS11); // |
112 | |
113 | TIMSK |= (1<<TOIE1); // Overlfow ISR erlauben |
114 | |
115 | |
116 | TCNT1 = 40536; // TImer1 vorladen damit er nach 100ms überläuft |
117 | |
118 | // I2C initialisieren
|
119 | |
120 | i2c_init(); |
121 | |
122 | |
123 | // Global Interrupts aktivieren
|
124 | sei(); |
125 | |
126 | |
127 | |
128 | while(1) // Start Dauerschleife |
129 | {
|
130 | |
131 | //Zeit setzen
|
132 | if ( count_100ms == 1) // 100ms |
133 | {
|
134 | timestamp |= ((1 << 3)); |
135 | ++count_500ms; |
136 | count_100ms = 0; |
137 | }
|
138 | |
139 | if ( count_500ms == 5) // 500ms |
140 | {
|
141 | timestamp |= ((1 << 4)); |
142 | ++count_1s; |
143 | count_500ms = 0; |
144 | }
|
145 | |
146 | if ( count_1s ==2) // 1s |
147 | {
|
148 | timestamp |= ((1 << 5)); |
149 | count_1s = 0; |
150 | }
|
151 | |
152 | |
153 | // Test Taster
|
154 | |
155 | if((PIND &(1<<PD2))) |
156 | {
|
157 | |
158 | for(int address = CCS_ADDRESS_START ; address<= CCS_ADDRESS_END;address++) |
159 | {
|
160 | uart_puts("Statusabfrage von Slaveadresse:"); |
161 | send_int_uart(address); |
162 | ccs_data = I2CRead_CCS(address,CCS_STATUS);// Status des akutellen Slaves prüfen |
163 | uart_puts("Status:"); |
164 | send_int_uart(ccs_data); |
165 | uart_puts("\n\r"); |
166 | |
167 | if(ccs_data & CCS_NEW_DATA) |
168 | |
169 | {
|
170 | // Wenn noch Daten vom Slave verarbeitet werden passiert nix
|
171 | uart_puts("Slaveadresse:"); |
172 | send_int_uart(address); |
173 | uart_puts("verarbeit noch alte Daten"); |
174 | uart_puts("\n\r"); |
175 | |
176 | }
|
177 | |
178 | else
|
179 | |
180 | {
|
181 | data = 0; |
182 | |
183 | uart_puts("Neue Daten werden an Slave gesendet..."); |
184 | uart_puts("\n\r"); |
185 | |
186 | for (int i = CC_DATA_START; i<= CC_DATA_END; i++) |
187 | {
|
188 | ++data; // Testdaten |
189 | I2CWrite_CCS(address, i, data); |
190 | uart_puts("Block Nr."); |
191 | send_int_uart(i); |
192 | uart_puts(", Inhalt:"); |
193 | send_int_uart(data); |
194 | uart_puts("\n\r"); |
195 | }
|
196 | I2CRead_CCS(address,CCS_STATUS);// Status des akutellen Slaves prüfen |
197 | ccs_data |= CCS_NEW_DATA; |
198 | I2CWrite_CCS(address, CCS_STATUS, ccs_data); // Für Slave markieren das neue Daten da sind |
199 | }
|
200 | }
|
201 | }
|
202 | |
203 | |
204 | //Zeitgesteuerte Aktionen
|
205 | |
206 | //100ms
|
207 | if ((timestamp & (1<<3))) |
208 | {
|
209 | |
210 | timestamp &= ~((1 << 3)); // Zetistempelbit 100ms löschen |
211 | }
|
212 | |
213 | //500ms
|
214 | if ((timestamp & (1<<4))) |
215 | {
|
216 | |
217 | timestamp &= ~((1 << 4)); // Zetistempelbit 500ms löschen |
218 | }
|
219 | //1s
|
220 | if ((timestamp & (1<<5))) |
221 | {
|
222 | |
223 | |
224 | |
225 | |
226 | timestamp &= ~((1 << 5)); // Zetistempelbit 1s löschen |
227 | }
|
228 | }//Ende Dauerschleife |
229 | }//Ende Hauptschleife |
230 | |
231 | //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
232 | |
233 | //Unterfunktion Integerwert über uart ausgeben
|
234 | void send_int_uart(int value) |
235 | {
|
236 | char buffer [33]; |
237 | itoa (value,buffer,10); |
238 | uart_puts(buffer); |
239 | }
|
und hier der vom Slave:
1 | |
2 | //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
3 | |
4 | // Demoprogramm für den ClockClock Slave
|
5 | |
6 | // µC :ATmega8
|
7 | |
8 | // CPU Takt : 8MHz
|
9 | |
10 | // Funktionsbeschreibung:
|
11 | |
12 | //------------------------------
|
13 | |
14 | // Version: V0.1
|
15 | // Datum: 05.08.12
|
16 | |
17 | |
18 | |
19 | //------------------------------
|
20 | |
21 | //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
22 | |
23 | #include <avr/io.h> |
24 | #include <avr/interrupt.h> |
25 | #include "uart.h" //Enthällt uart funktionen (Achtung uart.c muss in makefile eingetragen werden, wenn dies nicht von der ide gemacht wird) |
26 | #include <stdlib.h> // enthällt die Umwandlung von int zu char (itoa) |
27 | #include <util/delay.h> // Enthällt delay funktionen |
28 | #include <avr/wdt.h> // Enthält Watchdog Funktionen |
29 | #include <cc_com.h> // Definitionen für die I2C Kommunikation zwischen den Baugruppen |
30 | |
31 | #include <avr/pgmspace.h> |
32 | |
33 | #include "twislave.h" |
34 | |
35 | // Definitionen
|
36 | |
37 | #define TIMER1_preload 53036
|
38 | |
39 | #ifndef F_CPU
|
40 | #define F_CPU 8000000UL // CPU Takt in Hz
|
41 | #endif
|
42 | #define UART_BAUD_RATE 9600
|
43 | #define SLAVE_ADRESSE 0x40 // Slave-Adresse, wenn niederwertigstes Bit = 1 ist,
|
44 | // sind General Call Anfragen erlaubt
|
45 | |
46 | |
47 | //Deklaration der Variablen
|
48 | |
49 | int read = 0; |
50 | |
51 | volatile unsigned char count_100ms = 0; |
52 | volatile unsigned char count_500ms = 0; |
53 | volatile unsigned char count_1s = 0; |
54 | volatile unsigned char timestamp = 0; // Zeitstempel byte |
55 | //( Bit3 = 100ms; Bit4 = 500ms; Bit5= 1s)
|
56 | |
57 | |
58 | //Deklaration der Funktionsprototypen
|
59 | |
60 | void send_int_uart(int value); // Deklaration für UART INt SEND Unterfunktion |
61 | |
62 | |
63 | void Initialisierung(void) |
64 | {
|
65 | cli(); |
66 | |
67 | init_twi_slave(SLAVE_ADRESSE); //TWI als Slave mit Adresse slaveadr starten |
68 | |
69 | sei(); |
70 | }
|
71 | |
72 | |
73 | //Interrupts
|
74 | |
75 | |
76 | // Aktion bei Timer 1 Overflow (alle 100ms)
|
77 | ISR (TIMER1_OVF_vect) |
78 | {
|
79 | ++count_100ms; // Intervallzähler inkrementieren |
80 | TCNT1 = 53036; // Timer1 vorladen damit er nach 100ms überläuft |
81 | }
|
82 | |
83 | |
84 | |
85 | |
86 | |
87 | // Hauptschleife
|
88 | //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
89 | int main (void) // Start Hauptschleife |
90 | {
|
91 | |
92 | |
93 | |
94 | |
95 | // Eingänge definieren
|
96 | |
97 | |
98 | |
99 | // Ausgänge definieren
|
100 | DDRD |=(1<< PD1); //UART Tx |
101 | DDRD |=(1<< PD5); //Test Led1 |
102 | DDRD |=(1<< PD6); //Test Led2 |
103 | |
104 | // UART initialisieren
|
105 | |
106 | uart_init( UART_BAUD_SELECT(UART_BAUD_RATE,F_CPU) ); |
107 | |
108 | |
109 | // Startkonfig Timer 1
|
110 | |
111 | TCCR1B |= (1<<CS10); // Prescaler /64 = Overflow alle 100ms und Timer starten |
112 | TCCR1B |= (1<<CS11); // |
113 | |
114 | TIMSK |= (1<<TOIE1); // Overlfow ISR erlauben |
115 | |
116 | |
117 | TCNT1 = 53036; // TImer1 vorladen damit er nach 100ms überläuft |
118 | |
119 | |
120 | Initialisierung(); //I2C init |
121 | |
122 | |
123 | // Global Interrupts aktivieren
|
124 | sei(); |
125 | |
126 | |
127 | |
128 | while(1) // Start Dauerschleife |
129 | {
|
130 | |
131 | //Zeit setzen
|
132 | if ( count_100ms == 1) // 100ms |
133 | {
|
134 | timestamp |= ((1 << 3)); |
135 | ++count_500ms; |
136 | count_100ms = 0; |
137 | }
|
138 | |
139 | if ( count_500ms == 5) // 500ms |
140 | {
|
141 | timestamp |= ((1 << 4)); |
142 | ++count_1s; |
143 | count_500ms = 0; |
144 | }
|
145 | |
146 | if ( count_1s ==2) // 1s |
147 | {
|
148 | timestamp |= ((1 << 5)); |
149 | count_1s = 0; |
150 | }
|
151 | |
152 | |
153 | //Zeitgesteuerte Aktionen
|
154 | |
155 | //100ms
|
156 | if ((timestamp & (1<<3))) |
157 | {
|
158 | |
159 | timestamp &= ~((1 << 3)); // Zetistempelbit 100ms löschen |
160 | }
|
161 | |
162 | //500ms
|
163 | if ((timestamp & (1<<4))) |
164 | {
|
165 | uart_puts("CCS Status:"); |
166 | uart_puts("\t"); |
167 | send_int_uart(rxbuffer[CCS_STATUS]); |
168 | uart_puts("\n\r"); |
169 | timestamp &= ~((1 << 4)); // Zetistempelbit 500ms löschen |
170 | }
|
171 | |
172 | |
173 | |
174 | //1s
|
175 | if ((timestamp & (1<<5))) |
176 | {
|
177 | |
178 | timestamp &= ~((1 << 5)); // Zetistempelbit 1s löschen |
179 | }
|
180 | |
181 | |
182 | if((rxbuffer[CCS_STATUS] & CCS_NEW_DATA ) && (read == 0) ) // |
183 | |
184 | |
185 | {
|
186 | uart_puts("CCS Status:"); |
187 | uart_puts("\t"); |
188 | send_int_uart(rxbuffer[CCS_STATUS]); |
189 | uart_puts("\n\r"); |
190 | |
191 | read = 0; |
192 | |
193 | uart_puts("Daten von Master erhalten:"); |
194 | uart_puts("\n\r"); |
195 | |
196 | uart_puts("CCS Status:"); |
197 | uart_puts("\t"); |
198 | send_int_uart(rxbuffer[CCS_STATUS]); |
199 | uart_puts("\n\r"); |
200 | |
201 | |
202 | |
203 | for (int i = CC_DATA_START; i<= CC_DATA_END; i++) |
204 | {
|
205 | uart_puts("Datenblock Nr:"); |
206 | send_int_uart(i);uart_puts("\t"); |
207 | uart_puts("Inhalt:"); |
208 | send_int_uart(rxbuffer[i]); |
209 | uart_puts("\n\r"); |
210 | }
|
211 | |
212 | read = 1; |
213 | }
|
214 | |
215 | |
216 | if((PIND &(1<<PD2))) |
217 | {
|
218 | |
219 | rxbuffer[CCS_STATUS] &= ~(CCS_NEW_DATA); // Alle neuen Daten verarbeitet, bit löschen |
220 | |
221 | uart_puts("Taster 1 beaetigt, Datenempfang wird dem Master bestaetigt:"); |
222 | uart_puts("\n\r"); |
223 | }
|
224 | |
225 | |
226 | |
227 | }//Ende Dauerschleife |
228 | }//Ende Hauptschleife |
229 | |
230 | //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
231 | |
232 | //Unterfunktion Integerwert über uart ausgeben
|
233 | void send_int_uart(int value) |
234 | {
|
235 | char buffer [33]; |
236 | itoa (value,buffer,10); |
237 | uart_puts(buffer); |
238 | }
|