Forum: Mikrocontroller und Digitale Elektronik I2C Adresse ermitteln


von Achim S. (achims)


Lesenswert?

Hallo Gemeinde
Wie kannn ich die Adresse eines I2C Teilnehmers ermitteln. Aus dem 
Datenblatt. Ist Klar.
Wie kann ich die Adresse ermitteln mit einem Programm? Habe das Programm 
von Peter gesehen, Ist ein Sniffer. Kann ich damit die Adresse 
ermitteln?
Es gibt einige Sachen auf dem Arduino. Möchte es aber in normalen C 
machen und auf einem Display mit I2C ausgeben.
Hat da jemand ein Programm dazu oder eine Idee?
achim

von Myxo M. (myxom)


Lesenswert?

Achim Seeger schrieb:
> Wie kannn ich die Adresse eines I2C Teilnehmers ermitteln.

Du brauchts irgendeine Feedbackleitung von dem jeweiligen I2C-IC.
Anderes ist es nicht zu machen, weil es im I2C-Protokoll nicht 
vorgesehen wurde.

I2C Komponenten wurden z.B. in PHILIPS-TVs eingebaut, wo der Entwickler 
deren Adresse vor Hardware-Legung schon kannte.

von Achim S. (achims)


Lesenswert?

Habe es in einigen Beiträgen gesehen.
Es werden alle möglichen Adressen gesendet. Welche Adresse antwortet ist 
vorhanden.
Manche machen es sehr einfach.
Möchte die Adresse nicht über extra Programm auslesen und am PC 
anzeigen, sondern über ein Display im Bus.
Hat jemand eine Idee dazu?

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Achim Seeger schrieb:
> Hat da jemand ein Programm dazu oder eine Idee?
> achim

 Jede Device auf I2C Bus muss eigene Adresse bestätigen, mit ACK.
 Also, Adresse ausgeben, auf ACK warten, wenn ja, irgendwo merken
 und STOP senden.
 Adresse um eins erhöhen und...

von Achim S. (achims)


Lesenswert?

Genau so hatte ich es mir gedacht.

von Simon S. (-schumi-)


Lesenswert?

Unter Linux gibt es das Tool i2cdetect, welches genau das macht was du 
willst. Es benutzt zwei verschiedene Methoden (schreiben & lesen), die 
je nach zu scannender Adresse benutzt werden (weil die jeweils eine oder 
andere Methode bei manchen Chips Probleme bereiten kann).

Hier der Code zum Scannen (in C): 
https://github.com/groeck/i2c-tools/blob/master/tools/i2cdetect.c#L58
Von den zwei geschachtelten for-schleifen nicht verwirren lassen, das 
kommt daher dass die Ausgabe in 16 Spalten erfolgt:
1
╭─simon at localhost in ~ 
2
╰─○ sudo i2cdetect -y 0  
3
     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
4
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
5
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
6
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
7
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
8
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
9
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
10
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
11
70: -- -- -- -- -- -- -- --
(in diesem Fall ist nichts am Bus angeschlossen)

von Joachim B. (jar)


Lesenswert?

http://playground.arduino.cc/Main/I2cScanner

läuft prima

ich nutze das auf dem nano und geben das auf nokia 5110 LCD

dummerweise betrachtet jeder die Adressgenerierung anders

ich schaue ins Datanblatt und nehme alle Bits ! für ein Adressbyte !
in o.g. Link wurde das nicht getan was zu einer Verwirrung bei mir 
führte die ich dann später auflösen konnte.

ist zwar am Arduino aber nun gut....
1
I2C Scanner -> Scanning...
2
I2C device found at address 0x38; 0111000x; << 0x70; 01110000 PCF8574A Tastatur
3
I2C device found at address 0x50; 1010000x; << 0xA0; 10100000
4
I2C device found at address 0x68; 1101000x; << 0xD0; 11010000 DS1307/DS3231 RTC
5
done

meine Tastatur liegt bei mir auf 0x70, das letzte Bit ist aber R/W 
vorbehalten was für die PI (der anderen) Schreiber eben nicht zählt oder 
anders gesagt, es sind nur 127 Adressen nach alter Definition möglich, 
ergo wurden nur die vordersten 7 Bit beguckt was zu 0x38 führt

mit einem links shift habe ich meine kleine Welt wieder gerade gerückt, 
wie man das auch betrachtet ist ja egal, nur muss man sich vorher über 
die Betrachtungsweise einigen.

: Bearbeitet durch User
von Achim S. (achims)


Lesenswert?

Sieht sehr gut aus.

Hallo Simon
Dein Programm läuft unter Linux. Kann man das einfach umschreiben auf 
einen AT? Ansonsten werde ich mir gründlich ansehen.

Hallo Joachim
Du hast sogar die Umrechnung in hex dabei. Das lohnt sich langsam was zu 
machen.
achim

von Wolfgang A. (Gast)


Lesenswert?

Joachim B. schrieb:
> dummerweise betrachtet jeder die Adressgenerierung anders

Probleme gibt es immer dann, wenn das Adressierungsbyte 
fälschlicherweise als Adresse bezeichnet wird.

von Thorsten S. (thosch)


Lesenswert?

Wolfgang A. schrieb:
> Probleme gibt es immer dann, wenn das Adressierungsbyte
> fälschlicherweise als Adresse bezeichnet wird.

Warum "fälschlicherweise"?
Es ist aber durchaus weit verbreitete Praxis, genau das zu tun.
Ist eben einfach praktischer das Read-Flag in die Adresse reinzuodern, 
als diese immer noch um ein Bit linksschieben zu müssen.
Viele Hersteller von ICs mit I2C-Schnittstelle geben die Slave-Adressen 
genau so an. Analog Devices z.B. in seinen Datenblättern zu HDMI 
Schnittstellen ICs und Video Encodern und Decodern.

Auch auf Softwareseite wird es anscheinend von den meisten 
Programmierern so gehandhabt, dass man einer 
I2C_Read/Write/irgendwwas-Routine die Slave-Adresse als gerade 
8-Bit-Zahl übergibt.

von Klaus (Gast)


Lesenswert?

Thorsten S. schrieb:
> Warum "fälschlicherweise"?
> Es ist aber durchaus weit verbreitete Praxis, genau das zu tun.

Es ist durchaus weit verbreitete Praxis, in Tempo 30 Zonen schneller zu 
fahren. Trotzdem ist es falsch.

Der Aufbau von Telegrammen bei einem Dateübertragungsprotokoll steht der 
Spezifikation. Da ist bei I2C ein 7 Bit Adressfeld definiert, und auch 
wo es im Telegram steht: in den zuerst übertragenen 7 Bit. Und dort 
steht auch, wo weitere Bits des Adressfeldes bei 10 Bit Adressen zu 
finden sind.

> Auch auf Softwareseite wird es anscheinend von den meisten
> Programmierern so gehandhabt, dass man einer
> I2C_Read/Write/irgendwwas-Routine die Slave-Adresse als gerade
> 8-Bit-Zahl übergibt.

Wie man an I2Cdetect (weiter oben) sieht, ist dem nicht so. Da werden 
sogar die in den I2C-Spec reservierten Adressen beim Scan ausgelassen, 
es kommt also keine Adresse größer als 0x78 vor.

MfG Klaus

von Simon S. (-schumi-)


Lesenswert?

Achim Seeger schrieb:
> Hallo Simon
> Dein Programm läuft unter Linux.
Ich habs nicht geschrieben, das ist Teil von GNU/Linux

> Kann man das einfach umschreiben auf
> einen AT? Ansonsten werde ich mir gründlich ansehen.
Relevant sind ja sowiso nur die Zeilen 58 bis 121. Ein bisschen was 
musst du natürlich ändern:
 * Wenn du die Darstellung nicht willst kannst du natürlich die 
for-Schleifen zusammenfassen und alle printf+fflush rauswerfen
 * Bei "/* Select detection command for this address */" musst du vorher 
halt den mode festlegen (vlt. möchtest du das ja auch für den User 
einstellbar machen, wobei ich bisher mit MODE_AUTO nie Probleme hatte)
 * "/* Skip unwanted addresses */" kannst du eigentlich rauswerfen, da 
wird (soweit ich verstehe) überprüft ob der Bus den entsprechenden 
Lese/Schreib-Befehl unterstützt
 * "/* Set slave address */" musst du natürlich mit den entsprechenden 
Tools auf dem AVR machen. Der Teil mit "if (errno == EBUSY)" kann auch 
weg, weil das die Fehlerbehandlung ist wenn ein Treiber das Gerät schon 
benutzt.
 * "/* Probe this address */" Die Write und Read Befehle natürlich durch 
die entsprechenden beim AVR ersetzten
 * "if (res < 0)" Kein Plan wie du deine Ergebnisse verarbeiten willst, 
hier musst du das dann programmieren

: Bearbeitet durch User
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Klaus schrieb:
> Wie man an I2Cdetect (weiter oben) sieht, ist dem nicht so. Da werden
> sogar die in den I2C-Spec reservierten Adressen beim Scan ausgelassen,
> es kommt also keine Adresse größer als 0x78 vor.

 Wie es I2Cdetect macht, ist vollkommen wurscht.
 Alle 24xxx haben 0xA0 Adressen, wie du die finden willst wenn keine
 Adresse größer als 0x78 vorkommt, ist mir schleierhaft.
 I2C Adressen sind normalerweise 7-bit und zwar die oberen 7-bit.
 R/W wird bei der Adresse einfach nicht benutzt. Deswegen hat
 Thorsten auch Recht, wenn er schreibt, dass I2C-Adressen gerade sind.

: Bearbeitet durch User
von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Marc Vesely schrieb:
> I2C Adressen sind normalerweise 7-bit und zwar die oberen 7-bit.

Also was jetzt?

Du hast recht: i2c-Adressen haben 7 bit. Damit geht der theoretische 
Adressraum von 0 bis 127, und 0xA0 ist keine gültige Adresse.

"die oberen 7 bit" gibt es nicht.

von Wolfgang A. (Gast)


Lesenswert?

Auch wenn sich einige hier auf den Kopf stellen, die Adresse besteht aus 
sieben Bit und das R/W-Bit gehört nicht dazu. So hat es Philips (jetzt 
NXP) spezifiziert und festgeschrieben. Sonst entspricht es de facto 
nicht der I2C Spezifikation.
http://www.nxp.com/documents/application_note/AN10216.pdf

Es darf natürlich jeder aus diesen oder jenen Gründen andere 
Konventionen verwenden, aber dann soll er sich nicht wundern, wenn es 
Kommunikationsprobleme gibt.

Bei einem gewöhnlichen EF-Haus hat die Haustür auch nicht zwei 
Hausnummer - eine zum Rein- und eine zum Rausgehen ;-)

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Wolfgang A. schrieb:
> Bei einem gewöhnlichen EF-Haus hat die Haustür auch nicht zwei
> Hausnummer - eine zum Rein- und eine zum Rausgehen ;-)

Genialer Vergleich - Danke!

von Wolfgang A. (Gast)


Lesenswert?

Marc Vesely schrieb:
> Alle 24xxx haben 0xA0 Adressen, wie du die finden willst wenn keine
>  Adresse größer als 0x78 vorkommt, ist mir schleierhaft.

Dann guck mal ins Datenblatt, was da als "Slave Address" bezeichnet ist
z.B. 24xx1026 (Figure 5-1: Ccontrol Byte Format)
http://ww1.microchip.com/downloads/en/DeviceDoc/20002270D.pdf

Und damit auch jeder den Unterschied merkt und es zu keinen 
Verwechselungen kommen kann, hat Maxim das betreffende Byte lieber 
"Control Byte" genannt ;-)

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Michael Reinelt schrieb:
> Du hast recht: i2c-Adressen haben 7 bit. Damit geht der theoretische
> Adressraum von 0 bis 127, und 0xA0 ist keine gültige Adresse.
>
> "die oberen 7 bit" gibt es nicht.
 No comment.

Wolfgang A. schrieb:
> Dann guck mal ins Datenblatt, was da als "Slave Address" bezeichnet ist
> z.B. 24xx1026 (Figure 5-1: Ccontrol Byte Format)
> http://ww1.microchip.com/downloads/en/DeviceDoc/20002270D.pdf

 Habe ich. Da steht genau das, was ich auch geschrieben habe.

von Bernhard F. (bernhard_fr)


Lesenswert?

Michael Reinelt schrieb:

> Also was jetzt?
>
> Du hast recht: i2c-Adressen haben 7 bit. Damit geht der theoretische
> Adressraum von 0 bis 127, und 0xA0 ist keine gültige Adresse.
>
> "die oberen 7 bit" gibt es nicht.

Natürlich haben die Adressen nur 7bit. (zu den erweiterten auf 10 sag 
ich jetzt absichtlich nichts)
Aber da die meisten uC nunmal in vollen 8bit denken, sehen diese 7bit 
irgendwo abgelegt halt so aus.
1
X A7 A6 A5 A4 A3 A2 A1 A0

Wenn man die Adresse dann auf den Bus für Operationen schicken will wird 
einmal nach links geshiftet und das letzte Bit entsprechend für Read 
oder Write gesetzt.

Dann kommt die Stelle an, der der Praktiker sich einschaltet. Wenn man 
die Adresse in der Form:
1
A7 A6 A5 A4 A3 A2 A1 A0 0
im Programm hinterlegt, dann spart man sich die Shift-Opperation. Das 
R/W Bit wird dann mit einer einfachen Oder-Verknüpfung hinzugefügt, und 
der Wert wird direkt auf den Bus geschickt. Kein Programmierer der Welt 
würde jetzt aber diesen Wert als "Adresse+0bit" abspeichern, sondern er 
heißt zur allgemeinen Verwirrung eben auch "Adresse".

Die 7 Adressbits oder höherwertigen Bits hier als "obere Bits" zu 
bezeichnen würde ich jetzt nicht als falsch erachten...


Die Adresse besteht also grundsätzlich nur aus 7 bit. Wo der 
Programmierer die letztendlich hinschreibt ist dann anscheinend nicht 
definiert und das macht jeder wie er gerade lustig ist. Und darum kann 
man da jetzt auch noch ewig weiterdikutieren ohne einen gemeinsamen 
Nenner zu finden.
Mann muss leider jedes mal wieder aufpassen wie es implementiert wurde.

Können wir dieses Thema dann abhaken, bevor es ausartet?

: Bearbeitet durch User
von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Bernhard F. schrieb:
> Können wir dieses Thema dann abhaken, bevor es ausartet?

Gerne. Wenn sich dann bitte alle nochmal den Beitrag von Wolfgang 
Beitrag "Re: I2C Adresse ermitteln" durchlesen und zu 
Herzen nehmen, dann können wir die Diskussion wirklich beenden.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Bernhard F. schrieb:
> Aber da die meisten uC nunmal in vollen 8bit denken, sehen diese 7bit
> irgendwo abgelegt halt so aus.
> X A7 A6 A5 A4 A3 A2 A1 A0

 Sind im Prinzip gleicher Meinung, aber:

  A7 A6 A5 A4 A3 A2 A1 A0 X

 Und so steht es auch in den meisten DaBla, was ja auch logisch ist.
 Bit 0 gehört nicht zur Adresse, weil das eben Kontrollbit ist, hat
 mit der Adresse genau Nullkommanichts zu tun, wird ganz einfach ein-
 oder ausgeblendet.

: Bearbeitet durch User
von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Marc Vesely schrieb:
> Und so steht es auch in den meisten DaBla, was ja auch logisch ist.
>  Bit 0 gehört nicht zur Adresse, weil das eben Kontrollbit ist, hat
>  mit der Adresse genau Nullkommanichts zu tun, wird ganz einfach ein-
>  oder ausgeblendet.

ich weiss nicht was daran so schwierig ist. Ob das in den meisten 
Datenblättern steht ist irrelevant. Die I2C-Spezifikation besagt dass 
die Adresse 7 Bit hat, und damit von 0 bis 127 geht. Was gibts da 
herumzudiskutieren? Ob das vorausschauende Shiften jetzt bequem oder 
lässig oder faul oder dumm oder sonstwas ist: irrelevant. Es ist nur mit 
Sicherheit eines: nicht Standardkonform.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Michael Reinelt schrieb:
> Datenblättern steht ist irrelevant. Die I2C-Spezifikation besagt dass
> die Adresse 7 Bit hat, und damit von 0 bis 127 geht.

 Nein, das ist eben dein Denkfehler.
 Es besagt nur, dass es 128 verschiedene Adressen geben kann.
 Wenn ich die höherwertigen 4 Bits nehme, dann habe ich 16 verschiedene
 Adressen,aber keine Adresse kann kleiner als 16 sein (außer 0).
 Klarer ?

: Bearbeitet durch User
von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Marc Vesely schrieb:
> Es besagt nur, dass es 128 verschiedene Adressen geben kann.

Soweit richtig.

Du bist hartnäckig :-)

Probieren wir es mal anders: du stimmst mir zu, dass die mehrdeutige 
Betrachtungsweise einer i2c-Adresse verwirrend und lästig ist? Wenn man 
irgendwo liest "Adresse 42" damit nicht klar ist ob jetzt 0x2a oder 0x54 
gemeint ist?

Du stimmst mir zu, dass es verwirrend ist, wenn ein i2c-teilnehmer nach 
"deiner" betrachtungsweise zwei Adressen hat? nämlich 0x54 zum lesen und 
0x55 zum Schreiben? Während er in "meiner" Betrachtungsweise immer die 
gleiche Adresse hat, nämlich 0x2a, geshiftet und geodert mit dem 
R/W-Bit?

Den Einwand, man könnte sich das Shiften sparen, indem man gleich mit 
der 8-Bit-Adresse arbeitet, lasse ich nicht gelten: die drei Taktzyklen 
sind bei den gemächlichen 100/400 kHz nicht der Rede wert (und wird im 
Optimalfall sowieso vom Compiler wegoptimiert). Und wie immer gilt das 
biblische Motto "premature optimization is the root of all evil!".

Jede mir bekannte relevante I2C-Implementierung arbeitet mit "meiner" 
Adressierung. Die andere kommt nur dann vor, wenn der Programmierer 
glaubte, intelligent sein zu müssen ("premature optimization is the root 
of all evil!"). Alle mir bekannten Datenblätter sprechen in der anderen 
Betrachtungsweise nicht mehr von der I2C-Adresse, sondern von einem 
"Control byte" oder einem "Address byte", aber nicht von der 
i2c-Adresse.

Zitat aus einer i2c-Spec: "Some vendors incorrectly provide two 8-bit 
slave addresses for their device, one to write to the device and one to 
read from the device. This 8-bit number actually encodes the 7-bit slave 
address and the read/write bit. "

Du stimmst mir zu dass ein 7-bit-Wert tatsächlich Werte von 0 bis 127 
annehmen kann, und nicht "gerade Zahlen zwischen 0 und 254"?

Wenn du ein x-beliebiges Format hast, welches 32 bit umfasst, und die 
Definition sagt, "Bit 17 bis 21 sind Wert X", rechnest du dann mit 5 Bit 
= 0..31 für Wert X, oder rechnest du alle niederwertigen Bits mit ein?

Dabei ist es so einfach: eine 7-bit-adresse ist eine 7-bit-adresse ist 
eine 7-bit-adresse ist eine 7-bit-adresse und hat damit 7 bit und 7 bit 
sind 7 bit und mit 7 bit lassen sich Adressen von 0..127 abdecken.

Eine Adresse 0xA? ist keine 7-bit-adresse ist keine 7-bit-adresse weil 
sie sich mit 7 bit nicht adressieren lässt.

: Bearbeitet durch User
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Michael Reinelt schrieb:
> Du bist hartnäckig :-)
 Ja. Du bist aber auch nicht gerade das, was man nachgiebig nennt. :-)

> Du stimmst mir zu dass ein 7-bit-Wert tatsächlich Werte von 0 bis 127
> annehmen kann, und nicht "gerade Zahlen zwischen 0 und 254"?
 Nein, nicht in diesem Fall. Es bedeutet nur 2^7 verschiedene Werte.
 Die Anzahl der bits gibt nur an, wieviele verschiedene Zustände,
 also auch Adressen, damit ausgedrückt werden können.
 Die Position der bits gibt deren Wertigkeit.
 Also wenn bits (7-6-5-4) 16 verschidene Zustände annehmen können und
 bits (3-2-1-0) auch, stellt das noch lange nicht denselben Wert.

> Wenn du ein x-beliebiges Format hast, welches 32 bit umfasst, und die
> Definition sagt, "Bit 17 bis 21 sind Wert X", rechnest du dann mit 5 Bit
> = 0..31 für Wert X, oder rechnest du alle niederwertigen Bits mit ein?
 Erstens ist das noch lange nicht dasselbe weil Wert und Adresse eben
 nicht dasselbe sind. Bei einer Adresse blendet man einfach die nicht
 benötigten bits aus, genauso wie bei der I2C Adresse. Und genau
 deswegen sagt man dann aber nicht, dass die Adresse 0x11 gemeint ist,
 sondern Adresse 0x11xxxx.

> Jede mir bekannte relevante I2C-Implementierung arbeitet mit "meiner"
> Adressierung. Die andere kommt nur dann vor, wenn der Programmierer
> glaubte, intelligent sein zu müssen ("premature optimization is the root

> Du stimmst mir zu, dass es verwirrend ist, wenn ein i2c-teilnehmer nach
> "deiner" betrachtungsweise zwei Adressen hat? nämlich 0x54 zum lesen und
> 0x55 zum Schreiben? Während er in "meiner" Betrachtungsweise immer die
> gleiche Adresse hat, nämlich 0x2a, geshiftet und geodert mit dem
> R/W-Bit?
 Mal abgesehen davon, dass das R/W bit genau umgekehrt gesetzt wird, ist
 deine Aussage ganz Falsch.
 I2C_Adr = 0xA0
 Beim lesen ist I2C_Adr | rw_bit
 Beim schreiben nicht mal das.

 Und warum du die Adresse nach rechts schiebst, ist mir ganz unklar.

: Bearbeitet durch User
von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Marc Vesely schrieb:
> Michael Reinelt schrieb:
>> Du bist hartnäckig :-)
>  Ja. Du bist aber auch nicht gerade das, was man nachgiebig nennt. :-)

Dann haben sich ja zwei gefunden :-)

>> Du stimmst mir zu dass ein 7-bit-Wert tatsächlich Werte von 0 bis 127
>> annehmen kann, und nicht "gerade Zahlen zwischen 0 und 254"?
>  Nein

Schade. Aber einen Versuch war's wert ;-)
ich teile deine Einschätzung trotzdem nicht.

>> Wenn du ein x-beliebiges Format hast, welches 32 bit umfasst, und die
>> Definition sagt, "Bit 17 bis 21 sind Wert X", rechnest du dann mit 5 Bit
>> = 0..31 für Wert X, oder rechnest du alle niederwertigen Bits mit ein?
>  Erstens ist das noch lange nicht dasselbe weil Wert und Adresse eben
>  nicht dasselbe sind.

Warum? Anders gefragt: "Bit 17..21 sind irgendeine Sub-Adresse". Ist 
dann deine Sub-Adresse 0..31 oder was? Nochmal anders: "Bit 17..21 sind 
die Registernummer". Ist dann deine Registernummer 0..31 oder nicht? Wo 
liegt der Unterschied zwischen registernummer und Adresse?

>> Du stimmst mir zu, dass es verwirrend ist, wenn ein i2c-teilnehmer nach
>> "deiner" betrachtungsweise zwei Adressen hat? nämlich 0x54 zum lesen und
>> 0x55 zum Schreiben? Während er in "meiner" Betrachtungsweise immer die
>> gleiche Adresse hat, nämlich 0x2a, geshiftet und geodert mit dem
>> R/W-Bit?
>  Mal abgesehen davon, dass das R/W bit genau umgekehrt gesetzt wird
Ok, der Punkt geht an dich. Meine Entschuldigung: 
http://www.staff.uni-mainz.de/pommeren/Buchstabendreher/lechts.html

>  ist deine Aussage ganz Falsch.
>  I2C_Adr = 0xA0
>  Beim lesen ist I2C_Adr | rw_bit
>  Beim schreiben nicht mal das.
>  Und warum du die Adresse nach rechts schiebst, ist mir ganz unklar.
ich schiebe nicht nach rechts, sondern (gemäß Spezifikation) nach links, 
und setze dann Bit 0 gemäß R/W.

von Gerhard O. (gerhard_)


Lesenswert?

Mir gefaellt die "Control Byte" Definition von Microchip noch am Besten. 
Das Control Byte enthält eben ein 7-bit Addressenfeld und das R/W 
Controlbit.

Mfg,
Gerhard

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Gerhard O. schrieb:
> Mir gefaellt die "Control Byte" Definition von Microchip noch am Besten.
> Das Control Byte enthält eben ein 7-bit Addressenfeld und das R/W
> Controlbit.

Die Definition gefällt mir zwar nicht, aber damit kann ich mich 
anfreunden: Die nennen es "Control byte" und nicht (fälschlicherweise) 
"i2c-address"

: Bearbeitet durch User
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Michael Reinelt schrieb:
> Dann haben sich ja zwei gefunden :-)

 Der Klügere gibt nach ;-D

von Gerhard O. (gerhard_)


Lesenswert?

Michael Reinelt schrieb:
> Gerhard O. schrieb:
>> Mir gefaellt die "Control Byte" Definition von Microchip noch am Besten.
>> Das Control Byte enthält eben ein 7-bit Addressenfeld und das R/W
>> Controlbit.
>
> Die Definition gefällt mir zwar nicht, aber damit kann ich mich
> anfreunden: Die nennen es "Control byte" und nicht (fälschlicherweise)
> "i2c-address"

Es werden sich damit von einigen Herstellern sowieso große Freiheiten 
genommen wenn man sich errinnert wie oft gerade bei EEPROMS das Control 
Byte oft die verschiedensten Zusatzfunktion hat und nur die oberen vier 
Bits wirklich den Namen Addresse oder Funktionsidentifier verdienen. Bei 
gewissen EEPROMS sind Teile davon eine Erweiterung des 
Datenaddress-Bitfeld.

Moral von der Geschicht: Das Datenblatt sich zu Gemüt führen und sich 
danach ohne Denken richten;-)

Gerhard

: Bearbeitet durch User
von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Marc Vesely schrieb:
> Der Klügere gibt nach ;-D

Das ist jetzt aber unfair! ;-)

Gerhard O. schrieb:
> Moral von der Geschicht: Das Datenblatt sich zu Gemüt führen

Das bleibt einem sowieso nie erspart. Zur Verwirrung mit der i2c-Adresse 
kommen dann noch so Besonderheiten wie von dir beschrieben, oder die 
DOG-Displays, die sich gleich zwei i2c-Adressen genehmigen, SMBus (wo 
das repeated-start ganz anders funktioniert) oder EEBus (ganz 
eigenartig)

von Gerhard O. (gerhard_)


Lesenswert?

Michael Reinelt schrieb:
> Marc Vesely schrieb:
>> Der Klügere gibt nach ;-D
>
> Das ist jetzt aber unfair! ;-)
>
> Gerhard O. schrieb:
>> Moral von der Geschicht: Das Datenblatt sich zu Gemüt führen
>
> Das bleibt einem sowieso nie erspart. Zur Verwirrung mit der i2c-Adresse
> kommen dann noch so Besonderheiten wie von dir beschrieben, oder die
> DOG-Displays, die sich gleich zwei i2c-Adressen genehmigen, SMBus (wo
> das repeated-start ganz anders funktioniert) oder EEBus (ganz
> eigenartig)

Eben! Im Wandel der Zeit und Proliferation der I2C Bausteine mussten 
halt "Krücken" gefunden weden die eben damals noch ungedachte (Im 
Standard) neue Funktionen erst ermöglichten.

Ist ja auch gar nicht so schlimm weil die meisten Datenblätter I2C 
Transaktionen sowieso äusserst ausführlich beschreiben und im 
allgemeinen leicht zu verstehen sind. (Mir geht es zumindest so)

: Bearbeitet durch User
von Achim S. (achims)


Lesenswert?

Hallo
Habe eure Diskussion verfolgt.
Finde richtig nett, das ihr euch einig geworden seit. Leider habe ich 
ein paar Lösungen dadurch gefunden, aber so richtig ist noch nichts 
dabei.
Hat jemand Erfahrung mit Peter Dannegger Programm I2C Sniffer?
achim

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Achim Seeger schrieb:
> Finde richtig nett, das ihr euch einig geworden seit. Leider habe ich
> ein paar Lösungen dadurch gefunden, aber so richtig ist noch nichts
> dabei.

 Nachdem ich eindeutig gewonnen habe, kann ich mich auch wieder melden.

 Warum probierst du es nicht mit einem selbstgeschriebenem Programm,
 dabei lernst du doch viel mehr als mit fremden Programmen ?

von Achim S. (achims)


Lesenswert?

Hallo Marc
habe schon einiges gemacht. Leider ist es reines Caos.
Die Anbindung und Aufruf zum Bus geht bereits. Auch die Anzeige auf dem 
Display. Leider komme ich mit der eigentlichen Adresswahl und speichern 
der Ergebnisse nicht weiter.
Keine Angst, habe schon genug Programme hier reingestellt. Kannst ja mal 
unter Multitasking nachsehen oder dem Nibo2.
Werde auch einiges dazu reinstellen
1
#include "i2clcd.h"
2
#include "i2cmaster.h"
3
#include "avr/io.h"
4
#include "util/delay.h"         // Versuch am LM 75 mit 0x91
5
#include "avr/interrupt.h"
6
7
#define lm75_r 0x91       // Leseadresse des LM75
8
uint8_t msb_temp;          // Oberes Temperatur-Byte
9
uint8_t lsb_temp;          // Unteres Temperatur-Byte
10
uint16_t temp_wrd;         // Ganzes Temperatur-Wort
11
uint8_t ret;               // Kontrollvariable für I2C Kommunik.
12
uint8_t x;                 // X-Position der Kommastelle
13
signed char temperatur;    // Variable m. Vorzeichen für die Temp.berechnung
14
char Buffer[20];           // Umwandlungs-Variable für LCD Anzeige
15
16
void temperfassung(void)  //  Versuch einen Wert zu geben
17
  {
18
    ret = i2c_start(lm75_r);    // Start Lesen des LM75
19
   if (ret == 0)                // obere1unteres Bit le schr.
20
    {                   // Wenn LM75 ein OK sendet...
21
  msb_temp = i2c_readAck();  //...speichere oberes Bit
22
  lsb_temp = i2c_readNak();  //...speichere unteres Bit
23
    }
24
  else                       // Fehlererkennung
25
    {                        // Wenn LM75 kein OK sendet
26
       lcd_command(LCD_CLEAR);  // Leere Display
27
       lcd_printlc(1,13,"READ");  // "Lesevorgang"
28
       lcd_printlc(2,13,"NOK");  // "Nicht OK (NOK)"
29
    }
30
  }

Soweit ein Teil meines Versuches. geht dabei um die Ausgabe eines Wertes 
und wird auf ausgabe der Adresse erweiter (wenn es klappt).
Ist bei weitem nicht vorzeigbar oder etwa fertig. Die komplette Sache 
der Adressen fehlt noch. (nicht alles in der Luft zerreissen)
achim

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Achim Seeger schrieb:
> Soweit ein Teil meines Versuches. geht dabei um die Ausgabe eines Wertes
> und wird auf ausgabe der Adresse erweiter (wenn es klappt).
 Ich dachte, du wolltest nur sehen, wer auf dem Bus antwortet und wer
 nicht ?

> Ist bei weitem nicht vorzeigbar oder etwa fertig. Die komplette Sache
> der Adressen fehlt noch. (nicht alles in der Luft zerreissen)
 Keine Angst, ich programmiere meistens in Assembler, aber warte mal
 ein paar Minuten...

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Hier, auf die Schnelle, natürlich ohne Gewährleistung:
1
 uint8_t StatCode = 0;
2
3
void CheckBus(void) {
4
 for (uint8_t Srch_Adr=0; Srch_Adr < 255; Srch_Adr +=2)
5
 {
6
   // START senden
7
   TWCR = (1<<TWINT) | (1<<TWSTA) | (1<<TWEN);
8
   while (!(TWCR & (1<<TWINT)));
9
   if ((TWSR & 0xF8) != START) {
10
     Fehler_Rut();                 // Bus wird nicht freigegeben
11
     return;  // oder break ?
12
   }
13
14
   TWDR = Srch_Adr;                // Adresse senden. 
15
   TWCR = (1<<TWINT) | (1<<TWEN);
16
   while (!(TWCR & (1<<TWINT)));
17
18
   StatCode = (TWSR & 0xF8);
19
   TWCR = (1<<TWINT) | (1<<TWEN) | (1<<TWSTO);  // STOP senden.
20
   ShowDev_Rut(Srch_Adr);
21
 }
22
 return;
23
}
24
 
25
 void ShowDev_Rut(uint8_t I2C_Adr) {  
26
    if (StatCode = MT_SLA_ACK)   // ACK gekriegt, Device anwesend
27
    {
28
      // Adresse senden, schreiben, merken...
29
    }
30
    else                        // Kein ACK gekriegt (MT_SLA_ACK = 0x18)
31
    {
32
      // Keine Adresse senden, nicht schreiben, nicht merken...
33
    }
34
    return;
35
 }
36
 
37
 void Fehler_Rut(void) {
38
    // Busfehler, Hilfe holen, Werkstatt anrufen
39
    return;
40
 }

 CopyLeft by ich, All Wrongs Reserved

: Bearbeitet durch User
von Bernhard F. (bernhard_fr)


Lesenswert?

Marc Vesely schrieb:

>
1
>  for (uint8_t Srch_Adr=0; Srch_Adr < 255; Srch_Adr +=2)
2
>

Wie konntest du nur...  Das wird ein langer Thread werden ;)

von holger (Gast)


Lesenswert?

>>  for (uint8_t Srch_Adr=0; Srch_Adr < 255; Srch_Adr +=2)
>>
>
>Wie konntest du nur...  Das wird ein langer Thread werden ;)

Das zeigt doch nur das die 8Bit Darstellung der I2C Adresse
plus dem R/W Bit eingängiger ist. Den Schwachsinn mit der
7Bit Adresse und dann doch in einem Byte senden, nur halt
um 1 geschoben erfasst man halt nicht so schnell.

Genau genommen gibt es doch 256 I2C Adressen.
128 zum lesen und 128 zum schreiben;)

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Bernhard F. schrieb:
> Wie konntest du nur...  Das wird ein langer Thread werden ;)

 Hmmm. Lange hin und her überlegt, abgewogen, für und wider abge-
 schätzt, Argumente und Gegenargumente, die Entscheidung war für mich
 überhaupt nicht leicht...
 Aber vielleicht ist Michael Reinelt schlafen gegangen oder er hätte
 das einfach übersehen ohne deine Bemerkung ?
 Jetzt ist es natürlich zu spät für irgendwelche Korrekturen.
 Für Morgen:
 Ja, Michael, ich weiss es, aber ich bin eben hartnäckig :-)

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

holger schrieb:
> Das zeigt doch nur das die 8Bit Darstellung der I2C Adresse
> plus dem R/W Bit eingängiger ist.
 Das wären dann 9 bit wenn ich richtig addiert habe ?

> Den Schwachsinn mit der
> 7Bit Adresse und dann doch in einem Byte senden, nur halt
> um 1 geschoben erfasst man halt nicht so schnell.

 Sag das den I2C Herstellern, die machen es nämlich alle so.
 Und wenn ich die Adresse so verwende, wie es die I2C Hersteller
 auch tun, brauche ich genau nichts zu schieben.

: Bearbeitet durch User
von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Marc Vesely schrieb:
> for (uint8_t Srch_Adr=0; Srch_Adr < 255; Srch_Adr +=2)

Die Schleife wird aber halbwegs lange laufen... mit 7 Bit wär dir das 
nicht passiert :-)

Außerdem sollten in deiner Schleife auch noch reservierte Adressen 
übersprungen werden, das wären zumindest die 0 (General Call), 1 (CBUS), 
2 (anderes Busformat) und alles ab 120 (10-Bit-Adressierung).

: Bearbeitet durch User
von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Michael Reinelt schrieb:
> Außerdem sollten in deiner Schleife auch noch reservierte Adressen
> übersprungen werden, das wären zumindest die 0 (General Call), 1 (CBUS),
> 2 (anderes Busformat) und alles ab 120 (10-Bit-Adressierung).

 Wieso meine Schleife ? Ist für Achim.
 Adresse 0 wird nicht bestätigt, die anderen kann er ja ruhig senden,
 da nach dem ersten Byte sowieso STOP gesendet wird.
 Ehrlich gesagt, mich interessiert es auch ob das funktionieren wird.
 Gesniffert habe ich schon auf dem I2C bus, aber so etwas hatte ich noch
 nie versucht.

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Marc Vesely schrieb:
> Wieso meine Schleife ? Ist für Achim.
Aber du hast sie doch vorgeschlagen.

Hinweis: Die terminiert nie, ist eine Endlosschleife, die Bedingung 
"Srch_Adr < 255" ist immer wahr: zuletzt bei 254, nach "Srch_Adr +=2" 
ists wieder 0, und nochmal von vorne...

>  Adresse 0 wird nicht bestätigt,
Doch, von allen Slaves die auf General Call lauschen.

> die anderen kann er ja ruhig senden,
>  da nach dem ersten Byte sowieso STOP gesendet wird.
Man sollte es vermeiden, bevor andere Devices sich verschlucken. Hat 
schon seinen grund, warum i2cdetect die (gemäß i2c-Spezifikation) 
auslässt.
>  Ehrlich gesagt, mich interessiert es auch ob das funktionieren wird.
>  Gesniffert habe ich schon auf dem I2C bus, aber so etwas hatte ich noch
>  nie versucht.
Funktionieren wird es ziemlich sicher.

von Joachim B. (jar)


Lesenswert?

Marc Vesely schrieb:
> Wieso meine Schleife ? Ist für Achim.

ich war zwar nicht gemeint, finde deinen Ansatz aber trotzdem 
interessant:
1
   while (!(TWCR & (1<<TWINT)));
2
   if ((TWSR & 0xF8) != START) {
3
     Fehler_Rut();                 // Bus wird nicht freigegeben

mein Problem, ich frage im Interrupt eine Tastatur ab, genauer Tasten 
die am PCF8574 hängen, das klappte prima.

Als im main loop einer RTC am I2C hinzu kam konnte ich Abstürze durch 
Tastenbetätigungen provozieren, musste schon sehr viele Tasten betätigen 
in kurzer Zeit.

Dann lernte ich das I2C Interruptgesteuert läuft und mir kam der 
Verdacht wenn mitten in der main loop der I2C angesprochen wird ohne 
beendet zu sein und die I2C Abfrage in IRQ dazwischen funkt muss das 
kollidieren.

Momentan verriegel ich die beiden Zugriffe gegeneinander.

nun kommts:

Leichter wäre es wenn ich im Interrupt fragen könnte ob der Bus frei 
ist, es macht ja nix wenn der IRQ alle 10ms aufruft wenn mir einmal für 
10ms eine Abfrage auf Tasten entgeht sollte der Timer IRQ mitten in eine 
main loop I2C Abfrage reinspringen.

meine eigenen Versuche mit den
while (!(TWCR & (1<<TWINT))); // Ende vom Verkehr abwarten ?
scheiterten wenn der Timer IRQ zuschlug, der I2C Zugriff der main loop 
wurde durch Unterbrechung nicht beendet.

oder habe ich das irgendwie noch nicht komplett verstanden ?

: Bearbeitet durch User
von Walter Tarpan (Gast)


Angehängte Dateien:

Lesenswert?

Das hier funktioniert bei mir (ATmega16, 32, 644).

von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Joachim, irgendwie werd ich aus deiner problembeschreibung nicht 
schlau...

Grundsätzlich gibt es zwei Möglichkeiten, einen I2C-master am AVR zu 
realisieren: Mit oder ohne (TWI-)interrupts. Mischen sollte man die 
beiden nicht...

oder ist dein problem, dass du I2C-Zugriffe sowohl in der Main also in 
einem (Timer?) Interrupt machst? Das kann natürlich nicht gutgehen...

Vielleicht solltest du mal dienen Code zeigen...

von Joachim B. (jar)


Lesenswert?

Michael Reinelt schrieb:
> oder ist dein problem, dass du I2C-Zugriffe sowohl in der Main also in
> einem (Timer?) Interrupt machst? Das kann natürlich nicht gutgehen...

jau genau, mit Verriegelung kein Problem, der Ansatz den belegten Bus 
abzufragen hatte ich ja auch und das sollte auch funktionieren.

wenn der BUS in main loop belegt ist Tastaturabfrage in der IRQ 
überspringen ....

mein Fehler war wohl das ich in der ISR auf Ende vom Transfer der main 
loop  warten wollte ...

peinlich

: Bearbeitet durch User
von Michael R. (Firma: Brainit GmbH) (fisa)


Lesenswert?

Joachim B. schrieb:
> wenn der BUS in main loop belegt ist Tastaturabfrage in der IRQ
> überspringen ....

ich würde das an deiner Stelle ganz anders machen: Da I2C mit 100kHz 
vergleichsweise "schnarchlangsam" ist (ein Byte dauert fast 0.1ms) 
gehört das nicht in eine ISR. ich würde im Timer-Interrupt nur ein Flag 
setzen "10 Millisekunden sind vorbei" und alle i2c-Zugriffe in der Main 
abwickeln.

: Bearbeitet durch User
von Joachim B. (jar)


Lesenswert?

Michael Reinelt schrieb:
> ....ich würde im Timer-Interrupt nur ein Flag
> setzen "10 Millisekunden sind vorbei" und alle i2c-Zugriffe in der Main
> abwickeln.

ne genau das wollte ich ja vermeiden

wenn in der main loop eine längere Berechnung läuft entgehen mit 
Tastaturdrücke !

Oder ich muss in jeder Stelle gucken ob ich das Tastaturabfrage Flag 
gesetzt ist -> nervig !

ne das mit Flag ist OK wenn in der Timer IRQ mein LCD Update gesetzt 
wird alle 330ms dann wird auch gleich i2c busy gesetzt und die 
Tastenabfrage übersprungen, in der main loop wird i2c busy wieder 
rückgesetzt wenn die RTC ausgelesen wurde und LCD update erfolgt ist.

von Marc V. (Firma: Vescomp) (logarithmus)


Lesenswert?

Joachim B. schrieb:
> Leichter wäre es wenn ich im Interrupt fragen könnte ob der Bus frei
> ist, es macht ja nix wenn der IRQ alle 10ms aufruft wenn mir einmal für
> 10ms eine Abfrage auf Tasten entgeht sollte der Timer IRQ mitten in eine
> main loop I2C Abfrage reinspringen.
>
> meine eigenen Versuche mit den
> while (!(TWCR & (1<<TWINT))); // Ende vom Verkehr abwarten ?
> scheiterten wenn der Timer IRQ zuschlug, der I2C Zugriff der main loop
> wurde durch Unterbrechung nicht beendet.
>
> oder habe ich das irgendwie noch nicht komplett verstanden ?

 Mal sehen, ob ich das richtig verstanden habe:
 Du fragst deine Tasten in der Timer ISR ab ?
 Wenn du aber mit RTC beschäftigt bist, willst du nicht unterbrochen
 werden ?
   Wenn so, INTs sperren und wieder freigeben.

 Oder gleich wieder aus der ISR raus, falls du gerade beim RTC Verkehr
 bist ?
   Wenn so, eine Art von RTC_Flag setzen, beim ISR-Eintritt prüfen.

 Oder habe ich da etwas falsch verstanden ?

 Wie ich das sehe, kann man Status nicht abfragen, wenn man
 vorher nichts gesendet hat, also ist nichts mit while schleife.
 Die andere Möglichkeit, auf Bus Idle zu warten ist bißchen kompliziert
 weil der Clock eben nicht 50/50 sein muß, sondern kann beliebig lange
 bzw. kurze High/Low Zeiten haben, solange die Mindestzeiten eingehalten
 werden. Und die sind sogar bei 100KHz nur 4us. Da ist mit Wartezeiten
 von mindestens 10ms zu rechnen, nur um sicher zu sein, daß nichts auf
 dem Bus läuft. Ob das die Lösung ist, die du suchst, bezweifle ich.

 Aber am besten erklärst du nochmal genau was du vermeiden willst.

von Joachim B. (jar)


Lesenswert?

Marc Vesely schrieb:
> Mal sehen, ob ich das richtig verstanden habe:
>  Du fragst deine Tasten in der Timer ISR ab ?

genau, damit mir kein Tastendruck entgeht

>  Wenn du aber mit RTC beschäftigt bist, willst du nicht unterbrochen
>  werden ?

nein, unterbrochen schon aber dann in der Timer ISR eben kein I2C Tasten 
abfragen

>    Wenn so, INTs sperren und wieder freigeben.
jain, mache ich ja schon

>  Oder gleich wieder aus der ISR raus, falls du gerade beim RTC Verkehr
>  bist ?

nö alles andere muss ja in der ISR fertig gemacht werden, ausser in dem 
Moment die Tasten, die dürfen auch mal für 10ms ungefragt bleiben, 
werden also in der ISR übersprungen.

Die einzige Gefahr die bleibt das immer zufällig, die I2C Tastenabfrage 
im Timer synchron auf RTC Abfrage im main loop folgt, was dann zu keiner 
Tastenabfrage führen würde, aber das verhindere ich im Moment damit das 
ich das Flag für LCD update (wo die RTC Abfrage erfolgt) in der ISR 
setze also bestimme ob ich in der ISR Tasten abfragen mag oder nicht und 
diese sequenziell erfolgen.

Ablauf,

10ms Timerinterrupt
1
    if(lcd_time_update) 
2
      lcd_time_update--;
3
    else 
4
    {  lcd_time_update=33;
5
       _i2c_busy=1;
6
    }
7
// hier folgt noch was ......
8
// ......
9
// hier gehts weiter ......
10
    if(_i2c_key)
11
    {  if(!_i2c_busy)
12
      {  if(_i2c_key=='A')
13
         {  if(!i2c_start(PCF8574A_0+I2C_READ))  //;  // set device address and write mode
14
// hier folgt noch was ......

im main loop
1
    if(lcd_time_update==33 /*&& lcd_time_update>=23*/)
2
    {
3
      RTC.getTime();
4
      sprintf(_rtc__str,"%02d:%02d:%02d", RTC.hour, RTC.minute, RTC.second);
5
      myGLCD.print(_rtc__str, LEFT, 27);
6
      myGLCD.print("RTC", (9*6), 27);
7
      _i2c_busy=0; // gibt i2c auch für Tastatur im IRQ wieder frei
8
    }

>    Wenn so, eine Art von RTC_Flag setzen, beim ISR-Eintritt prüfen.

ich denke das mache ich ja

>  Oder habe ich da etwas falsch verstanden ?>  Aber am besten erklärst du nochmal genau was du vermeiden willst.

ich glaube habe ich erklärt

es sieht momentan so aus als wenn es prima läuft, kann keinen Absturz 
mehr provozieren.

von David (Gast)


Lesenswert?

Guten Tag,

ist der Code zufällig noch irgendwo verfügbar?

Vielen Dank!
David

von David (Gast)


Lesenswert?

Simon S. schrieb:
> Unter Linux gibt es das Tool i2cdetect, welches genau das macht
> was du
> willst. Es benutzt zwei verschiedene Methoden (schreiben & lesen), die
> je nach zu scannender Adresse benutzt werden (weil die jeweils eine oder
> andere Methode bei manchen Chips Probleme bereiten kann).
>
> Hier der Code zum Scannen (in C):
> https://github.com/groeck/i2c-tools/blob/master/tools/i2cdetect.c#L58
> Von den zwei geschachtelten for-schleifen nicht verwirren lassen, das
> kommt daher dass die Ausgabe in 16 Spalten erfolgt:

Also dieser hier

von Patrick L. (Firma: S-C-I DATA GbR) (pali64)


Lesenswert?

Ohne jetzt den Ganzen Thread zu lesen,
I²C Devices geben sich mit einem ACK/NACK zu erkennen wenn sie 
angesprochen werden und existieren / nicht existieren.

Der Buspirate nutzt dies um nach gültigen I²C Adressen zu suchen.
Im Hackaday Forum ist der Quellcode dazu verfügbar.

von Gerhard O. (gerhard_)


Lesenswert?

Das verwende ich bei mir mit dem EVERY:
1
// New I2C Master lib:  Refer to https://github.com/technoblogy/tiny-mega-i2c
2
#include <TinyMegaI2CMaster.h>  
3
4
/******************************************************************************
5
* Function:   I2C_PortScan()
6
* Description: Scans I2C Address space and returns found I2C Slave Devices
7
* Uses:
8
* Returns:      none
9
*******************************************************************************/
10
void I2C_PortScan(void)
11
{
12
  
13
  Serial.println(F("I2C Device Scan:"));  
14
  
15
  for(uint8_t i=1;i<128;i++)
16
  {
17
    if ( TinyMegaI2C.start(i, 0) == TRUE )
18
    {
19
      Serial.print(F("0x")); 
20
      if((i*2) < 10){
21
         Serial.print("0"); 
22
      }
23
      Serial.println(i*2,HEX);  
24
    }
25
  }
26
  Serial.println(F("Done:"));  
27
}

Funktioniert einwandfrei.

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.