Ich habe mich jetzt mal in I2C eingelesen und frage mich ob ich so richtig denke. Also, ich erteile dem Slave eine Adresse, nun habe ich das wie folgt verstanden: Master: I2C Start I2C Schreibe Adresse + Write I2C Schreibe byte I2C Stop Das ist ja die Übertragung. Nun habe ich wie folgt verstanden das, sobald der Slave seine Adresse "verstanden" hat in einen ISR springt und dort dann die register, eins nach dem anderen einliest. Ist das so richtig? Demach könnte ich als "erstes" Byte eine länge der Daten senden und auf dem Slave dann eine schleife mit der Anzahl der länge laufen lassen, richtig? Also auf dem Master: Sende start Sende adresse+write Sende länge Sende bytes in schleife Sende checksumme Sende stop Und auf dem slave: Empfange adresse Springe ISR Lese erstes byte (länge) Führe schleife in anzahl der länge aus Lese checksumme Führe programm aus Habe ich das so richtig verstanden? Dann muss ich nur noch gucken wie es vom slave zum master geht. Danke euch schonmal.
Hallo Tobias, auf Anhieb würde ich sagen, Du hast hier einen speziellen Fall beschrieben. Das Protokoll für einen PCF8574 ist etwas einfacher. Wenn Du Dich da praktisch einarbeiten möchtest, dann fang mit dem PCF8574 an. Der ist ziemlich simpel und unkritisch. mfg klaus
Ich möchte halt atmega <-> atmega Ich prügel mich da schon durch g Mir ging es nur darum ob der "ablauf" so richtig ist!?
Schau mal bei TI nach, MSP430. Da gibt es auch Beispiele für I2C Master-Client Komunikation. Aber im Prinzip müsste Dein Ansatz so OK sein. Du erstellst das Protokoll ja selber. Ansonsten ähneln sich die Protokolle der I2C-Bausteine. Aber in jedem Datenblatt findest Du trotzdem dazu eine spezielle Protokollbeschreibung. mfg Klaus
Tobias N. schrieb: > Ich möchte halt atmega <-> atmega > > Ich prügel mich da schon durch *g* > > Mir ging es nur darum ob der "ablauf" so richtig ist!? Richtig ist das was du als richtig definierst. Einem Telefon ist es auch egal, ob du reinpfeifst oder deine Nachricht in Form von Rülpsern übermittelst. Das Telefon stellt den Übertragunskanal bereit, wie deine Botschaften dann aussehen, ist dein Bier (so etwas nennt man ein Protokoll) Also: wenn du das so machen willst, dann mach das so. Nur das man beim Client keine Schleife machen wird. Wenn per I2C was reinkommt, dann 'benachrichtigt' die Hardware ds Programm mit einem Interrupt. In diesem Interrupt entscheidest du dann, was das gerade eingetroffene Byte für eine Bedeutung hat und was du damit machst. Ist es das erste Byte in der Übertragung, dann speicherst du es dir als Länge der noch zu empfangenden Bytes ab, ist es nicht das erste Byte, dann speicherst du das Byte als Datenbyte ab und erniedrigst diesen Längenzähler um 1. Wird so der Längenzähler zu 0, dann weisst du, dass damit die Nachricht komplett übertragen wurde. In den vielen Fällen muss man in der µC Programmierung weg von dieser 'Ich mach was in einer Schleife' Denkweise. Man muss hin zu einer 'Ich wache gerade auf, finde diese Inforamtion vor, was mache ich damit ehe ich wieder schlafen gehe' Denkweise.
Ich dachte dann so:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
Habe da noch eine Frage. Wird die ISR mit jedem Byte was empfangen wird aufgerufen oder wird diese aufgerufen sobald die Slave Adresse erkannt wurde und arbeitet dann bis zum Stop?
Gast
#3827659
TWI auf den AVRs ist quasi alles zu Fuss, jedes Byte einzeln.
Gast
#3827732
------ Arduino: i2c avr <--> avr "mal eben machen" ist schon einfacher mit Arduino: http://arduino.cc/en/Tutorial/MasterReader ------ AVR: AVR311 PDF: http://www.atmel.com/images/doc2565.pdf AVR311 Software: http://www.atmel.com/Images/AVR311.zip (geht wohl mit avr-gcc nicht?!) ---> dann halt diese modifizierte hier: https://github.com/kelvinlawson/avr311-twi-slave-gcc AVR TWI Master und Slave Funtionen in C Beitrag "AVR TWI Master und Slave Funtionen in C"
Karl Heinz schrieb: > Nur das man beim > Client keine Schleife machen wird. Wenn per I2C was reinkommt, dann > 'benachrichtigt' die Hardware ds Programm mit einem Interrupt. In diesem > Interrupt entscheidest du dann, was das gerade eingetroffene Byte für > eine Bedeutung hat und was du damit machst. Ist es das erste Byte in der > Übertragung, dann speicherst du es dir als Länge der noch zu > empfangenden Bytes ab, ist es nicht das erste Byte, dann speicherst du > das Byte als Datenbyte ab und erniedrigst diesen Längenzähler um 1. Wird > so der Längenzähler zu 0, dann weisst du, dass damit die Nachricht > komplett übertragen wurde. Jein. ich mach das immer etwas anders: Ich definiere mir einen Empfangspuffer mit einer definierten Größe, sodass die maximal erwartete Nachricht noch Platz hat. Danach empfange ich Byte für Byte, kümmere mich an der Stelle aber überhaupt nicht darum welche Bedeutung die Bytes haben (ob das erste Byte eine Länge oder eine Registernummer oder die relative Mondfeuchtigkeit ist, ist an der Stelle irrelevant). Solange ich noch Platz im Buffer für das gerade empfangene Byte habe, speichere ich das Byte und antworte ich mit ACK, hab ichs nicht mehr Platz, mit NACK. Danach stelle ich den Buffer und die Länge des empfangenen Pakets der darüberliegenden Schicht zur Verfügung. Was die damit macht, ist mir auch wieder egal. Tobias N. schrieb: > ISR (TWI_vect) > { > len = read_Ack(); // Erstes Byte ist die Länge. > > for(i=0;i <len; i++) > { > buf[i] = read_Ack(); // Lese Byte für Byte ein und schreibe in > Array > } > len = read_Nack(); // weiss nicht ob das wichtig ist > return buf; > } Da denkst du grad ziemlich verkehrt: die TWI-ISR wird für jeden Vorgang am TWI aufgerufen (adressierung, byte empfangen usw) da drinnen kannst du kein read_Ack() machen.
Dann muss ich über das isr alles auswerten? Also auch die adresse, lesen oder schreiben, und die einzelnen bytes. Also: start signal -> isr Adresse -> isr Jedes byte -> isr Stop signal -> isr So? Also springt er jedesmal in die isr!? Danke euch schonmal.
Tobias N. schrieb: > So? Also springt er jedesmal in die isr!? Ja, korrekt. Wobai man am Master noch die Wahl hat, ob man I2C mit oder ohne Interrupt realisiert (ohne ist gebräuchlicher), den Slave kann man sinnvollerweise nur mit ISR implementieren.
Also in etwa so:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
Nur mal so grob aber so in etwa sollte das ja dann sein, oder?
Tobias N. schrieb: > Nur mal so grob aber so in etwa sollte das ja dann sein, oder? nein, eigentlich überhaupt nicht :-( Am AVR (zumindest auf den "großen" wie ATmega) gibt dir die TWI-Hardware schon die Rahmenbedingungen für die State Machine vor, gesteuert über TWSR (TWI Status Register). Dazu gibts eine wunderbare Beschreibung mit wunderbaren Tabellen im Datenblatt. Arbeite das mal durch. Wenn schon dann sähe es etwa so aus:
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | |
14 | |
15 | |
16 | |
17 | |
18 | |
19 | |
20 | |
21 | |
22 | |
23 | |
24 | |
25 | |
26 | |
27 | |
28 | |
29 | |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | |
39 | |
40 | |
41 | |
42 | |
43 | |
44 | |
45 | |
46 | |
47 | |
48 | |
49 | |
50 | |
51 | |
52 | |
53 | |
54 | |
55 | |
56 | |
57 | |
58 | |
59 | |
60 | |
61 | |
62 | |
63 | |
64 | |
65 | |
66 | |
67 | |
68 | |
69 | |
70 | |
71 | |
72 | |
73 | |
74 | |
75 | |
76 | |
77 | |
78 | |
79 | |
80 | |
81 | |
82 | |
83 | |
84 | |
85 | |
86 | |
87 | |
Wie du vielleicht erkennst: I2C ist keine Anfängerkost...
Aahh. In TWCR steht drinne ob Start oder adresse+R oder adresse+W also muss ich jedesmal nur das Register auslesen und auswerten :) Wird ja immer einfacher die ganze Sache g
Tobias N. schrieb: > In TWCR steht drinne ob Start oder adresse+R oder adresse+W also muss > ich jedesmal nur das Register auslesen und auswerten :) nein. Tobias N. schrieb: > Wird ja immer einfacher die ganze Sache nein. Bitte - lies dir im Datenblatt das Kapitel zu TWI, und danach die AVR311 "Using the TWI module as I2C slave". Sonst wird das nix. nochmal: LIES DAS! Vorher kriegst du von mir keine Antwort mehr.
Antwort schreiben
Bitte melde dich an, um einen Beitrag zu schreiben.