Forum: Mikrocontroller und Digitale Elektronik I2C Protokoll erstellen


von Matze T. (timemy)


Lesenswert?

Hallo,

ich habe folgendes Problem: Ich möchte einen Atmel Atmega168 über USB 
ansteuern, dies realisiere ich mit einem FTDI Chip. Die Daten die ich 
ihm darüber schicke wollte ich per I2C weiterleiten an meinen Empfänger 
(wahrscheinlich einen Adressbaustein mit dem ich dann verschiedene 
Relais, LED´s, usw ansteuere).
So nun zum Problem:
Wie erstelle ich mir so einen "Wandler" der mir die Daten vom UART in 
ein I2C "wandelt".
Ich habe mich schon ein bisschen Informiert und stelle mir das Protokoll 
so vor:

Art        Aktion-Adressbit-Datenbits-Bestätigung
Schreiben : WR__Adresse_Data_Data_Data_..8mal.._ACK
Lesen     : RD__Adresse_Data_Data_Data_..8mal.._ACK

Ich programmiere das ganze mit dem AVR-Studio.
Wäre für jede Info und eventuelle Beispiele zum Verständnis, wie ich das 
angehen muss, dankbar.

MfG

von Thomas P. (tpircher) Benutzerseite


Lesenswert?

Also du willst ein ASCII-basiertes Protokoll implementieren?
Der "wandler" heisst Parser oder Kommando Interpreter. Diese koennen 
sehr kompliziert werden und bei groesseren Projekten werden Parser 
Generatoren (wie flex und bison) verwendet. Parser fuer AVRs werden 
meist von Hand geschrieben, da diese viel kleiner und schneller sind. 
Wenn du nach "parser" suchst wirst du eine Menge im Web finden.

Ein Kritikpunkt zu deinem skizzierten Protokoll ist dass du nicht 
mehrere Lese- und Schreib-Operationen in einem Rutsch machen kannst. Mit 
anderen Worten, du kannst z.B. kein Repeated Start generieren.

Eigenwerbung:
userial (http://www.tty1.net/userial/) implementiert ein Protokoll 
(siehe http://www.tty1.net/userial/manual/userial.html), welches alle 
I2C Operationen auf dem Bus durchfuehren kann. Beispiele sind in der 
Dokumentation angefuehrt.

Die Implementation ist ein wenig kompliziert, da zuerst das 
vollstaendige Kommando auf Syntaktische Korrektheit geprueft wird. Erst 
anschliessen wird das Kommando ausgefuehrt.

Thomas

von Matze T. (timemy)


Lesenswert?

Danke Thomas für die schnelle Antwort (sau schnell),

Das mit dem Aufbau des Protokoll´s ist echt gut erklärt, Mir ist nur die 
Prgrammstruktur noch nicht ganz klar.
Ich erstelle also eine Funktion z.B.


I2C_Senden(void)
{
//schreibe ihm hier den Clock und den Aufbau vor
}
I2C_Empfangen(void)
{
//Aufbau des Empfangsprotokolls
}

so und in der main unterscheide ich dann anhand des ersten Bits, ob 
Lesen oder schreiben und rufe je nachdem die dazugehörige Funktion auf. 
Könnte das so klappen?? Woher weiß der µC sonst was ich machen möchte?? 
Er muss ja das erste Bit lesen um zu entscheiden. Und woher weiß er 
Welche Daten vom PC kommen was aussagen?? Muss ich diese 
zwischenspeichern und dann einzeln auswerten??
Ich stell viell grad blöde fragen, aber ich möchte es halt auch 
verstehen und nicht einfach nur machen.
Danke

MfG

von Thomas P. (tpircher) Benutzerseite


Lesenswert?

Matze Timemy wrote:
> I2C_Senden(void)
> I2C_Empfangen(void)

Wahrscheinlich wirst du auch Parameter an die Funktionen uebergeben 
wollen, z.B.:
1
void I2C_Senden(const unsigned char *data, unsigned char len);
data ist ein Array mit den Werten die du senden willst und len ist die 
Anzahl an Bytes in data.
1
void I2C_Empfangen(unsigned char *data, unsigned char len);
data ist ein Buffer der Groesse len und wird von I2C_Empfangen() mit den 
gelesenen Bytes ueberschrieben.

Obige Funktionen sehen keine Moeglichkeit vor, dem aufrufenden Programm 
etwaige Fehlermeldungen zu signalisieren. Das kann aber einfach durch 
einen boolean oder Integer als Rueckgabewert bewerkstellight werden.

> so und in der main unterscheide ich dann anhand des ersten Bits, ob
> Lesen oder schreiben und rufe je nachdem die dazugehörige Funktion auf.

Anhand des Least Significant Bits im Adress-Byte wolltest du sagen? Ja, 
das ist in Ordnung so.

> Er muss ja das erste Bit lesen um zu entscheiden. Und woher weiß er
> Welche Daten vom PC kommen was aussagen?? Muss ich diese
> zwischenspeichern und dann einzeln auswerten??

Das waere von Vorteil. Stelle dir vor, du liest Zeichen fuer Zeichen und 
fuehrst sofort die noetigen Aktionen am I2C bus aus (Start, 
Schreibe/Lese-Operation). Stelle dir nun vor, in der Mitte des Kommandos 
tritt nun ein Parse-Error auf, weil der Benutzer ein ungueltiges Zeichen 
eingegeben hat. Nun musst du die Operation am I2C bus abbrechen 
(Stop-Signal schicken).

Es ist besser alle Eingaben vor der ersten Operation am I2C bus auf 
Gueltigkeit zu ueberpruefen und erst dann etwas auf den I2C bus legen, 
wenn du sicher bist dass die Eingabe korrekt formattiert ist.

Wenn es dir nur ums Lernen geht und 100%-ige Sicherheit nicht benoetigt 
wird, kannst du auch die Abkuerzung nehmen und auf den I2C bus zugreifen 
waehrend du die Eingabe parst.

> Ich stell viell grad blöde fragen, aber ich möchte es halt auch
> verstehen und nicht einfach nur machen.

Die Einstellung lernen zu wollen wird in technischen Foren gerne 
gesehen. :-)

Thomas

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.