Forum: Mikrocontroller und Digitale Elektronik Soft I2C Master


von Samuel Müller (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,
ich habe mir ein kleines Mikroncontroller Board gebaut. Darauf befindet 
sich ein ATmega32u2 und ein AD-Wandler MCP3426. Das ganze ist mit USB 
und der LUFA Library über einen VirtualSerialPort an den Computer 
verbunden und lässt sich darüber ansteuern. Der AD-Wandler wird über 
eine I2C-Schnittstelle angesteuert, nun sind leider die tollen SLD und 
SDA Funktionen auf anderen Pin's die schon belegt sind und auch nicht 
geändert werden können. Also muss ein Software I2C-Master her. Da das 
Protokoll ja eigentlich schön ausführlich in dem Datenblatt des 
ADC-Wandels erklärt ist habe ich erst eine Ewigkeit mein eigenes Glück 
herausgefordet und versucht eine Kommunikation her zu stellen. Leider 
erfolglos, entweder es ist überhaupt nichts passiert oder das Programm 
hat sich aufgehängt und es ging nichts mehr.

Also habe ich mir gedacht, warum das Rad zwei mal erfinden, solche I2C 
Software Implementierungen muss es doch schon zur genüge geben denn ich 
werde sicherlich nicht der erste sein beim dem es von den Pin's her 
nicht passt.

Nach etwas suchen habe ich auch ein paar Open-Source-Libraryies 
gefunden, jedoch bin ich mir nicht sicher ob diese wirklich das können 
was ich brauche denn dieser ADC-Wandler ist doch recht speziell an sich. 
Außerdem habe ich an beiden Pin's Interrupts zur Verfügung die bestimmt 
für etwas bessere Performance sorgen könnten wenn diese mitverwendet 
werden.

Könnt ihr mir Software I2C Libraries empfehlen?
Am besten mit Interrupt Unterstützung und ggf. mit deutscher 
Dokumentation, wobei ich auch der englischen Sprache mächtig bin.

ATmega32U2
http://www.atmel.com/images/doc7799.pdf

MCP3426
http://ww1.microchip.com/downloads/en/DeviceDoc/22226a.pdf

I2C Library
http://extremeelectronics.co.in/avr-tutorials/software-i2c-library-for-avr-mcus/

LUFA
http://www.fourwalledcubicle.com/LUFA.php

von isnah (Gast)


Lesenswert?

Ich glaube die "Fleury-Standard-I2c-Lib" istin deinem Fall wie 
geschaffen:

http://homepage.hispeed.ch/peterfleury/group__pfleury__ic2master.html

Bei mir funktioniert die Softwareösung mit "i2cmaster.s" in einigen 
Projekten tadellos.

von Peter D. (peda)


Lesenswert?

Samuel Müller schrieb:
> oder das Programm
> hat sich aufgehängt und es ging nichts mehr.

Dann hast Du was falsch gemacht.
Der Master gibt alle Timings vor, d.h. er wartet eine bestimmte Zeit und 
setzt oder liest einen Pin. D.h. er ist immer irgendwann fertig. 
Schlimmstenfalls sind die Daten Müll oder Du kriegst ein NACK, das ist 
alles.

Samuel Müller schrieb:
> Außerdem habe ich an beiden Pin's Interrupts zur Verfügung die bestimmt
> für etwas bessere Performance sorgen könnten wenn diese mitverwendet
> werden.

Wie sollen denn diese Interrupts getriggert werden?
Wie gesagt, es sind Timings einzuhalten, mehr nicht. Die sind allerdings 
so kurz, daß ein Timerinterrupt nicht lohnt (viel zuviel 
Stack-Overhead).

von Peter D. (peda)


Angehängte Dateien:

Lesenswert?

Anbei mal meine SW-I2C Lib.

von Samuel Müller (Gast)


Lesenswert?

Danke für die Antworten, wie Peter Dannegger es geschrieben hat macht 
die verwendugn von Interrups natürlich keinen Sinn.

Ich habe mich nun für die Lib von Peter Fleury entschieden, da diese 
wohl schon sehr oft verwendet wurde und gut zu funktionieren scheint.

Erfolgreich eingebunden bin ich nun direkt auf mein nächstes Problem 
gestoßen, irgend etwas bei der Kommunikation scheint wohl nicht zu 
klappen.

Die if-Bedingung wird jedes mal erfüllt.
1
void test_ad () {
2
    unsigned char ret;
3
4
#define Adress  0xd
5
6
DDRB  = 0xff;                              // use all pins on port B for output 
7
    PORTB = 0xff;                              // (active low LED's )
8
9
    i2c_init();                                // init I2C interface
10
  
11
    // write 0x75 to eeprom address 0x05 (Byte Write) 
12
    ret = i2c_start(Adress+I2C_WRITE);       // set device address and write mode
13
    if ( ret ) {
14
        // failed to issue start condition, possibly no device found
15
        i2c_stop();
16
        PORTB=(Adress+I2C_WRITE);
17
}

Schön wäre es hier natürlich ein Oszi zu haben -.-
Als Adresse habe ich "1101" aus dem Datenblatt (Seite 19) entnommen.
Das würde ja einem "d" in hex entsprechen, habe es auch schon mit d0, b 
und b0 versucht, jedes mal das selbe Ergebnis.

Mein nächster Gedanke war das die delays zwischen den gesendeten Bits 
nicht stimmt. Dazu konnte ich folgenden Code aus der Assembler Datei 
entnehmen:
1
.stabs  "",100,0,0,i2c_delay_T2
2
  .stabs  "i2cmaster.S",100,0,0,i2c_delay_T2
3
  .func i2c_delay_T2  ; delay 5.0 microsec with 4 Mhz crystal  
4
i2c_delay_T2:        ; 4 cycles
5
  rjmp 1f      ; 2   "
6
1:  rjmp 2f      ; 2   "
7
2:  rjmp 3f      ; 2   "
8
3:  rjmp 4f      ; 2   "
9
4:  rjmp 5f      ; 2   "
10
5:   rjmp 6f      ; 2   "
11
6:  nop          ; 1   "
12
  ret          ; 3   "
13
  .endfunc     ; total 20 cyles = 5.0 microsec with 4 Mhz crystal

Aus den Kommentaren konnte ich keine explizite Anweisung entnehmen das 
hier etwas am Code geändert werden muss, jedoch verwende ich einen 16MHz 
Kristall und kann auch nirgens eine Verknüpfung mit F_CPU finden.

von Samuel Müller (Gast)


Lesenswert?

Nachtrag:
Laut Kommentar soll die Wartezeit für Normal ja 5us dauern und für fast 
1,3us. Da mein ADC-Baustein ja den fast mode unterstützt und dies bei 
meinen 16MHz ziemlich genau 20Takte sind (hoffentlich habe ich mich 
nicht verrechnet), sollte zumindest mit der Zeit ja alles passen oder?
1
; delay half period
2
; For I2C in normal mode (100kHz), use T/2 > 5us
3
; For I2C in fast mode (400kHz),   use T/2 > 1.3us

von isnah (Gast)


Lesenswert?

Bei der Assemblerdatei "i2cmaster.s" bringt dich die "C-Verknüpfung" 
F_CPU leider nicht weiter. Du musst daher auf der Maschinenebene die 
Taktzyklen zusammenzählen.

Daraus folgt ein einfacher Dreisatz:

Für eine Taktfrequenz von 4MHz braucht es eine Vrzögrtungt von 20 
Taktzyklen
Wieviele braucht es bei einer Frequenz von 16MHz?

Zur Hilfe noch meine 10MHz-Sequenz:

;*********************************************************************** 
**

; delay half period

; For I2C in normal mode (100kHz), use T/2 > 5us

; For I2C in fast mode (400kHz),   use T/2 > 1.3us

;*********************************************************************** 
**

  .stabs  "",100,0,0,i2c_delay_T2

  .stabs  "i2cmaster.S",100,0,0,i2c_delay_T2

  .func i2c_delay_T2  ; delay 5.0 microsec with 4 Mhz crystal

i2c_delay_T2:        ; 4 cycles

  rjmp 1f      ; 2   "

1:  rjmp 2f      ; 2   "

2:  rjmp 3f      ; 2   "

3:  rjmp 4f      ; 2   "

4:  rjmp 5f      ; 2   "

5:   rjmp 6f      ; 2   "

6:  rjmp 7f      ; 2   "

7:  rjmp 8f      ; 2   "

8:  rjmp 9f      ; 2   "

9:  rjmp 10f     ; 2   "

10:   rjmp 11f     ; 2   "

11:  rjmp 12f     ; 2   "

12:  rjmp 13f     ; 2   "

13:  rjmp 14f     ; 2   "

14:  rjmp 15f     ; 2   "

15:   rjmp 16f     ; 2   "

16:  rjmp 17f     ; 2   "

17:  rjmp 18f     ; 2   "

18:  rjmp 19f     ; 2   "

19:  rjmp 20f     ; 2   "

20:   rjmp 21f     ; 2   "

21:  nop          ; 1   "

  ret          ; 3   "

  .endfunc     ; total 50 cyles = 5.0 microsec with 10 Mhz crystal

von Karl H. (kbuchegg)


Lesenswert?

Da I2C ein getakteter Bus ist, ist es erst mal nicht besonders kritisch, 
wenn dein Master langsamer arbeitet als er könnte.

Ich denke eher, dass hier
> Als Adresse habe ich "1101" aus dem Datenblatt (Seite 19) entnommen.
das Problem liegt.

Das erste Byte in der I2C Übertragung ist eine Kombination aus Adresse 
und Modus. Das unterste Bit (LSB) gibt an, ob vom Baustein gelesen oder 
zum Baustein geschrieben werden soll. Die restlichen 7 Bit sind die 
Adresse. D.h. die Adresse muss um 1 Bit nach links geshiftet in das zu 
übertragende Byte eingehen.
Nun ist es leider so, dass aus den Datenblättern oft nicht hervorgeht, 
ob die angebene Adresse diese Verschiebung bereits berücksichtigt hat 
oder nicht.

Die Fleury Lib will auf jeden Fall die bereits um 1 Bit verschobene 
Adresse haben.

D.h. dein Adresse kann 0x0D sein, sie könnte aber auch um 1 Bit nach 
links geschoben 0x1A lauten.

Für letzteres spricht zum Beispiel, dass in 0x0D ja bereits das unterste 
Bit auf 1 ist. D.h. mittels
1
    ret = i2c_start(Adress+I2C_WRITE);
bzw.
1
    ret = i2c_start(Adress+I2C_READ);
wäre es gar nicht mehr möglich, da jemals ein 0 Bit rein zu bringen.
(d.h. mit einer Addition wäre das schon möglich. Aber eigentlich sollte 
da ja auch nicht + stehen sondern |)

: Bearbeitet durch User
von Karl H. (kbuchegg)


Lesenswert?

Ähm.
Deine Datenblatt INterpretation der Sache mit der Adresse ist aber 
höchst eigenwillig.

Denn dort steht nicht das, was du da im Thread behauptet hast.
Da steht
1
The first byte after the START bit is always the address
2
byte of the device, which includes the device code (4
3
bits), address bits (3 bits), and R/W bit. The device
4
code for the devices is 1101, which is programmed at
5
the factory. The I2C address bits (A2, A1, A0 bits) are
6
as follows:

Auf der nächsten Seite ist sogar eine Zeichnung, wie die Bits im ersten 
I2C Byte aufzufassen sind
1
     7   6   5   4   3   2   1   0
2
   +---+---+---+---+---+---+---+---+
3
   | 1 | 1 | 0 | 1 | A2| A1| A0| M |
4
   +---+---+---+---+---+---+---+---+

d.h. die Hex D finden sich im höherwertigen Nibble wieder, während das 
untere Nibble aus den auf deiner Schaltung beschalteten Eingängen A2 bis 
A0 ergibt und dazu dann noch das Modus-Bit für Schreiben oder Lesen.

D.h. je nachdem wie A2 bis A0 beschaltet sind, hast du eines der 
Adress-Bytes
1
A2 A1 A0     Adressbyte
2
--------------------------
3
 0  0  0     0xD0
4
 0  0  1     0xD2
5
 0  1  0     0xD4
6
 0  1  1     0xD6
7
 1  0  0     0xD8
8
 1  0  1     0xDA
9
 1  1  0     0xDC
10
 1  1  1     0xDE

: Bearbeitet durch User
von Samuel Müller (Gast)


Angehängte Dateien:

Lesenswert?

Meine Überlegungen gingen in die selbe Richtung wie deine Karl Heinz.
Jedoch habe ich wie oben beschrieben auch schon das ganze mit 0xD0 
ausprobiert und kein anderes Resultat erzielt. Die Adress Bits A0, A1 
und A2 scheinen bei meinem Baustein (MCP3426) keine Rolle zu spielen, 
heißt wohl es ist egal welche Werte sie besitzten?

Anbei noch mal der Ausschnitt aus dem Datenblatt über den wir gerde 
reden.

von Karl H. (kbuchegg)


Lesenswert?

Samuel Müller schrieb:

> Die Adress Bits A0, A1
> und A2 scheinen bei meinem Baustein (MCP3426) keine Rolle zu spielen,
> heißt wohl es ist egal welche Werte sie besitzten?


Was heißt 'scheinen'?
Die sind auf der Platine die du hast irgendwie verkabelt. Schau halt auf 
die Platine wie genau sie verschaltet sind.

Nix 'scheinen'. 'wissen' ist gefragt.

: Bearbeitet durch User
von Samuel Müller (Gast)


Lesenswert?

In meinem ersten Beitrag ist das Schaltbild des Bausteines zu erkennen 
auf dem deutlich "sichtbar" keine Adresspins vorhanden sind. Hier vlt 
noch ein Satz aus dem Datenblatt "The MCP3427 and MCP3428 have two 
external
device address pins (Adr1, Adr0).".

Da diese Pins bei mir nicht vorhanden sind "scheinen" die Adress Bits 
bei mir keine Rolle zu spielen da in diesem Zusammenhang nicht weiter 
auf die Version MCP3426 eingegangen wird.

von Karl H. (kbuchegg)


Lesenswert?

Samuel Müller schrieb:

> Da diese Pins bei mir nicht vorhanden sind "scheinen" die Adress Bits
> bei mir keine Rolle zu spielen da in diesem Zusammenhang nicht weiter
> auf die Version MCP3426 eingegangen wird.

Jein.
Im Datenblatt steht, dass sie beim 26-er factory programmed sind. D.h. 
irgendeine der 8 Adressen ist die richtige.

von Samuel Müller (Gast)


Lesenswert?

Also ich verstehe das so, das nur der Device Code programmiert ist. Aber 
ich will ja nichts unversucht lassen, darum habe ich es direkt ein mal 
ausprobiert mit 0xD0 bis 0xDE und habe wieder kein positives Resultat 
erzielt -.-

von Karl H. (kbuchegg)


Lesenswert?

Samuel Müller schrieb:
> Also ich verstehe das so, das nur der Device Code programmiert ist.

Im Datenblatt steht explizit, dass die Adressen (nicht nur der Device 
Code) factory programmed sind.

Ich würde mal davon ausgehen, dass der Hersteller die Adresse 0xD0 
genommen hat (also die Adressbits alle 0). Allerdings: wenn er das immer 
so gemacht hat, dann wäre das auch so dokumentiert. Er hat sich also 
eine Hintertür offen gelassen.

> Aber
> ich will ja nichts unversucht lassen, darum habe ich es direkt ein mal
> ausprobiert mit 0xD0 bis 0xDE und habe wieder kein positives Resultat
> erzielt -.-

Tja. Jetzt hast du ein Problem.
Entweder bist du auf der falschen Adresse oder es ist sonst noch was 
falsch, oder beides.

Es ist halt nie gut, wenn man zuviele Unbekannte im Spiel hat.
Hast du denn nicht noch einen Prozessor, bei dem du Hardware-TWI zur 
Verfügung hast, so dass man erst mal davon ausgehen kann, dass I2C 
grundsätzlich funktionieren müsste?

Alternativ: hast du ein anderes I2C-IC, dessen Adresse du kennst?

Ziel der Sache ist es, erst mal etwas Stochern-im-Nebel durch Bekanntes 
zu ersetzen.

: Bearbeitet durch User
von Samuel Müller (Gast)


Lesenswert?

Leider nicht, das ist eine fertig zusammengelötete Platine und an dem 
I2C-Bus hängt nur der AD-Wandler dran. Ich hätte zwar noch einen 
Controller, Wandler, Widerstände und Kondensatoren aber das alles 
freiluft zu verkabeln würde wohl eher noch mehr Fehlerquellen eröffnen 
anstatt sie zu reduzieren.

Kann ich nicht z.B. über den Interrupt und eine LED eine Art debugging 
machen das ich sehe ob der Baustein überhaupt irgend etwas macht oder 
meine Kommunikationsversuche komplett ignoriert.
Für die Adresse kann ich theoretisch auch ne Schleife einbauen, das mein 
Controller einfach alle verfügbaren Adressen durchprobiert.

von Peter D. (peda)


Lesenswert?

Samuel Müller schrieb:
> Für die Adresse kann ich theoretisch auch ne Schleife einbauen, das mein
> Controller einfach alle verfügbaren Adressen durchprobiert.

Genau so.
Erstmal nur die Adresse senden und prüfen, ob ein ACK kommt.

Immer Schritt für Schritt vorgehen:
http://www.youtube.com/watch?v=ncFCdCjBqcE

von Samuel Müller (Gast)


Lesenswert?

Also ich habe mir nun eine Schleife gebaut die jede mögliche Adesse 
probiert und wenn ein ACK kommt mir diese an den LED's anzeigen soll. 
Leider auch hier kein Ergebnis.
1
while (Adress < 0xff) {
2
3
    ret = i2c_start(Adress);
4
    if ( ret ) {
5
      i2c_stop();
6
    }
7
    else {
8
      PORTB=(Adress);
9
    }
10
    Adress += 1;
11
  }

Nun habe ich auch mal den analogen Multiplexer ausgelötet der an dem 
Analogeingang des ADC angebracht ist, trotzdem nichts.
Mittlerweile frage ich mich wirklich ob der ADC noch richtig 
funktioniert, denn softwaremäßig kann ja jetzt eigentlich nciht mehr 
viel falsch sein oder?

von Samuel Müller (Gast)


Lesenswert?

Gibt es irgend eine Möglichkeit heraus zu finden ob das Bauteil noch 
richtig funktioniert?

von holger (Gast)


Lesenswert?

>Gibt es irgend eine Möglichkeit heraus zu finden ob das Bauteil noch
>richtig funktioniert?

Ja, korrekte I2C Routinen schreiben und das Viech
damit abfragen. Auf den Rücken legen und mit einem
Kugelschreiber drauf rumdrücken wird wohl nichts bringen.

von Peter D. (peda)


Lesenswert?

Ich kenn die Fleury-Lib nicht.
Warum da Assembler verwendet wird, ist komisch.
I2C ist nicht zeitkritisch, kann man also komplett in C schreiben.

Häng mal 2 LEDs (+R) gegen VCC an SDA und SCL, die müssen bei Traffic 
flackern bzw. ohne Traffic aus sein.

von greg (Gast)


Angehängte Dateien:

Lesenswert?

Hab vor Jahren für den 8051 mal diesen Supersimpel-Soft-I2C geschrieben. 
Kein clock stretching, kein multimaster, aber wenig Code und 
funktioniert.
Mit minimaler Arbeit kann man das für den AVR adaptieren. I2C ist keine 
Raketenwissenschaft.

von greg (Gast)


Lesenswert?

Nachtrag: sieh den Code als gemeinfrei (Public Domain) an.

von Samuel Müller (Gast)


Lesenswert?

holger schrieb:
> Ja, korrekte I2C Routinen schreiben und das Viech
> damit abfragen. Auf den Rücken legen und mit einem
> Kugelschreiber drauf rumdrücken wird wohl nichts bringen.

Fachlich ziemlich daneben würde ich mal sagen, vielleicht solltest du 
deine Zeit lieber in einem Forum über Tiere verbringen.

Peter Dannegger schrieb:
> Ich kenn die Fleury-Lib nicht.
> Warum da Assembler verwendet wird, ist komisch.
> I2C ist nicht zeitkritisch, kann man also komplett in C schreiben.
>
> Häng mal 2 LEDs (+R) gegen VCC an SDA und SCL, die müssen bei Traffic
> flackern bzw. ohne Traffic aus sein.

Heißt ich könnte das versuchsweise auch mal mit ms Delays probieren?
Bei den normalen 5us wird da ja wohl nicht sehr viel zu sehen sein.

von greg (Gast)


Lesenswert?

Hmpf, wenn ich mir meinen alten Code da anschaue, könnte man da einige 
Sachen auf Anhieb besser machen. ;) Z.B. könnte man den Typ vom 
Parameter "ack" bei i2c_read auf unsigned char ändern. Wie auch immer, 
als Basis sollte das passen.

von Karl H. (kbuchegg)


Lesenswert?

Samuel Müller schrieb:

> Heißt ich könnte das versuchsweise auch mal mit ms Delays probieren?

Du kannst auch Sekunden nehmen. I2C ist nicht zeitkritisch, da die 
Übertragung getaktet ist. Siehe gregs Code.
Warum P.Fleury das in Assembler gemacht hat, erschliesst sich mir auch 
nicht wirklich. Die Hardware-I2C ist in C geschrieben.
Nimm gregs Code und überarbeite ihn für den M32. Ist nicht wirklich viel 
Arbeit. Das bisschen Pin hoch, Pin runter ist nicht die Welt.

: Bearbeitet durch User
von Samuel Müller (Gast)


Lesenswert?

greg schrieb:
> Hmpf, wenn ich mir meinen alten Code da anschaue, könnte man da
> einige
> Sachen auf Anhieb besser machen. ;) Z.B. könnte man den Typ vom
> Parameter "ack" bei i2c_read auf unsigned char ändern. Wie auch immer,
> als Basis sollte das passen.

Danke für das Beispiel, ich werde es mir morgen direkt mal ansehen, 
möchte ja nichts unversucht lassen.

Zur Sicherheit habe ich direkt mal noch einen neuen AD-Wandler bei 
Reichelt bestellt, wie ich die kenne dauert das aber bestimmt noch ne 
Weile bis der kommt.

von holger (Gast)


Lesenswert?

>Fachlich ziemlich daneben würde ich mal sagen, vielleicht solltest du
>deine Zeit lieber in einem Forum über Tiere verbringen.

Leg dich besser nicht mit den grossen Jungs an.

Vieleicht solltest du deine Zeit mal damit verbringen
die I2C Spec zu lesen. Das hast du sicher nicht getan.

Lies deine Frage noch mal

>Gibt es irgend eine Möglichkeit heraus zu finden ob das Bauteil noch
>richtig funktioniert?

Es ist ein Bauteil was per I2C angesteuert wird. Wie soll
man das ohne korrekte I2C Routinen schaffen?

Der einzige der hier in den Zoo gehört bist du.
Selbst mit fremder Hilfe schaffst du es nicht so etwas
simples wie einen I2C Baustein auszulesen.

Ist deine Schaltung überhaupt in Ordnung?
Besorg dir mal ein Speicherosci oder einen Logicanalyzer.

Dann reden wir weiter.

von Samuel Müller (Gast)


Angehängte Dateien:

Lesenswert?

Problem gefunden ... -.-

von isnah (Gast)


Lesenswert?

Der Fehler ist so trivial, dass keiner darauf gekommen ist - Hut ab, 
dass du ihn trotzdem noch bekannt gemacht hast. ;-)

von hilfesuchender (Gast)


Lesenswert?

Beitrag "Re: Soft I2C Master"

Kann mir jemand erklären welche Pins für diese Lib verwenden werden?

Danke Lg

von Peter D. (peda)


Angehängte Dateien:

Lesenswert?

hilfesuchender schrieb:
> Kann mir jemand erklären welche Pins für diese Lib verwenden werden?

Die kannst Du frei wählen.

SSDA, SSDA_DDR, SDA_PIN und SSCL, SSCL_DDR
definierst Du entsprechend aus der "sbit.h".

von hilfesuchender (Gast)


Lesenswert?

kannst Du mir bitte ein Beispiel  machen wie das aussehen Soll?
Verstehe die angehängte Datei nicht!

Danke und ein Frohes Fest

von Peter D. (peda)


Lesenswert?

1
#include "sbit.h"
2
3
#define SSDA     PORT_A0
4
#define SSDA_DDR  DDR_A0
5
#define SSDA_PIN  PIN_A0
6
#define SSCL     PORT_A1
7
#define SSCL_DDR  DDR_A1

von hilfesuchender (Gast)


Lesenswert?

Vielen Dank Peter für deine tolle Hilfe!
Sehr nett!

von der kleine Nils (Gast)


Lesenswert?

Auch wenn der Trend etwas älter ist!
Ich möchte gern den Code von Peter Dannegger verwenden!
Beitrag "Re: Soft I2C Master"

Habe aber nicht ganz verstanden wie ich ein Byte von einem I2c Slave mit 
Nack lesen Kann!
Kann es mir jemand erklären!
Vielen Lieben Dank
Und ein frohes Fest!

von der kleine Nils (Gast)


Lesenswert?

Kann mir jemand lincht ins dunkel bringen?

von Karl H. (kbuchegg)


Lesenswert?

Ich versteh die Frage nicht.

Was ist an der Funktionssignatur
1
static uint8_t si2c_r( uint8_t nack )      // input NACK
unklar?

rufst du si2c_r mit einem 0 als Argument auf, dann wird ein ACK 
gesendet. Rufst du es mit einer 1 als Argument auf, dann wird ein NACK 
generiert.

So wie hier
1
uint8_t eeprom_rd( uint16_t eeaddr, uint8_t *sram, uint16_t len )
2
{
3
...
4
  do
5
    *sram++ = si2c_r( !--len );        // NACK on last byte
6
  while( len );
7
...

Ein bischen Codestudium ist jedem zuzumuten.

von der kleine Nils (Gast)


Lesenswert?

Aber warum verwendet Peter 16Bit Variablen?
I2c verwendet normalerweise doch 8 Bit Variablen!
Entschuldige meine Dummen Fragen!

von Karl H. (kbuchegg)


Lesenswert?

der kleine Nils schrieb:
> Aber warum verwendet Peter 16Bit Variablen?

Man haette die rw Funktion auch mit einer lokalen Variablen machen 
können, wenn du das meinst.

Die für dich relevanten funktionen
1
static uint8_t si2c_r( uint8_t nack )      // input NACK
2
...
3
4
static uint8_t si2c_w( uint8_t val )      // input data
5
...
arbeiten mit Bytes.

von der kleine Nils (Gast)


Lesenswert?

Vielen Dank für deine Hilfe!
Also verstehe ich richtig das die Funktion si2c_r für Read steht und die 
Funktion si2c_w für write?

Ich also nur die zwei Funktionen Verwenden brauche wenn ich einen 
I2C_ADC auslesen will?

Danke für deine Geduld!

von der kleine Nils (Gast)


Lesenswert?

Habe etwas herum experimentiert!
Ich musste damit ich vernünftige Daten auf dem Bus (I2c_Sniffer von 
Peter)
den Takt um eine 10 Potenz verkleinern!
So geht es aber ich verstehe nicht warum es mir dem großen Takt nicht 
geht!

Danke für Eure Hilfe

von Peter D. (peda)


Lesenswert?

der kleine Nils schrieb:
> So geht es aber ich verstehe nicht warum es mir dem großen Takt nicht
> geht!

Das ist nur ein einfacher Master ohne SCL-Stretching Support. Der kann 
daher nur einfache Slaves und keine I2C-MCs ansteuern.
Der Sniffer ist aber ein MC und benutzt SCL-Stretching.

von der kleine Nils (Gast)


Lesenswert?

Achso ich verstehe!
Danke

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.