Forum: Mikrocontroller und Digitale Elektronik Auswahl Adressen I2C Bus am Attiny 841


von Heiner (Gast)


Lesenswert?

Mit dem folgenden Programm kann ich mit 3 Jumper 8 verschiedene Adressen 
am Attiny 841 einstellen. Dabei verwende ich die folgenden Pins:
- A0 PA1
- A1 PA2
- A2 PA3
PA1 und PA2 und PA3 liegen über einen Widerstand nach Vcc (5V). Mit dem 
Jumper wird der PIN auf GND gelegt. Bei der Kontrolle stimmen die 
Belegung aber nicht überein.
1
 
2
//  Adresse       HEX     Dez    Adressen   Jumper          Berechnet
3
#define Adress_1  0x20    // 50 Slave Adresse 1 A0, A1, A2 offen    --> 0x32
4
#define Adress_2  0x22    // 48 Slave Adresse 2 A0 auf GND        --> 0x30
5
#define Adress_3  0x24    // 46 Slave Adresse 3 A1 auf GND        --> 0x2E
6
#define Adress_4  0x26    // 38 Slave Adresse 4 A2 auf GND        --> 0x26
7
#define Adress_5  0x28    // 36 Slave Adresse 5 A0 und A1 auf GND    --> 0x24
8
#define Adress_6  0x30    // 34 Slave Adresse 6 A0 und A2 auf GND    --> 0x22
9
#define Adress_7  0x32    // 32 Slave Adresse 7 A1 und A2 auf GND    --> 0x20
10
#define Adress_8  0x34    // 30 Slave Adresse 8 A0, A1 und A2 auf GND  --> 0x20
11
12
uint8_t I2C_SLAVE_ADDRESS;
13
14
#define S1 (1<<PINA1)  // Jumper A0, Auswahl auf GND
15
#define S2 (1<<PINA2)  // Jumper A1, Auswahl auf GND
16
#define S3 (1<<PINA3)  // Jumper A2, Auswahl auf GND
17
18
void auswahl_sw()
19
  {
20
  uint8_t Schalter = PINA & (S1 | S2 | S3);
21
  switch (Schalter)
22
    {              // betrachte die Eingangsmenge der Schalterstellung(en) von S1 und S2 und S3
23
    case  0:    I2C_SLAVE_ADDRESS = Adress_1;    // Adresse 50 - A0, A1, A2 offen - 0x32
24
      break;
25
    case S1:    I2C_SLAVE_ADDRESS = Adress_2;    // Adresse 48 A0 auf GND - 
26
      break;
27
    case S2:    I2C_SLAVE_ADDRESS = Adress_3;    // Adresse 46 A1 auf GND - 
28
      break;
29
    case S3:  I2C_SLAVE_ADDRESS = Adress_4;    // Adresse 38 A2 auf GND - 
30
      break;
31
    case S1|S2: I2C_SLAVE_ADDRESS = Adress_5;    // Adresse 36 A0 und A1 auf GND
32
      break;
33
    case S1|S3: I2C_SLAVE_ADDRESS = Adress_6;    // Adresse 34 A0 und A2 auf GND -
34
      break;
35
    case S2|S3:  I2C_SLAVE_ADDRESS = Adress_7;    // Adresse 32 A1 und A2 auf GND -
36
      break;
37
    case S1|S2|S3: I2C_SLAVE_ADDRESS = Adress_8; // Adresse 30 A0, A1, A2 auf GND
38
      break;    
39
    }
40
  }
Leider finde ich keinen Grund da für. Es funktioniert, aber leider 
falsch.
Die Kontrolle der Adressen habe ich von einem Master durchgeführt und 
die Adressen suchen lassen.
LG Heiner

von (prx) A. K. (prx)


Lesenswert?

Heiner schrieb:
> Es funktioniert, aber leider falsch.

Gehts genauer?

von c-hater (Gast)


Lesenswert?

Heiner schrieb:

> PA1 und PA2 und PA3 liegen über einen Widerstand nach Vcc (5V). Mit dem
> Jumper wird der PIN auf GND gelegt.

Aha. Negative Logik.

>   switch (Schalter)
>     {              // betrachte die Eingangsmenge der
> Schalterstellung(en) von S1 und S2 und S3
>     case  0:    I2C_SLAVE_ADDRESS = Adress_1;    // Adresse 50 - A0, A1,
            ^^^
> A2 offen - 0x32
     ^^^

Und wie passt das dazu (Auszug willkürlich gewählt, der Fehler zieht 
sich durch das gesamte Statement)? Das ist positive Logik.

Immerhin, wennschon falsch, dann wenigstens konsequent...

> Leider finde ich keinen Grund da für.

Weil du halt nicht selber denken kannst. Ganz schlecht...

von (prx) A. K. (prx)


Lesenswert?

Heiner schrieb:
> case S1|S2|S3: I2C_SLAVE_ADDRESS = Adress_8;
> // Adresse 30 A0, A1, A2 auf GND

Wenn Sx auf GND, dann wird 0 gelesen. Nicht Sx.

von Heiner (Gast)


Lesenswert?

Komisch, wenn ich nicht denken kann, wo kommt dann das Programm her?
Positiv und negativ leider etwas durcheinander.
Auf jeden Fall, für euren Hinweis.

von c-hater (Gast)


Lesenswert?

Heiner schrieb:

> Komisch, wenn ich nicht denken kann, wo kommt dann das Programm her?

Das Problem ist nicht, den Fehler zu machen. Das oder ähnliches ist sehr 
wahrscheinlich jedem schonmal passiert.

Das Problem ist: du hast ihn nicht selbstständig erkannt und das trotz 
deutlicher (und von dir korrekt erkannter) Anzeichen. Du hattest doch 
bereits erkannt, dass der Code "im Prinzip" das richtige macht, nämlich 
für 8 unterschiedliche Jumper-Konfigurationen acht unterschiedliche 
Adressen zu konfigurieren. Und du hast auch erkannt, dass es die 
gewünschten Adressen sind. Sie passten halt nur nicht zur Erwartung 
bezüglich der Jumper.

Da bleibt dann nicht mehr sehr viel zu denken. Aber eben offensichtlich 
auch: zu viel für dich...

von Martin (Gast)


Lesenswert?

Heiner schrieb:

> Komisch, wenn ich nicht denken kann, wo kommt dann das Programm her?
> Positiv und negativ leider etwas durcheinander.
> Auf jeden Fall, für euren Hinweis.

Du solltest dem asozialen Typen nicht mal indirekt antworten. Der gehört 
verachtet und geächtet.

von (prx) A. K. (prx)


Lesenswert?

Heiner schrieb:
> Komisch, wenn ich nicht denken kann, wo kommt dann das Programm her?
> Positiv und negativ leider etwas durcheinander.

Ist eine hässliche aber ziemlich konsequent durchgezogene Angewohnheit 
von c-hater: sich über seine Ausdrucksweise selbst dann ins Abseits zu 
stellen, wenn er ansonsten inhaltlich Recht haben sollte.

: Bearbeitet durch User
von Heiner (Gast)


Lesenswert?

In einer Sache muss ich ich Recht geben. Er hat mir den fehker gezeigt. 
Über den Ton muss man wohl erhaben sein. Es geht alles in einem 
freundlichen Ton.
Früher gabe es man den Begriff: ... schlechte Kindheit gehabt..
Wir haben da was gemeinsames. Ich kann meine Kenntnisse in C stark 
verbessern und andere können am Ton arbeiten.
Nicht für ungut. wohl wir mal schauen wie deas besser geht.

von Heiner (Gast)


Lesenswert?

Da ich hier die negative und positive Logik verwechselt habe such ich 
nach einer Lösung.
So steht es im ori bei mir.
#define S3 (1<<PINA3)  // Jumper A2, Auswahl auf GND
Eine Möglickeit ist zu negieren. z.B. so:
#define S3 (!(1<<PINA3))  // Jumper A2, Auswahl auf GND
Ergibt eine Fehlermeldung

von (prx) A. K. (prx)


Lesenswert?

Heiner schrieb:
> Eine Möglickeit ist zu negieren. z.B. so:
> #define S3 (!(1<<PINA3))  // Jumper A2, Auswahl auf GND
> Ergibt eine Fehlermeldung

Rechne diese Werte von Hand aus, und setze die in
   case S1|S1|S3:
ein.

von Egonwalter M. (heiner1234)


Lesenswert?

Heiner schrieb:
> Da ich hier die negative und positive Logik verwechselt habe such ich
> nach einer Lösung.
> So steht es im ori bei mir.
> #define S3 (1<<PINA3)  // Jumper A2, Auswahl auf GND
> Eine Möglickeit ist zu negieren. z.B. so:
> #define S3 (!(1<<PINA3))  // Jumper A2, Auswahl auf GND
> Ergibt eine Fehlermeldung

Dann check nochmal Bitoperationen, Heiner!

Tipp: Dein letztes #define S3 (!(1<<PINA3)) - WIE LOESCHT MAN BITS?????

: Bearbeitet durch User
von Stefan F. (Gast)


Lesenswert?

Warum so kompliziert?
1
uint8_t adresse=0x20;       // Startadresse
2
adresse += PINA & 0b1110;   // 0-14 addieren (je nach Schalterstellung)

von Hannes (Gast)


Lesenswert?


von Stefan F. (Gast)


Lesenswert?

Oder wenn du die Logik wirklich negieren willst, dann halt so:
1
uint8_t adresse=0x20;       // Startadresse
2
adresse += ~PINA & 0b1110;  // 0-14 addieren (je nach Schalterstellung)

Du hast die Hex-Zahlen falsch hoch gezählt, richtig wäre

#define Adress_1  0x20
#define Adress_2  0x22
#define Adress_3  0x24
#define Adress_4  0x26
#define Adress_5  0x28
#define Adress_6  0x2A   <--- ab hier war es falsch
#define Adress_7  0x2C
#define Adress_8  0x2E

von Heiner (Gast)


Lesenswert?

Hannes schrieb:
> Das ist doch von Dir ...
>
> 
https://www.makerconnect.de/index.php?resources/attiny-841-ein-ic-und-5-verschiedene-module-teil-3-ein-und-ausg%C3%A4nge.82/

Hat Ähnlichkeit, sogar recht grosse

Stefan ⛄ F. schrieb:
> Oder wenn du die Logik wirklich negieren willst, dann halt so:
> uint8_t adresse=0x20;       // Startadresse
> adresse += ~PINA & 0b1110;  // 0-14 addieren (je nach Schalterstellung)
>
> Du hast die Hex-Zahlen falsch hoch gezählt, richtig wäre
>
> #define Adress_1  0x20
> #define Adress_2  0x22
> #define Adress_3  0x24
> #define Adress_4  0x26
> #define Adress_5  0x28
> #define Adress_6  0x2A   <--- ab hier war es falsch
> #define Adress_7  0x2C
> #define Adress_8  0x2E

Bin gerade dabei verschiedene Versionen zu testen. Mit 0x2A hast du 
recht, wollte einfach erst mal sehen ob es funktioniert. Kümmere mich 
erst mal um das negieren und werde berichten
Danke

von Egonwalter M. (heiner1234)


Lesenswert?

Heiner schrieb:
> Hannes schrieb:
>> Das ist doch von Dir ...
>>
>>
> 
https://www.makerconnect.de/index.php?resources/attiny-841-ein-ic-und-5-verschiedene-module-teil-3-ein-und-ausg%C3%A4nge.82/
>
> Hat Ähnlichkeit, sogar recht grosse
>
Steh' dazu, Kollega!!

> Stefan ⛄ F. schrieb:
>> Oder wenn du die Logik wirklich negieren willst, dann halt so:

>> #define Adress_6  0x2A   <--- ab hier war es falsch
>> #define Adress_7  0x2C
>> #define Adress_8  0x2E
>
> Bin gerade dabei verschiedene Versionen zu testen. Mit 0x2A hast du
> recht, wollte einfach erst mal sehen ob es funktioniert. Kümmere mich
> erst mal um das negieren und werde berichten
> Danke

Aha, erst mal probieren und wenn's nicht funktioniert, um Hilfe rufen 
anstatt selbst nachzudenken

von Peter D. (peda)


Lesenswert?

Heiner schrieb:
> uint8_t Schalter = PINA & (S1 | S2 | S3);

Negieren geht ganz einfach:
1
  uint8_t Schalter = ~PINA & (S1 | S2 | S3);

von Sebastian W. (wangnick)


Lesenswert?

Ich würde es wohl etwa so machen:
1
// (CC) BY-NC-SA
2
uint8_t i2c_addr[8] PROGMEM = {0x20,0x22,0x24,0x26,0x28,0x2A,0x2C,0x2E};
3
4
#define I2C_PINS PINA
5
#define I2C_MASKS1 (1<<PINA1)  // Jumper A0, Auswahl auf GND
6
#define I2C_MASKS2 (1<<PINA2)  // Jumper A1, Auswahl auf GND
7
#define I2C_MASKS3 (1<<PINA3)  // Jumper A2, Auswahl auf GND
8
9
uint8_t i2c_slave_addr () {
10
    uint8_t sel = !(I2C_PINS&I2C_MASKS1) 
11
            | (!(I2C_PINS&I2C_MASKS2)<<1) 
12
            | (!(I2C_PINS&I2C_MASKS3)<<2);
13
  return pgm_read_byte(i2c_addr+sel);
14
}

von Hannes (Gast)


Lesenswert?

Guter Ansatz, wird Heiner aber nicht nutzen können, da er es nicht 
versteht 🤷‍♂️

von Joachim B. (jar)


Lesenswert?

Stefan ⛄ F. schrieb:
> Oder wenn du die Logik wirklich negieren willst, dann halt so:
+1

klaro, man negiert ~ und hat wieder positive Logik, ist der übliche Weg!
Port mit Bits einlesen, negieren und "undieren" fertig.

Kann man ja auch auf Papier erst mal machen und/oder in 
Einzelschritten/Einzelzeilen! mit Debug Seriell print Ausgabe.

Wenn es auf dem Papier klappt und in Einzelschritten kann man den Code 
passend kürzen wenn nötig.
Das größte "Problem" ist wenn Anfänger alles in eine Zeile quetschen 
wollen ohne Regeln, Klammersetzung, Punkt vor Strichrechnung und noch 
mit implizite Casts, das kann nur schiefgehen!

von Egonwalter M. (heiner1234)


Lesenswert?

Joachim B. schrieb:

> Das größte "Problem" ist wenn Anfänger alles in eine Zeile quetschen
> wollen ohne Regeln, Klammersetzung, Punkt vor Strichrechnung und noch
> mit implizite Casts, das kann nur schiefgehen!

Das passiert dann, wenn man ohne nachzudenken
- Code aus dem Internet nimmt
- ihn ohne zu verstehen, WAS er macht, zusammenkopiert
- keine Ahnung von Bitmanipulation hat

dann aber hofft, dass es "schon irgendwie funktioniert" und wenn's nicht 
klappt ...

SCNR

und nb - hier sind so viele Tipps und Hinweise gegeben worden ...

: Bearbeitet durch User
von Heiner (Gast)


Lesenswert?

Egonwalter M. schrieb:
> Steh' dazu, Kollega!!

Ich steh dazu. Ziehe es aber vor meine Probleme vorher zu klären, da ich 
keine Lust habe mir Beleidigungen anzuhören. Mir geht es um Technik 
dabei. Es gibt hier viele studierte Leute die das ganze mal richtig 
gelernt (studiert) haben.
Es gibt aber auch Leute die sich über jeden Erfolg, über jede 
funktionierende Zeile Code freuen. Was bleibt den jenen Leuten übrig als 
Codes aus dem Internet zu holen und solange dran zu schrauben und zu 
fragen bis es verstanden wurde.
Habe einen Grundsatz dabei, frage so lange bis ich auch die Erklärung 
verstanden habe. Leider ist ja de Attiny 841 im Netz sehr kurz gekommen, 
kaum Code, kaum Beispeiel dazu. Was bleibt einen anderes als zu fragen.

Egonwalter M. schrieb:
> Aha, erst mal probieren und wenn's nicht funktioniert, um Hilfe rufen
> anstatt selbst nachzudenken

Warum sagst du gleich ohne nachzudenken. Habe die Teile im Buch studiert 
und im Netz die entsprechenden Teile durchgelesen. Habe angefangen mir 
die Teile und Rechnungen aufzuschreiben. Hab selber einen Weg genommen, 
der nicht drin steht, und es geändert. Es gibt verschiedene Wege nach 
Rom. Auch die Möglichkeit von Peter mit ~ habe ich genommen.
Peter hat schon vor einigen Jahren geschrieben das der Code eingerückt 
werden muss und die Klammern zugeordnet werden. Genau das mache ich. 
Schau ganz oben ob das richtig ist.
LG Heiner

von Egonwalter M. (heiner1234)


Lesenswert?

Hallo Heiner

Ich bin von einer falschen Voraussetzung ausgegangen; ich dachte, 
nachdem das oben erwähnte PDF "I2C Bus und der Attiny 841 - Teil3 Ein- 
und Ausgänge" von Dir ist, Du würdest Dich mit dem Bus und dem Einlesen 
und dem Verarbeiten der Ports auskennen.

Mein Fehler.

Tut mir leid.

: Bearbeitet durch User
von Heiner (Gast)


Lesenswert?

Am Bus arbeite ich noch sehr stark. Der Unterschied ist doch relativ 
gross für mich. Es ist nicht dein Fehler, sondern meine Unwissenheit.

von Joachim B. (jar)


Lesenswert?

Heiner schrieb:
> Leider ist ja de Attiny 841 im Netz sehr kurz gekommen,
> kaum Code, kaum Beispeiel dazu. Was bleibt einen anderes als zu fragen.

sorry, das kann man nicht gelten lassen, das negieren und invertiert 
einzulesen und die Bits abfragen und die Bits ausmaskieren hat NICHTS 
mit dem Attiny 841 zu tun und hat auch nicht mit dem I2C Bus zu tun!

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.