Forum: Mikrocontroller und Digitale Elektronik PIC: HW I2C & SW SPI gemeinsam nutzen


von Markus J. (doc_database)


Lesenswert?

Hallo Forumgemeinde,

ich sitze gerade (noch) an dem Problem, das ich entweder I2C (Hardware) 
oder SPI (Software) nutzen kann.
Ich möchte beides nutzen.
Ich benutze den C18 Compiler mit den Microchip-Bibliotheken I2C.h und 
sw_spi.h, also Sowftware SPI.

Für I2C benutze ich RB0 & RB1
Für SPI benutze ich RD0(Dout) RD1(Sckl) RD4 (CS)

Für mich ist nicht erkennbar, wo sich die beiden Protokolle Hardware 
teilen, sodass nur eines von beiden funktioniert.

Hatte sowas schon mal jemand, und wie kann man beides implementiern.

Quellcode poste ich später.

von Falk B. (falk)


Lesenswert?

@ Markus J. (doc_database)

>ich sitze gerade (noch) an dem Problem, das ich entweder I2C (Hardware)
>oder SPI (Software) nutzen kann.
>Ich möchte beides nutzen.

>Für mich ist nicht erkennbar, wo sich die beiden Protokolle Hardware
>teilen, sodass nur eines von beiden funktioniert.

Wenn deine SPI auf reiner Software basiert benutzt sie ausser den IOs 
keine weitere Hardware. Damit sollte ein Parallelbetrieb problemlos 
möglich sein.

MfG
Falk

von Markus J. (doc_database)


Lesenswert?

@Falk Brunner
> Wenn deine SPI auf reiner Software basiert benutzt sie ausser den IOs
> keine weitere Hardware. Damit sollte ein Parallelbetrieb problemlos
> möglich sein.

Ja, reines SW SPI und HW I2C
Ich werde mal abwarten, ob sich vielleicht jemand erbarmt, und mir ein 
Codeschnipsel eines funktionierenden Projektes einstellt.

Ich werde gleich mal alles übrige, was nicht notwendig ist, 
auskommentieren und nochmal auf Fehlersuche gehen.

Wenn du sagst, das es geht, dann deckt sich das auchmit meiner Meinung.
Seltsam nur, das der µC darüber anders "denkt" :-))

von Peter D. (peda)


Lesenswert?

Markus J. wrote:

> Seltsam nur, das der µC darüber anders "denkt" :-))

Der µC ist der letzte, der anders denkt.

Ich vermute mal, Du benutzt irgendnen Wizard, der Dir Code generiert und 
in dem wurde nur nicht vorgesehen, beides zu benutzen.

Das ist immer so, wenn man nicht selber programmiert, sondern nen 
Wizzard benutzt. Es können nur vorhergesehene Dinge implementiert 
werden.


Wenn Du eins von beiden in Software machst, ist in jedem Fall auch 
beides gleichzeitig nutzbar.

Wenn Du beides in Hardware machst, kommt es nur dann zu Konflikten, wenn 
beides die gleichen Pins benutzen will.
Aber dazu gibt Dir das Datenblatt Deines uns unbekannten PIC Auskunft.


Peter

von Markus J. (doc_database)


Lesenswert?

Hallo Peter!

Peter Dannegger wrote:
> Ich vermute mal, Du benutzt irgendnen Wizard, der Dir Code generiert und
> in dem wurde nur nicht vorgesehen, beides zu benutzen.
>
Wizzard?
Du meinst sowas wie Maestro? Halte ich nicht viel von.
Als Wizzard bezeichne ich aber nicht die Programmierung eines 18F4550 
mit dem C18 in C. Einverstanden?
Demnach alles "per Hand" (wenn man Assembler mal ausklammert)

> Wenn Du beides in Hardware machst, kommt es nur dann zu Konflikten, wenn
> beides die gleichen Pins benutzen will.
> Aber dazu gibt Dir das Datenblatt Deines uns unbekannten PIC Auskunft.

Sorry, war schon spät.
Daran sollte man denken.

Gruß Markus

Edit:
Ich benutze die mit dem C18 ausgelieferten Bibliotheken, also ich binde 
diese in meinen Quellcode ganz herkömmlich über die Header-File ein.
Ich benutze die i2c.h und die sw_spi.h aus dem Unterferzeichnis des 
MCC18.
Vielleicht kommst du von daher auf den Wizzard

von Peter D. (peda)


Lesenswert?

Markus J. wrote:

> Wizzard?

Ein Wizzard generiert von sich aus Code, wenn Du irgendwelche 
Schlüsselwörter benutzt, die nicht im C-Standard definiert sind.
Manche Wizzards haben auch ne Klickibunti-Oberfläche.


> Als Wizzard bezeichne ich aber nicht die Programmierung eines 18F4550
> mit dem C18 in C. Einverstanden?

Nun, der C-Compiler wird Dir bestimmt nicht gesagt haben, daß sich I2C 
und SPI nicht vertragen.
Ein Compiler übersetzt einfach stur, was Du hinschreibst, mehr nicht.
Er meckert nur, wenn Du Syntaxfehler machst.


> Demnach alles "per Hand" (wenn man Assembler mal ausklammert)

Ja, richtigen C-Code eben (XYZ = 0x1234;).

Man muß allerdings dazu das Datenblatt lesen, welche Werte man in welche 
IO-Register schreiben muß, damit die gewünschte Funktion ausgeführt 
wird.


Peter

von Markus J. (doc_database)


Lesenswert?

Ich weiß aus den Artikeln, das du ein Verfechter von Assembler bist.
Macht auch Sinn, aber für mich ist das nix.

Ich bin die einzelnen Module aus der Biliothek durchgegangen und habe 
nichts gefunden.
Teilweise habe ich sie an meine Hardware anpassen müßen.

Gerade jetzt schreibe ich das ganze noch mal in abgespeckter Form, so, 
dass nur I2C und SPI benutzt wird.
Wenn es klappt, setzte ich es hier rein, damit es andere auch finden.

von Peter D. (peda)


Lesenswert?

Markus J. wrote:
> Ich weiß aus den Artikeln, das du ein Verfechter von Assembler bist.
> Macht auch Sinn, aber für mich ist das nix.

Das ist mir aber neu.

Ich habe zwar mal mit Assembler angefangen, aber das ist schon viele 
Jahre her.
Und ich habe mal nen AVR-Bootloader in Assembler geschrieben, weil ein 
Bootloader nur sehr klein ist (<256 Worte) und in Assembler es viel 
leichter ist, ihn an die verschiedenen AVRs anzupassen.

Aber in der Regel schreibe ich alles in C (AVR-GCC oder Keil C51).


> Ich bin die einzelnen Module aus der Biliothek durchgegangen und habe
> nichts gefunden.

Beschreib doch erstmal Dein Problem.

Kriegst Du ne Fehlermeldung vom Compiler, dannn mußt Du die im exakten 
Wortlaut posten und die Zeile(n), auf die sie sich bezieht.
Ansonsten ist alles nur Glaskugelleserei.

Oder kompiliert es, aber es funktioniert in der Hardware nicht.
Dann mußt Du das Fehlerbild so exakt wie möglich beschreiben (was soll 
wann passieren, was weicht wie ab).


> Gerade jetzt schreibe ich das ganze noch mal in abgespeckter Form

Ja, ein Sourcecode ist immer am besten.


Peter

von Markus J. (doc_database)


Lesenswert?

Schon dabei.
Leider kann ich derzeit pauschal den Fehler nur damit Beschreiben, das 
ich sagen kann, das entweder SPI funktioniert (Display wird beschrieben, 
aber dafür wird die Uhrzeit aus dem RTC (I2C) nicht gelesen oder die 
Uhrzeit wird gelesen, aber das Disply bleibt leer.

Sorry, mahr habe ich derzeit nicht auf der Hand.
Daher wäre es klasse, wenn du und die Forumgemeinde später auf den 
fertigen Quellcode gucken würdest.
Entweder er funktioniert dann oder nicht :-))

von Markus J. (doc_database)


Angehängte Dateien:

Lesenswert?

So, da bin ich wieder.
Ich habe alles rausgeschmissen, was überflüssig ist.
µC: PIC 18F4550
RTC: DS1307 uber HW I2C an RB0 und Rb1
Display: SED1530 über SPI angeschlossen

Nachfolgend im Code gekennzeichnet, wo es hakt:
1
void DS_Read(char* data, char length, char wordaddr)
2
{
3
// Laut Datenblatt des DS1307 implementiert. Schreiben des Pointers auf das Register und anschließendes Lesen ab der Pointeraddress
4
  int i;
5
  unsigned char t;
6
  OpenI2C(MASTER, SLEW_ON);
7
  SSPADD = 9; // 20Mhz Quarz auf 5 Mhz heruntergeteilt
8
  IdleI2C();
9
  StartI2C();
10
  while(SSPCON2bits.SEN==1);
11
  IdleI2C();
12
  WriteI2C(0xD0); //DS Schreiben
13
  IdleI2C();
14
  WriteI2C(wordaddr); // Pointer setzten
15
  IdleI2C();
16
  StartI2C(); // hier habe ich voher RestartI2C() stehen gehabt, aber auch mal StartI2C() ausprobiert
17
  IdleI2C();
18
  WriteI2C(0xD1); // DS Lesen - Modus
19
  IdleI2C();
20
  // An nachfolgender Stelle geht es nicht weiter.
21
        // Dazu siehe auch Assembler Code
22
  t = ReadI2C(); // t zu Testzwecken  - Auslesen
23
  *data = t; //Schreiben des Werts in den Zeiger zur Rückgabe
24
  for(i=1; i<length; i++)
25
  {
26
    AckI2C();
27
    data++;
28
    t = ReadI2C(); //Weitere Werte auslesen
29
    *data = t;  
30
  }
31
  NotAckI2C(); // NAck
32
  StopI2C(); 
33
  IdleI2C();
34
  CloseI2C(); // Hardware schließen / freigeben
35
  
36
}
1
---  C:\MCC18\src\pmc_common\i2c\i2c_read.c  -----------------------------------------------------
2
  1760    86C5     BSF 0xfc5, 0x3, ACCESS
3
  1762    A0C7     BTFSS 0xfc7, 0, ACCESS
4
  1764    D7FE     BRA 0x1762
5
  1766    50C9     MOVF 0xfc9, W, ACCESS
6
  1768    0012     RETURN 0

von Markus J. (doc_database)


Angehängte Dateien:

Lesenswert?

Für C18 in MPLAB

von Peter D. (peda)


Lesenswert?

Ich kenne den PIC und die I2C-Lib nicht.

Aber wozu ist IdleI2C gut?

Und wo testest Du, ob ein WriteI2C erfolgreich war, d.h. ein ACK 
empfangen wurde?

Und wo sendest Du das ACK für jedes ReadI2C bzw. das NACK für das letzte 
ReadI2C?


Wenn beide Bibliotheken unabhängig voneinander funktionieren, kann es 
sein, daß sie unsauber programmiert sind, d.h. sich gegenseitig die 
Parameter verstellen.
Da hilft dann wohl nur selber schreiben oder den Code analysieren.
Liegen denn die Bibliotheken als C-Source vor?


Aus eigener Erfahrung kann ich sagen, daß es äußerst schwer ist, 
Bibliotheken ohne Nebenwirkungen zu schreiben.
Deshalb binde ich immer Bibliotheken als Quelltext ein.
Dann hat der Nachnutzer zumindest eine Chance, eventuelle Fehler zu 
korrigieren.


Peter

von Markus J. (doc_database)


Lesenswert?

Aber wozu ist IdleI2C gut?

Die Funktion prüft, ob der Bus wieder frei ist.

Ich habe allerdings mit die Hardware - I2C nicht ans laufen bekommen.
So wie ich gelesen habe, ist das Modeul MSSP dieses Chips auch sehr 
buggy.
Ich habe dann die PINs für eine Software - Lösung benutzt und mußte 
diese Bibliothek auch noch anpassen.

z.B. gab es dort eine Funktion SWPutsI2C(char*), die einen String 
übermittelt.
Leider bracht diese die Kommunitkation ab, wenn eine "0" übertragen 
werden mußte. Klar, Endekennung.

Es läuft und ich werde alles noch kommentieren, bevor ich es hier 
reinstelle

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.