Kleine Frage zu TWI bzw. I²C Ansteuerung

Gast #5693065
Lesenswert?

Moin,

ich möchte mein OLED (SSD1306) mit einem Atmega über TWI ansteuern.
Das ganze natürlich mit Assembler.
Ich habe bereits die Liste mit den ganzen Befehlen für das OLED 
vorbereitet, aber ich kann aus dem Datenblatt nicht genau entnehmen, wie 
ich ein loses Datenbyte sende um das GDDRAM zu beschreiben (bzw. ein 
Segment von der jeweiligen Page).
Ich lese etwas von "Data/Command Section Bit" und "Continuation Bit".

Natürlich sagt der Name bereits alles, aber wie und in welcher 
Reihenfolge setze ich das "Data/Command Bit"?
(In dem Diagramm vom Hersteller ist das nicht ganz ersichtlich finde 
ich)

Und wozu braucht man ein "Continuation Bit", denn dafür ist doch das 
senden/unterdrücken vom Stop Signal da.

Dankö schon mal ^^
Gast #5693078
Lesenswert?

int 21h schrieb:
> Natürlich sagt der Name bereits alles, aber wie und in welcher
> Reihenfolge setze ich das "Data/Command Bit"?
> (In dem Diagramm vom Hersteller ist das nicht ganz ersichtlich finde
> ich)

Ich kann das "nicht ersichtlich Finden" nicht nachvollziehen.

Ist im Diagramm klar dargestellt.
Angehängte Dateien:
Gast #5693087
Lesenswert?

1
void ssd1306_command_start (void)
2
{
3
  I2C_SetStart (SSD1306_SA);   // Slave address
4
  I2C_WriteByte (0x00);        // write command
5
}
6

7
void ssd1306_send_command (uint8_t command)
8
{
9
  ssd1306_command_start ();
10
  I2C_WriteByte (command);
11
  I2C_SetStop ();
12
}
13

14
void ssd1306_send_data_start (void)
15
{
16
  I2C_SetStart (SSD1306_SA);   // Slave address
17
  I2C_WriteByte (0x40);        // write data
18
}
Gast #5693107
Lesenswert?

Ich hänge noch mal einen Ausschnitt vom Diagramm an.
Daraus entnehme ich, dass man nach der Slave Adresse immer ein "Control 
Byte" mitgibt (und davon Bit 5-0 immer Low sind).
Aber ich verstehe immer noch nicht den Zweck des Continuation Bits.
Und dem Diagramm ist zu entnehmen, dass nach jedem Databyte wider ein 
Controlbyte folgt. Könnte man sich das nicht sparen?
Angehängte Dateien:
Gast #5693121
Lesenswert?

Bessa Wissa schrieb:
> void ssd1306_command_start (void)
> {
>   I2C_SetStart (SSD1306_SA);   // Slave address
>   I2C_WriteByte (0x00);        // write command
> }
>
> void ssd1306_send_command (uint8_t command)
> {
>   ssd1306_command_start ();
>   I2C_WriteByte (command);
>   I2C_SetStop ();
> }
>
> void ssd1306_send_data_start (void)
> {
>   I2C_SetStart (SSD1306_SA);   // Slave address
>   I2C_WriteByte (0x40);        // write data
> }

Bei ssd1306_command_start sowie bei ssd1306_send_data_start ist das 
"Data command selection Bit" auf Low.
Nur bei send_data setzt du das "Co" Bit auf High.
Aber macht das Sinn?
Gast #5694353
Lesenswert?

Ich habe die "ssd1306_send_data" Routine soweit fertig gestellt.
Auf meinem OLED wird aber noch nichts dargestellt.
Um mich jetzt noch einmal auf Fehlersuche zu begeben, muss noch etwas 
geklärt werden.

Mal Angenommen ich möchte jetzt ein Datenbyte an das OLED senden um 8 
Pixel vom Display weiß darzustellen.
Das mache ich mit der TWI Schnittstelle vom Atmega328p folgendermaßen:

-> START einleiten
-> TWI Datenregister mit der SLAVE_ADD+W beschreiben
-> TWI Datenregister ausgeben
-> TWI Datenregister mit dem Controlbyte beschreiben (0x40)
-> TWI Datenregister ausgeben
-> TWI Datenregister mit dem jeweiligen Byte beschreiben
-> TWI Datenregister ausgeben
-> STOP einleiten

Mir ist jetzt nicht ganz klar, wie sich die Slave Adresse darstellt.
Laut meinen Quellen über TWI besteht die Slave Adresse immer auf 7 Bit!
Das letzte Bit sagt dann aus ob das GDDRAM gelesen oder beschrieben 
werden soll.
In dem Diagramm (siehe oben) stehen aber nur 6 Bits für die Adresse.
Wofür ist das nächste Bit (SA0) da, also Bit 1?
Laut Datenblatt:
"For the SSD1306, the slave address is either “b0111100” or “b0111101” 
by changing the SA0 to LOW or HIGH (D/C pin acts as SA0)."
Gast #5694376
Lesenswert?

Hier noch einmal der Komplette Quellcode falls jemand interessiert ist 
(was ich nicht glaube ^^)
https://pastebin.com/Ww91e33e


Bessa Wissa schrieb:
> int 21h schrieb:
>> In dem Diagramm (siehe oben) stehen aber nur 6 Bits für die Adresse.
>
> In "unserem" Fall muss die Device Adresse linksbündig stehen damit
> für das R/W Bit noch Platz bleibt.
>
> Also Device Adresse = xxxx_xxxY, Y=R/W

Kann ich das SA0 Bit also auf Low setzen?
Gast #5694405
Lesenswert?

int 21h schrieb:
> falls jemand interessiert ist (was ich nicht glaube ^^)

Was ich auch nicht glaube, denn wenn man das Display wirklich
nutzbringend ansteuern will dann ist noch "ein wenig" mehr an
Assembler-Arbeit erforderlich.

Du hast auf Assembler-Ebene auch keinerlei Zeitvorteil da die
Geschwindigkeitsbegrenzung im I2C-BusTransfer zu suchen ist,
nicht im ansteuernden Code.
(Firma: Anscheinend Corner-Cases ;-)) #5694452
Lesenswert?

int 21h schrieb:
> Hier noch einmal der Komplette Quellcode falls jemand interessiert ist
> (was ich nicht glaube ^^)
> https://pastebin.com/Ww91e33e
>
Hallo,

schön das sich noch jemand für AVR-Assembler interessiert.
Der I2C-Bus in AVR8ASM ist sogar auch mein ( längeres ) Thema, 
allerdings Interruptbasiered. D.h. ich polle nicht TWCR.TWINT.

Damit schlage ich mich herum => Auslesen eines Wii Nunchuk.

Beitrag "AVR8ASM TWI Interrupt"


Ich setze mal das von dir verlinkte Listing hier rein und auch als 
Anhang, damit andere sich daraus einfach Passagen kopieren, edidieren 
und wieder hier reinsetzen können :
1
;Program is made for the Atmega328p for connecting with the SSD1306 OLED
2
;Made by int 21h
3

4
.def temp1 = r16
5
.def temp2 = r17
6
.def temp3 = r18
7

8
.equ SLAVE_ADDRESS_W = 0b01111010
9

10
;******************************
11
;      INIT
12
;******************************
13

14
  clr   temp2
15
  clr   temp3
16

17
  ;Init Stackpointer
18
  ldi   temp1, HIGH(RAMEND)
19
  out   SPH, temp1
20
  ldi   temp1, LOW(RAMEND)
21
  out   SPL, temp1
22

23
  ldi   temp1, 0xFF
24
  out   DDRD, temp1
25
  out   DDRC, temp1 ;Don't know if needed or not
26

27
;******************************
28
;      MAIN
29
;******************************
30

31
  ldi   temp1, 0b00110011
32
  ;8*8 Dotmatrix
33
  rcall oled_send_data
34
  rcall oled_send_data
35
  rcall oled_send_data
36
  rcall oled_send_data
37
  rcall oled_send_data
38
  rcall oled_send_data
39
  rcall oled_send_data
40
  rcall oled_send_data
41

42
end:
43
  rjmp  end
44

45
;******************************
46
;      ROUTINEN
47
;******************************
48

49
oled_send_command:
50
  ;Not worked on this yet
51
  ret
52

53
oled_send_data:
54
  push  temp1
55
  rcall oled_start
56
  
57
  ;Send Slave Addres
58
  ldi   temp1, SLAVE_ADDRESS_W
59
  sts   TWDR, temp1
60
  ldi   temp1, (1 << TWINT)|(1 << TWEN)
61
  sts   TWCR, temp1
62
oled_send_data_0:
63
  lds   temp1, TWCR
64
  sbrs  temp1, TWINT
65
  rjmp  oled_send_data_0
66

67
  ;Send Control Byte
68
  ldi   temp1, 0x40
69
  sts   TWDR, temp1
70
  ldi   temp1, (1 << TWINT)|(1 << TWEN)
71
  sts   TWCR, temp1
72
oled_send_data_1:
73
  lds   temp1, TWCR
74
  sbrs  temp1, TWINT
75
  rjmp  oled_send_data_1
76

77
  ;Send Byte
78
  pop   temp1
79
  push  temp1
80
  sts   TWDR, temp1
81
  ldi   temp1, (1 << TWINT)|(1 << TWEN)
82
  sts   TWCR, temp1
83
oled_send_data_2:
84
  lds   temp1, TWCR
85
  sbrs  temp1, TWINT
86
  rjmp  oled_send_data_2
87

88
  rcall oled_stop
89
  pop   temp1
90
  ret
91

92
oled_start:
93
  push  temp1
94
  ldi   temp1, (1 << TWINT)|(1 << TWSTA)|(1 << TWEN)
95
  sts   TWCR, temp1
96
oled_start_0:
97
  lds   temp1, TWCR
98
  sbrs  temp1, TWINT
99
  rjmp  oled_start_0
100
  ;Check Status Code
101
  lds   temp1, TWSR
102
  andi  temp1, 0x08
103
  sbrs  temp1, 3
104
  rcall oled_error
105
  pop   temp1
106
  ret
107

108
oled_stop:
109
  push  temp1
110
  ldi   temp1, (1 << TWINT)|(1 << TWSTO)|(1 << TWEN)
111
  sts   TWCR, temp1
112
oled_stop_0:
113
  lds   temp1, TWCR
114
  sbrs  temp1, TWINT
115
  rjmp  oled_start_0
116
  pop   temp1
117
  ret
118

119
;If an error occurs, toggle the LED
120
oled_error:
121
  push  temp1
122
  ldi   temp1, 0x01
123
  out   PORTD, temp1
124
  pop   temp1
125
  ret



Bernd_Stein
Angehängte Dateien:
Gast #5694455
Lesenswert?

Bessa Wissa schrieb:
> int 21h schrieb:
>> falls jemand interessiert ist (was ich nicht glaube ^^)
>
> Was ich auch nicht glaube, denn wenn man das Display wirklich
> nutzbringend ansteuern will dann ist noch "ein wenig" mehr an
> Assembler-Arbeit erforderlich.

Ja das ist mir klar, danke.
Aber erst einmal muss ich diese eine Routine zum laufen bekommen.
Der Rest klärt sich dann von selbst.
Mein Ziel wird es später sein, mit diesen Mitteln ein kleines Spiel zu 
entwickeln.
Sei es so geringfügig wie Snake oder ein Klicker Simulator.
Gast #5694475
Lesenswert?

Stefanus F. schrieb:
> Kann es sein, dass du das Display noch nicht initialisiert hast? Ich
> habe dazu noch keinen Programmcode gesehen. Diese Displays brauchen eine
> umfangreiche Initialisierungssequenz.

Ich habe das Display nicht initialisiert, da ich es bis her nicht für 
nötig gehalten habe. Ich wollte mich erstmal auf die Voreinstellungen 
beschränken (Page-Addressing Mode, x=0, y=0).
Aber vielleicht liegt ja wirklich hier der Fehler.
Ich werde mich noch mal von neuem einlesen.

Bessa Wissa schrieb:
> int 21h schrieb:
>> Welchen Zweck hat das ganze den??
>
> Damit er auch was mit labern kann.

XD
(Firma: Anscheinend Corner-Cases ;-)) #5694482
Lesenswert?

int 21h schrieb:
> Bernd S. schrieb:
>> Ich setze mal das von dir verlinkte Listing hier rein und auch als
>> Anhang, damit andere sich daraus einfach Passagen kopieren, edidieren
>> und wieder hier reinsetzen können :
>
> Welchen Zweck hat das ganze den??
>
Naja, du scheinst es ja ( AVR8ASM ) noch lernen zu wollen und Anderen 
machst du es dann etwas einfacher dir ihre Version kund zu tun.


Bernd_Stein
Gast #5694485
Lesenswert?

int 21h schrieb:
> Ich habe das Display nicht initialisiert, da ich es bis her nicht für
> nötig gehalten habe.

Plonk.

> Aber vielleicht liegt ja wirklich hier der Fehler.

Nicht nur vielleicht, sondern 100% sicher. Es sind ungefähr 26 Bytes zur 
Initialisierung nötig. Du darfst hiervon abgucken: 
http://stefanfrings.de/esp8266/WIFI-Kit-8-OLED.zip Die 
Initialisierungssequenz beginnt in oled.cpp Zeile 257.
Gast #5694550
Lesenswert?

Stefanus F. schrieb:
> Nicht nur vielleicht, sondern 100% sicher. Es sind ungefähr 26 Bytes zur
> Initialisierung nötig.

Ich habe mir die von dir mitgegebene Initialisierungs Routine mal 
angeschaut.
Die meisten von denen bzw. fast alle wären bei mir gar nicht nötig, da 
diese bereits beim Reset gesetzt werden.

Laut Datenblatt kann man 0x12 nicht als Parameter auswählen:
> i2c_send(0xDA); // com pins hardware configuration
> i2c_send(0x12);

Wieso versetzt du den uC in den sleep mode:
> i2c_send(0xAE); // display off
Wird übrigens von alleine durch den Reset gesetzt.

Also ist die ganze Initialisierungs Routine sozusagen überflüssig... 
schade :/
Gast #5694567
Lesenswert?

> Die meisten von denen bzw. fast alle wären bei mir gar nicht
> nötig, da diese bereits beim Reset gesetzt werden.

Kann sein. Ich habe es gemäss dem angehängten Datenblatt programmiert 
und dann so gelassen, da es funktioniert. Auf ein paar Bytes mehr oder 
weniger kommt es am Ende nicht an.

> Laut Datenblatt kann man 0x12 nicht als Parameter auswählen:
>> i2c_send(0xDA); // com pins hardware configuration
>> i2c_send(0x12);

In dem angehängten Datenblatt ist der Wert 0x12 vorgegeben und so 
funktioniert das Display auch.

> Wieso versetzt du den uC in den sleep mode

Weil das im Datenblatt so empfohlen wird.

> Also ist die ganze Initialisierungs Routine sozusagen überflüssig...

Das bezweifle ich. Der Chip ist für viele unterschiedliche Displays 
geeignet und hat mehrere Optionen zur Stromversorgung. Er muss dazu 
passend konfiguriert werden.

Ich kann Dir nur empfehlen, mit einem bewährten Code zu beginnen und den 
dann ggf. auf das Nötigste zu reduzieren. Wunder Dich dann aber nicht, 
wenn es beim nächsten Display nicht mehr funktioniert. Die Chinesen 
bauen oft gleichnamige Chips, die sich nicht exakt gleich verhalten.

Wir hatten diese Diskussion auch schon öfters bezüglich HD44780 
kompatible Displays. Fast immer wenn ein Programm nicht funktionierte, 
lag es daran, dass der Programmierer sich nicht an die Vorgaben des 
Datenblattes gehalten hat - in dem Glauben, er könne etwas weglassen 
oder schneller machen. So etwas funktioniert dann oft mit einem Display, 
aber nicht mit jedem vermeintlich baugleichen.
Angehängte Dateien:
Gast #5697642
Lesenswert?

Stefanus F. schrieb:
> Du darfst hiervon abgucken:
> http://stefanfrings.de/esp8266/WIFI-Kit-8-OLED.zip Die
> Initialisierungssequenz beginnt in oled.cpp Zeile 257.

Manche Routinen sind mir in dem Code noch nicht ganz klar.
1. Wieso taucht immer wieder "OLED_I2C_DELAY;" auf?
2. Bei der Funktion "bool OLED::i2c_send(uint8_t byte)" verarbeitest du 
jedes
   Bit aus der Variable byte einzeln. Bei mir erledigt es das 
integrierte TWI
   Module vom uC selbstständig.
   Das macht es sehr schwer, deinen Code mit meinem Assembler zu 
vergleichen,
   da du eine ganz andere Vorgehensweisen nutzt.
3. ich würde mir gerne die beiden Funktionen digitalWrite/Read genauer
   anschauen wollen, wäre das möglich?

Sonst ist alles genauso wie bei mir.
Deine Initialisierungsschritte sind die selben wie bei mir.
#5697662
Lesenswert?

int 21h schrieb:
> Noch eine Frage, hinter meinem OLED steht die Slave Adresse "0x78",
> müsste ich diese bei der Übertragung dann auch schicken oder die hälfte
> vom Wert?

kommt halt auf die Interpretation an, ich arbeite seit der vor Arduino 
Zeit mit 0x78 weil das Bit 0 read oder write meint.

Es ist ja egal ob man 0x78 | 0x01 macht oder (0x3C<<1) | 0x01 macht

Beides ist machbar
Gast #5697979
Lesenswert?

int 21h schrieb:
> 1. Wieso taucht immer wieder "OLED_I2C_DELAY;" auf?

Damit die Kommunikation nicht zu schnell wird. Das Display ist bis 
400kHz Taktrate spezifiziert. Darüber hinaus muss man aber auch gewisse 
Abstände zwischen den Signalwechseln an SCL versus SDL einhalten.

> 2. Bei der Funktion "bool OLED::i2c_send(uint8_t byte)" verarbeitest du
> jedes Bit aus der Variable byte einzeln.

Ja, das nennt man Bit-Banging. Diese Library nutzt nicht das TWI 
Interface, sondern normale I/O Pins.

> Bei mir erledigt es das integrierte TWI

Wenn möglich ist das sicher die bessere Wahl.

> Das macht es sehr schwer, deinen Code mit meinem Assembler zu
> vergleichen, da du eine ganz andere Vorgehensweisen nutzt.

Es sind doch nur drei Funktionen:

OLED::i2c_start() sendet eine START Bedingung
OLED::i2c_stop() sendet eine STOP Bedingung
OLED::i2c_send(uint8_t byte) sendet ein Byte und liefert die Antwort 
(ACK oder NACK) zurück.

und Empfangen wird gar nicht.

Ob du das wie ich per Bitbanging oder durch ein TWI Interface 
austauschst, spielt doch für den Rest des Quelltextes keine Rolle.

> 3. ich würde mir gerne die beiden Funktionen digitalWrite/Read genauer
>    anschauen wollen, wäre das möglich?

Dann lade Dir die Arduino IDE herunter und gucke in die Quelltexte rein. 
Sicher kannst du deren Quelltext auch irgendwo auf Github finden. Doch 
da gibt es nichts spannendes zu sehen. digitalWrite setzt einen 
einzelnen I/O Pin auf High oder Low und digitalRead liest den Zustand 
eines I/O Pins ein.

> Sonst ist alles genauso wie bei mir.

Sicher? Noch vor wenigen tagen schriebst du:
> Ich habe das Display nicht initialisiert, da ich es bis her nicht für
> nötig gehalten habe.
> Also ist die ganze Initialisierungs Routine sozusagen überflüssig...

Die Adresse wird in den oberen 7 Bit übertragen. Das niederwertigste Bit 
signalisiert, ob du lesen oder schreiben willst. Siehe 
https://www.nxp.com/docs/en/user-guide/UM10204.pdf

0x78 ist keine gültige I²C Adresse, weil das nicht in 7 Bit passt. Aber 
wenn du die richtige Adresse 0x3C um ein Bit nach links schiebst, um 
Platz für das R/W Bit zu machen, und dieses R/W Bit auf 0 setzt, dann 
kommt dabei 0x78 heraus. Das ist das Byte, dass du zur Adressierung 
senden musst.

Besorge Dir mal einen Logic Analyzer, damit kannst du deine 
Kommunikation überprüfen. Die Dinger kosten nur ca 10 Euro!
#5697982
Lesenswert?

Stefanus F. schrieb:
> 0x78 ist keine gültige I²C Adresse, weil das nicht in 7 Bit passt. Aber
> wenn du die richtige Adresse 0x3C

was ist schon richtig, es ist eine Frage der Interpretation.

Die ersten LIBs vor Arduino und Datenblätter wiesen 0x78 aus, das passt 
in 7 Bit rechtsshift!
Das read/write Bit gehört als 8tes Bit ja wohl dazu, also falsch ist es 
nicht.
Gast #5697998
Lesenswert?

Joachim B. schrieb:
> Stefanus F. schrieb:
>> 0x78 ist keine gültige I²C Adresse, weil das nicht in 7 Bit passt. Aber
>> wenn du die richtige Adresse 0x3C
>
> was ist schon richtig, es ist eine Frage der Interpretation.
>
> Die ersten LIBs vor Arduino und Datenblätter wiesen 0x78 aus, das passt
> in 7 Bit rechtsshift!
> Das read/write Bit gehört als 8tes Bit ja wohl dazu, also falsch ist es
> nicht.

Oh, 0x78 passt ja doch in 7 Bit. Facepalm.

Jedenfalls sollte man da klar unterscheiden. I²C Adressen sind immer 
7-bit (oder 10-bit) lang. Das achte Bit gehört nicht zur Adresse. Wenn 
das so wäre, dann müsste in der Spezifikation etwa das stehen:

"The device address is reserved for write operation. The following 
address (+1) is reserved for read operation."

Aber so steht das dort nicht. Sondern:

"7-bit slave address" (Absatz 3.1.0)

Absatz 3.1.10 zeigt detailliert, wie die 7-bit Adresse und das R/W Bit 
übertragen werden. Dort ist ganz klar die Adresse von R/W-bit getrennt 
gezeichnet. Und dann gibt es ja noch die 10-bit Adressierung, auch dort 
ist die Adresse klar von anderen Bits getrennt dargestellt.

Wer jetzt irgendwo von einer 8-bit Adresse oder einen 8-bit Wert 
schreibt, der hat es nicht verstanden und stiftet unnötige Verwirrung. 
Ich weiß dass sogar einige Datenblätter es nicht richtig darstellen oder 
zumindest unklar.

Wenn ich eine Funktion write_i2c(addr,buffer,len) oder 
read_i2c(addr,buffer,len) oder so ähnlich anbiete, dann muss klar sein, 
dass addr entweder eine 7-bit oder 10-bit Adresse ist. Irgendwelche 
protokollspezifischen Shift Operationen sind Aufgabe der 
Schnittstellen-Implementierung, nicht des Aufrufers. Willst du etwa bei 
der 10-bit Adressierung das Shiften auch dem Aufrufer überlassen? Das 
wäre Wahnsinn!
#5699062
Lesenswert?

Stefanus F. schrieb:
> Wer jetzt irgendwo von einer 8-bit Adresse oder einen 8-bit Wert
> schreibt, der hat es nicht verstanden

ich frage mich gerade WER was nicht verstanden hat, man muss auf jeden 
FALL 8 Bit senden, das die Adresse hier 7-bittig ist ist doch 
schnurzpiepegal ohne 8tes Bit R/W schickt man NICHTS, aber dreh dich nur 
weiter, DU hast IMMER Recht und alle anderen sind doof.
Gast #5699246
Lesenswert?

Joachim B. schrieb:
> Stefanus F. schrieb:
>> Wer jetzt irgendwo von einer 8-bit Adresse oder einen 8-bit Wert
>> schreibt, der hat es nicht verstanden
>
> ich frage mich gerade WER was nicht verstanden hat, man muss auf jeden
> FALL 8 Bit senden, das die Adresse hier 7-bittig ist ist doch
> schnurzpiepegal ohne 8tes Bit R/W schickt man NICHTS, aber dreh dich nur
> weiter, DU hast IMMER Recht und alle anderen sind doof.

Das kommt dabei heraus, wenn man einzelne Sätze aus dem Zusammenhang 
reißt ohne den Rest zu beachten. Ich habe klar geschrieben, dass

a) die Adresse 7-bit oder 10-bit groß ist, und
b) dass die 7-bit Adresse mit dem R/W bit zusammen als 8-bit gesendet 
wird.

Es gibt bei I²C keine 8-bit Adresse
#5699288
Lesenswert?

Stefanus F. schrieb:
> Es gibt bei I²C keine 8-bit Adresse

klar mit R/W, steht in Datenblätter die ich bis jetzt gelesen hatte mit 
R/W

z.B. beim PCF8574(a), DS3231, DS1307
https://datasheets.maximintegrated.com/en/ds/DS3231.pdf
https://www.sparkfun.com/datasheets/Components/DS1307.pdf

http://www.ti.com/lit/ds/symlink/pcf8574.pdf
#Seite12

lesen 0x79
schreiben 0x78

immer 8-bit
http://homepage.hispeed.ch/peterfleury/doxygen/avr-gcc-libraries/group__pfleury__ic2master.html

Es gab ein Leben vor Arduino
Gast #5699321
Lesenswert?

Stefanus F. schrieb:
> Habe ich ja geschrieben, einige Datenblatter machen das meiner Meinung
> nach falsch. Philips (jetzt NXP) hat die Adressen spezifiziert, meine
> Meinung nach ist da kein Raum für Abweichungen von 7 und 10 bits.

Richtig, für I2C gibt es eine aufgeschriebene Dokumentation. Und dort 
kommen nur 7 Bit oder 10 Bit Adressen vor. Das Datenblatt eines Chips 
ist nur Sekundärliteratur.

Daß in einem Byte 2 verschiedene Informationen übertragen werden (hier 
Adresse und Richtung der folgenden Übertragung) scheint für manche zu 
kompliziert zu sein. Etwas komplexere Protokolle, bei denen noch mehr 
als zwei unabhängige Informationen in ein Byte kodiert werden, würden 
die nie verstehen.

MfG Klaus
Gast #5699344
Lesenswert?

Stefanus F. schrieb:
> Philips (jetzt NXP) hat die Adressen spezifiziert

So ist es und Philips/NXP darf das.
Und sieht man in ein Datenblatt von NXP beispielsweise für den PCF8583 
https://www.nxp.com/documents/data_sheet/PCF8583.pdf, dann steht dort 
auf der 1. Seite:
"Slave addresses: A1h or A3h for reading, A0 or A2 for writing"
Für mich sind das eindeutig 8 Bit Werte ;-)

Man tut sich im übrigen keinen Gefallen, IIC-Adressen mit 7 Bit 
rechtsbündig anzugeben. Denn sobald man sich die Signale auf dem Bus 
ansieht, passt das nicht mehr zusammen.
Gast #5699382
Lesenswert?

Aus der I2C Spec:

> This address is 7 bits long followed by an eighth bit
> which is a data direction bit (R/W)

m.n. schrieb:
> Man tut sich im übrigen keinen Gefallen, IIC-Adressen mit 7 Bit
> rechtsbündig anzugeben. Denn sobald man sich die Signale auf dem Bus
> ansieht, passt das nicht mehr zusammen.

Das stimmt so nicht, mein i2c Dekoder zeigt sie mir als 7-Bit Wert an 
und getrennt davon das R/W Bit. Das krieg ich aber auch im Kopf leicht 
hin.

Nur weil manche nicht in der Lage sind etwas abstrakter zu denken, 
sollte man das eigene Niveau nicht daran anpassen. Es gibt noch 
wesentlich komplexere Kodierungen. Ein Fall ist z.B. die 10 Bit I2C 
Adresse oder noch etwas komplexer Base64.

MfG Klaus
#5699393
Lesenswert?

m.n. schrieb:
[...]
> Man tut sich im übrigen keinen Gefallen, IIC-Adressen mit 7 Bit
> rechtsbündig anzugeben. Denn sobald man sich die Signale auf dem Bus
> ansieht, passt das nicht mehr zusammen.

Einen Tod muß man sterben. Aber ich halte es auch für sinnvoller, die 
I2C-Adressen als 7bit- oder 10bit-Wert anzugeben, also natürlich 
rechtsbündig.

Dann kannst du in der Lib entscheiden wie die Adresse zusammen mit dem 
R/W-Bit auf den Bus gegeben werden muss. Das ist bei 10bit-Adressen dann 
schon nicht mehr so trivial im LA-Trace zu erkennen (wohl dem, der einen 
guten Protokoll-Dekoder hat).

In der Applikation musst du dich dann nicht um die Interna des 
Protokolls (wie wird eine Adresse auf dem Bus dargestellt) kümmern. Im 
Allgemeinen wird eine solche Abstraktion als positiv und erstrebenswert 
angesehen. YMMV.
#5699480
Lesenswert?

Klaus schrieb:
> Das stimmt so nicht, mein i2c Dekoder zeigt sie mir als 7-Bit Wert an
> und getrennt davon das R/W Bit.

und meiner (Software) I2C-Scanner zeigt beides an, so what?

Stefanus F. schrieb:
> .... einige Datenblatter machen das meiner Meinung
> nach falsch.

also sorry wenn ich den Datenblätter mehr vertraue als dir!
Deine Meinung lasse ich dir gerne, die darf ruhig anders sein.

m.n. schrieb:
> Und sieht man in ein Datenblatt von NXP beispielsweise für den PCF8583
> https://www.nxp.com/documents/data_sheet/PCF8583.pdf, dann steht dort
> auf der 1. Seite:
> "Slave addresses: A1h or A3h for reading, A0 or A2 for writing"
> Für mich sind das eindeutig 8 Bit Werte ;-)

ganz meine Meinung!

> Man tut sich im übrigen keinen Gefallen, IIC-Adressen mit 7 Bit
> rechtsbündig anzugeben. Denn sobald man sich die Signale auf dem Bus
> ansieht, passt das nicht mehr zusammen.

eben

im Übrigen ist das egal, man muss sich nur auf eine Regelung einigen, 
das kann je nach Quelle mal schief gehen, ist aber kein wirkliches 
Problem und behebbar, dann shifte ich halt, mal links, mal rechts nach 
Bedarf.
Lohnt nicht darüber zu streiten.......
Gast #5699483
Lesenswert?

Klaus schrieb:
> Das stimmt so nicht, mein i2c Dekoder zeigt sie mir als 7-Bit Wert an
> und getrennt davon das R/W Bit.

Wie Du siehst, taugt das Ding nichts! ;-)

Der IIC-Bus wurde Anfang der 80er von Philips entwickelt. Folglich hat 
man auch die Vorgaben des Urhebers Übernommen, zum Beispiel für den 
PCF8385 die Adressen A0 und A2 als Basisadressen zu verwenden.
Dass die heutige Jugend das nicht mehr weiß, ist nicht mein Problem.
Gast #5699547
Lesenswert?

Klaus schrieb:
> Daß in einem Byte 2 verschiedene Informationen übertragen werden (hier
> Adresse und Richtung der folgenden Übertragung) scheint für manche zu
> kompliziert zu sein.

Genau deswegen würde ich Schnittstellentreiber ("Libraries") immer so 
auslegen, dass jeder Aufrufparameter genau eine Funktion hat. Also eben 
nicht Adresse mit R/W Bit kombinieren. Spätestens wenn man das mal auf 
10-bit erweitert wird das ganz besonders wichtig, denn da steckt das R/W 
bit mitten drin.
Gast #5699550
Lesenswert?

m.n. schrieb:
> Und sieht man in ein Datenblatt von NXP beispielsweise für den PCF8583
> https://www.nxp.com/documents/data_sheet/PCF8583.pdf, dann steht dort
> auf der 1. Seite:
> "Slave addresses: A1h or A3h for reading, A0 or A2 for writing"
> Für mich sind das eindeutig 8 Bit Werte ;-)

Tolle Wurst, die legen es wohl drauf an, ihre Kunden zu verwirren.

> Man tut sich im übrigen keinen Gefallen, IIC-Adressen mit 7 Bit
> rechtsbündig anzugeben. Denn sobald man sich die Signale auf dem Bus
> ansieht, passt das nicht mehr zusammen.

Die beiden mir bekannten Logic Analyzer Programme können die Adresse 
wahlweise in beiden Formaten anzeigen.
Gast #5701258
Lesenswert?

Ich wollte heute mal wieder an dem Programm für die TWI Kommunikation 
weiterarbeiten.
Als nach vielen Versuchen immer noch nichts am Display zu sehen war, 
beschloss ich spaßeshalber noch einmal das OLED Arduino Sketch von 
Adafruit drauf zu spielen.
Auf dem Display war allerdings nichts zu sehen.
Vor wenigen Tagen lief das Programm noch und heute nicht mehr.
Die Schaltung ist die selbe geblieben, unverändert!
Dann habe ich test weise ein Programm zum auslesen der TWI Adresse 
geladen, dass auch funktioniert hat (0x3C kam raus).
Ist das GDDRAM vom OLED defekt?
Geht das wirklich so leicht?
Gast #5702252
Lesenswert?

Das habe mir jetzt alle Initialisierungs Commands herausgesucht, die 
unbedingt nötig sind um etwas darzustellen.
Dabei stieß ich auf den Command "Charge Pump Regulator", der anscheinend 
unbedingt aktiviert werden muss.
(Der Grund weshalb ich diesen Befehl erst jetzt im Datenblatt entdeckt 
habe, ist weil der ganz unten im Datenblatt steht und auch nicht in der 
Command Table eingetragen ist!)
Kann mir jemand bitte erklären, was dieser genau macht, da ich nicht 
viel von Elektronik verstehe?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren