Forum: Mikrocontroller und Digitale Elektronik I2C Verbindung zw. PIC32 und PIC18. Slave zu Master ?


von Stephan .. (Firma: keine) (malibow)


Lesenswert?

Hello,

Ich habe ein Problem mit der I2C Kommunikation zw. 2 PICs

genauer:
zw. PIC32MX360F512L  (MASTER)
und PIC18LF4550 (SLAVE)

zwar klappt es nicht Daten vom Slave zum Master zu schicken! andersrum 
kein Problem.

Problem beim senden vom Slave zum Master.:
Adresse wird erfolgreich gesendet! (Oszi überprüft) --> von ack gefolgt 
dann läuft aber irgendwas schief.

bisher sieht es so aus, dass ich nur das 2. Byte übertragen bekomme (das 
"I" von meinem string wird gesendet), was ich am Oszi auch sehe. das 
erste Byte wird irgendwie verschluckt, kann mir aber nicht erklären 
warum. Beim debuggen fällt auf, dass die putsI2C Routine in einer 
schleife hängen bleibt, wo sie auf das 9. Bit (ack) wartet, per oszi 
sehe ich auch kein ACK



Hat schonmal jemand die Kommunikation zw. 2 PICs zum laufen gebracht?

Grüße

Stephan

ich hab versucht die Kommunikation mit den demoprogrammen von Microchip 
aufzubauen
hier mein Quellcode:

Hier mein PIC18 Code:
1
unsigned char I2C_Send[21] = "MICROCHIP:I2C_SLAVE" ;
2
//********************* Read the address sent by master from buffer **************
3
      while(DataRdyI2C()==0);            //WAIT UNTILL THE DATA IS TRANSMITTED FROM master
4
      temp = ReadI2C();
5
//********************* Slave transmission ************************************       
6
  if(SSPSTAT & 0x04)                //check if master is ready for reception   
7
  while(putsI2C(I2C_Send));            // send the data to master
8
//-------------TERMINATE COMMUNICATION FROM MASTER SIDE---------------
9
  CloseI2C();                            //close I2C module
10
  
11
  while(1);


Hier mein (PIC32) Code:
1
SlaveAddress = r_SLAVEADRESSE;    
2
  StartI2C1();    //Send the Start Bit
3
  IdleI2C1();        //Wait to complete    
4
  MasterWriteI2C1( SlaveAddress );  //write SLAVE Adress and read Command
5
  IdleI2C1();        //Wait to complete
6
  while( I2C1STATbits.ACKSTAT );
7
8
  i2cbyte = MasterReadI2C1();
9
  IdleI2C1();        //Wait to complete
10
11
  StopI2C1();    //Send the Stop condition
12
  IdleI2C1();    //Wait to complete
13
C-Code



Kann mir irgendjemand helfen? oder hat nen Tipp?
Grüße

von Wilhelm F. (Gast)


Lesenswert?

Es ist schon ne Weile her, daß ich I2C-Software, voll interruptgesteuert 
natürlich, für einen LPC2000 von NXP schrieb. Daher stecke ich nicht 
mehr ganz so tief in der Materie drin. Bitte also etwas Nachsicht, falls 
ich mit einem Hinweis total daneben liegen sollte.

Ist es nicht so, daß ein Slave von sich aus nichts zum Master senden 
können soll? Deswegen heißt das eine Ding Master, und das andere 
Slave. Bei I2C gibt es jedoch Multi-Master-Konfigurationen.

Andernfalls müßte der Slave über eine separate Meldeleitung (Handshake 
o.ä.) dem Master-Controller mitteilen, daß er was hat, was abgeholt 
werden soll.

Gibt es denn von Mikrochip keine Application Notes, oder Beispiele? Für 
den LPC2000 gibt es sowas bei NXP und bei Keil. Bei NXP sollte es auch 
alle Spezifikationen zu I2C geben, da das früher Philips war.

von Stephan .. (Firma: keine) (malibow)


Lesenswert?

Hallo Wilhelm,

du hast das ganz gut beschrieben... und ich benutze auch eine handshake 
signalleitung

bisher soll das ganze noch ohne interrupt funktionieren... weil ich 
einfach mal die Kommunikation testen wollte.

Kommunikation sieht so aus:

Slave sendet dem Master per Handshake dass er daten hat.

Master sendet Adresse + Read bit.

Slave gibt ack zurück und übernimmt die leitung

nur daten senden funktioniert nicht..


den Quellcode den ich bisher nutze ist aus einer Demoapplikation von 
Microchip zusammengeflickt. leider funktionierts eben nicht richtig...
noch jemand ne idee?

von stepp64 (Gast)


Lesenswert?

Das haut aber so nicht hin, da ein SLAVE niemals das Clocksignal 
erzeugt. Das macht immer der Master. Du kannst also nicht Daten vom 
Slave zum Master senden, sondern du musst die Daten vom Master aus 
abholen lassen. Also:

- Master sendet Adresse mit aktivem Readbit
- Slave stellt die Daten intern im Sendepuffer bereit
- Master holt die Daten ab

Eigentlich müsste im Slave-PIC ein Interupt erzeugt werden, wenn der 
Sendepuffer durch die Hardware ausgelesen wurde, damit du ihn neu 
befüllen kannst.

Ich selbst hab das leider noch nicht so programmiert. Bei meinem 
derzeitigen Projekt plane ich aber ebenfalls 2 PICs über I2C zu 
verbinden. Hab mich also schon etwas eingelesen und denke, dass es so 
funktionieren müsste.

Gruß
Sven

von Stephan .. (Firma: keine) (malibow)


Lesenswert?

Hallo Sven,

ganz genau so ist es auch geplant... und eigentlich auch umgesetzt. 
(siehe Quellcode)
Master sendet Adresse+ Readbit
dann wartet er bis alles übertagen wurde und auf das ACK
"  IdleI2C1();        //Wait to complete
  while( I2C1STATbits.ACKSTAT );"

dann liest der Master die Datenleitung mit
"  i2cbyte = MasterReadI2C1();" und wartet ebenfalls wieder

"  IdleI2C1();"

hab des ganze auch schon per Oszi angeguckt clockleitung ist 
vorhanden....

noch wer nen vorschlag?

stepp64 schrieb:
> Eigentlich müsste im Slave-PIC ein Interupt erzeugt werden, wenn der
> Sendepuffer durch die Hardware ausgelesen wurde, damit du ihn neu
> befüllen kannst.

zwecks diesem kann ich dazu sagen das erledigt die putsI2C Routine 
selbst.

von Eschi (Gast)


Lesenswert?

Hallo,

versuch doch mal zuerst einmal den Master mit einem I2C-Baustein zum 
laufen zu bringen, z.B. ein EEPROM 24C02. Natürlich schlecht zu machen, 
falls man keines zur Hand hat.

Gruss Martin

von Stephan .. (Firma: keine) (malibow)


Lesenswert?

danke ist mein nächster einsatz werde mir des pcf 8574 irgendwie 
besorgen und somit probieren...

falls in der zwischenzeit noch jemand einfälle hat immer gerne her damit 
;-)
thx for helping

von Wilhelm F. (Gast)


Lesenswert?

@Stephan:

Hab noch mal etwas nach Dokumenten gesucht, die ich für eine frühere 
I2C-Entwicklung selbst benötigte. Die Inhalte sind gar nicht so einfach 
zu finden, weil präzise Beschreibungen über die I2C-States bei 
Philips/NXP in den Datenblättern von Bauteilen versteckt sind, und nicht 
in allgemeinen Dokumenten.

I2C-Interface PCA9564. Dort sind alle I2C-States beschrieben, und zu 
jedem Mode ein Diagramm, woran man sich orientieren kann bzw. muß:

http://www.nxp.com/#/pip/pip=[pip=PCA9564_4]|pp=[t=pip,i=PCA9564_4]|
oder direkt dort:
http://www.nxp.com/documents/data_sheet/PCA9564.pdf

Dann gibt es die AN10148 zum PCA9564 mit Flußdiagrammen zu jedem 
I2C-Mode:

http://www.nxp.com/search/?query=AN10148
oder direkt dort:
http://www.nxp.com/acrobat_download/applicationnotes/AN10148.pdf

Diese Dinge hatten mir schon mal sehr geholfen.

Die Diagramme/Flußdiagramme gelten für I2C generell, nicht nur für 
diesen Baustein.

Die I2C-Controller verschiedener Hersteller werden sich nicht groß 
unterscheiden, allenfalls ein wenig in den Registerbezeichnungen.

von Stephan .. (Firma: keine) (malibow)


Lesenswert?

Hallo,

danke für eure hilfe bisher....

habe nun den Vorschlag von Eschi verfolgt.
habe mir nen I2C Portexpander(PCF8574) an den I2C  drangehängt und den 
ausgelesen bzw beschrieben (erfolgreich). somit liegt der Fehler im 
PIC18 Code...
hat den schon jemand durchgelesen und vielleicht was entdeckt?

THX

von Stephan .. (Firma: keine) (malibow)


Lesenswert?

sodele
habs hinbekommen,

Problem war in der PIC18 Routine die den Inputbuffer nicht schnell genug 
gelöscht hat. --> gelöst mit delay von 100 nops

der fehlende 9 Takt (ACK) musst aktiv vom master aus mitgesendet 
werden....

falls es noch jemand interessiert... --> melden bin grad noch im 
zeitstress... aber kann das ganze gerne ncoh ausführlicher 
beantworten...

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.