Hallo, Guten Morgen.
Ich habe ein Problem und bin fast am Verzweifeln. Also frage ich euch mal.
Mein Projekt:
mit PIC 16F886
Programmiersprache: pmp (IDE mit Turbo Pascal)...bitte nicht lachen, aber ich komme damit am besten zurecht
ein I2C Bus mit Expandern PCF8574 (8 I/O pins) und PCF8575 (2x8 Pins)
das I/O mit dem PCF8574 funktioniert, keine Probleme, das eine Byte wird gelesen
beim PCF7575 hab ich Probleme, ich kann nur 1 Byte Input lesen, das zweite Byte wird nicht richtig gelesen.
Also hab ich mal den Oszi angeworfen und sehe dass beim Lesen etwas mit den ACK Bits nicht stimmt.
Mein Wissensstand ist dieser:
bei einer Write Sequenz sendet der Empänger, also der Expander, jeweils nach 8 empfangenen Bits das ACK Bit (zu sehen als 9. Bit)
bei einer Read Sequenz sendet der Slave nach Empfang des Adress Bytes sein ACK bit und sendet die aktuellen Daten des ersten Ports an den Master, der Master quittiert den Empfang mit seinem ACK Bit,
nach dem ACK des ersten Datenbytes sendet der Slave die aktuellen Daten des zweiten Ports. Wenn das ACK des Masters aber fehlt (wie in meinem Problemfall, siehe angehängte Bilder), sendet der Slave keine aktuellen Daten sondern lauter 1'.
Mein Problem ist also vermutlich, dass der Master bei einem Read mit 2 Datenbytes kein ACK sendet. Ja, das ACK fehlt schon bei dem ersten Byte. Da das ACK aber erst nach dem Empfang der Daten gesetzt wird, wird das erste Datenbyte noch korrekt empfangen, aber nicht mit einem ACK vom Master bestätigt.
Nun meine Frage, weiß jemand wie ich den PIC Master dazu bringe sein ACK zu senden bei einer Read Sequenz?
Anhang: 2 Screenshots
Bild 1: das Adressbyte wird vom Slave richtg ACKnowledged (=das 0 Bit als 9. Bit nach den 8 Adressbits, in dieser Sequenz schicke ich nur 1-Daten um die Pins auf Input zu schalten --- das funktioniert also
Bild 2: in der Read Sequenz bleibt das ACK vom Master High --> Problem!
bin's noch mal.
Ich hab mir die Sache bei dem PCF8574 mit dem Oszi auch mal genauer angeschaut, er sendet ja nur ein Datenbyte. Auch bei dem fehlt wie ich richtig vermutete, das positive ACK vom Master (= value auf der SDA Leitung). Das war mir bisher nicht aufgefallen, weil das Byte die aktuellen Inputs richtig enthielt. Aber es fehlt das positive ACK des Masters.
Hoppla, und ich sehe es fehlt der 9. Clockimpuls nach dem Datenbyte.
Oder wird bei nur einem Datenbyte gar kein ACK gesetzt vom Master und er clockt gar nicht mehr den 9. Impuls?
Nun sehe ich auch dass bei den 2-Bytigen PCF8575 das erste Datenbyte nur 6 Clockimpulse hat, also kein ACK, das 2. Byte dann aber 9 Clocks aber der ACK ist nicht gesetzt.
ja, wenn der Master sendet kommt das ACK vom Empfänger.
Bei mir ist das Problem, wenn der Master Daten empfängt, sendet er kein ACK zum Sender, dem Expander. Beim Ersten Byte clockt der Master nur 8mal, beim zweiten Byte 9 mal, aber sein ACK fehlt.
im Datenblatt des PPCF8575 steht aber, dass bei einem Read der Slave das
ACK generiert....s. Copy
Das ist doch genau das, was Clemens schrieb:
Um die Übertragung seitens des Maters zu beenden, schickt dieser ein NACK.
Alle anderen, fortlaufenden Lesevorgänge werden mit einem ACK quittiert.
Der Fehler liegt demnach an der I²C-Leseroutine des Masters
==> Quewllcode zeigen!
Ungünstig...
Das sollte meiner Meinung nach erst am Ende des kompletten Lesevorgangs passieren.
Dir fehlt da eine Schleife über die Anzahl der zu lesenden Bytes.
Danach kann dann das Stop-Signal gesendet werden.
Ungünstig...
Das sollte meiner Meinung nach erst am Ende des kompletten Lesevorgangs
passieren.
Dir fehlt da eine Schleife über die Anzahl der zu lesenden Bytes.
Danach kann dann das Stop-Signal gesendet werden.
mache ich doch:
Stop ist einmal am Ende und
innen sind 2 Reads.
// im Code sind Kommentare
1
procedure PCF2_Read ();
2
begin
3
//Adresse des zu lesenden PCF Expanders
4
OPCODE := PCF_ADDR shl 1;
5
//I2C Start
6
I2C_Master_Start;
7
//Lesen: zunächst alles auf HIGH schalten
8
I2C_Master_Write(OPCODE); //Opcode mit R/W = 0 = W
9
I2C_Master_Write(0xFF); //Outputs HIGH damit die Pins INPUT werden
10
I2C_Master_Write(0xFF); //Outputs HIGH damit die Pins INPUT werden
11
I2C_Master_RepeatedStart; // restart weil jetzt wieder eine Adresse mit W/R kommt
12
I2C_Master_Write(OPCODE or 0x01); //Opcode mit R/W = 1 = R
13
//Daten empfangen bei pcf8475 2x, bei pcf8474 nur 1x
AN735 (Using the PICmicro MSSP Module for I2C Communications) sagt:
The Acknowledge bit event consists of first setting the
Acknowledge state, ACKDT (SSPCON2<5>) and then
asserting high the event control bit ACKEN (SSPCON2<4>).
Mich wundert nur, dass SDA nach dem ACK Clock bis zum nächsten
Byte-Lesen LOW bleibt. Ist das normal?
Ja. Der Zustand von SDA wird nur während der steigenden Flanke von SCL gelesen; was mit SDA passiert, während SCL Low ist, ist egal. (Und da um das ACK-Bit herum zwischen Master und Slave umgeschaltet wird, kann es durchaus passieren, dass SDA hin und her wackelt.)
danke, Clemens, dann kann alles nun so lassen wie es ist.
Was ich mich bei diesem ACK Gedöns allerdings frage, warum ist das ACK nicht schom standardmäßig eingeschaltet, wenn der Master liest. Ob Lesen oder Schreiben ist, sieht er doch an dem W/R Bit in dem Adressbyte, das er als erstes zum Slave geschickt hat.
Der Sinn des NACK am Ende leuchtet mir noch nicht ein.
Ich hab jetzt mal dieses getestet:
Am Ende wird ein ACK geschickt: ----> gelesene Daten sind OK
Am Ende wird ein NACK geschickt: ---> gelesene Daten sind OK
Am Ende weder ein ACK noch ein NACK:--> alle Daten OK
Also wozu soll der Impuls dienen?
Ich sehe es so: der ACK dient dazu, dass der Slave sich zum Senden des nächsten Bytes vorbereiten kann/soll, nach dem letzten Byte wird nichts mehr abgerufen, also wäre der ACK Impuls auch nicht nötig (es hat da keinen Sinn mehr).
Der Master muß als letztes ein NACK senden, damit der Slave weiß, daß er nun SDA loslassen muß. Ansonsten können weitere Daten das Stop des Masters verhindern.
Der Master muß als letztes ein NACK senden, damit der Slave weiß, daß er
nun SDA loslassen muß. Ansonsten können weitere Daten das Stop des
Masters verhindern.
scheint aber nicht so zu sein. Am Ende setzt meine Master Stop Procedure das Register PEN=1. Laut Datenblatt bewirkt das, dass SDA und SCL High gehen.
Das Loslassen der SDA durch den Slave wird also initiiert durch die Stop Condition und nicht durch ein NACK.
Datenblatt des PIC 16F886:
PEN: Stop Condition Enable bit (in I2C Master mode only)
SCK Release Control:
1 = Initiate Stop condition on SDA and SCL pins. Automatically cleared by hardware.
0 = Stop condition Idle
Oder sehe ich da noch was falsch?
In meinem angehängten Bild werden SDA und SCL released nach High auch ohne ein NACK, sondern vermutlich durch das PEN=1.
Es ist wohl der Zustand dass die SCL permanent high geht, das den Slave veranlasst auch die SDA loszulassen.
Na dann setze mal den PCF8574 auf 0x00 und versuche ihn zurück zu lesen. Der Master kann dann kein Stop mehr senden.
Es sei denn, der PIC hat auch ein I2C-Recovery implementiert, wie die alten Philips 80C51:
"If the SDA line is obstructed by another device on the bus (e.g., a slave device out of bit synchronization), the problem can be solved by transmitting additional clock pulses on the SCL line (see Figure 14). The SIO1 hardware transmits additional clock pulses when the STA flag is set, but no START condition can be generated because the SDA line is pulled LOW while the I2C bus is considered free. The SIO1 hardware attempts to generate a START condition after every two additional clock pulses on the SCL line. When the SDA line is eventually released, a normal START condition is transmitted, state 08H is entered, and the serial transfer continues."
Ich sehe gerade, Dein PIC verletzt die I2C-Spezifikation. Du sendest zum Schluß nur 8 Takte, d.h. der ACK-Slot fehlt. Damit erfolgt das Stop fälschlich anstelle des ACK.
Peter, ich hab mal deinen Fall getestet PCF8575 alle 16 Pins auf Output 0 und dann 2 Bytes lesen mit ACK oder NACK oder garnix nach dem 2. Byteread:
Bei NACK und garnix wird die Sequenz mit der Stop Condition sauber beendet. Aber wie du schon vermutest, der Fall mit dem fehlenden ACK/NACK Puls ist nicht Spec-konform.
Bei ACK am Ende hängt die Sequenz, naja der Slave wartet auf die Clocks....also erwartetes Verhalten.
Aber wie getestet, NACK oder garnix ist kein Unterschied.
Ich habe allerdings zZ nur einen einzigen Slave am Bus, kann also noch nicht die komplette Story in ihren Folen testen.
Sicherlich kann man über viele andere Fälle diskutieren.
Ich hab nun das NACK nach dem letzten Read eingebaut, und gut ist's.