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.
@ 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
@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" :-))
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
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
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
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.
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
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 :-))
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 |
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.