/*
Hallo,
ich schicke Daten an zwei hintereinander geschaltete 74HC595 8-Bit
Schieberegister an deren Ausgänge LEDs hängen. Nix besonderes
eigentlich. Die Schaltung funktioniert, der Code ebenfalls - allerdings
immer nur ein Mal.
1. Schieben
rein: 0x0001
raus: 0x0001
ok
2. Schieben
rein: 0x0002
raus: 0x0200
Versatz, nicht ok
3. Schieben
rein: 0x0004
raus: 0x0004
jetzt stimmt das Muster wieder,
allerdings ist der Vorgang nicht reproduzierbar, denn:
Zweiter Versuch:
1. Schieben
rein: 0x0001
raus: 0x0001
ok
2. Schieben
rein: 0x0000
raus: 0x0000
scheinbar ok
3. Schieben
rein: 0x0004
raus: 0x0000
wieder kaputt
Es kommt mir so vor als ob die beiden parallelen Eingänge 'clock storage
register' der beiden Schieberegister, welches die Daten auf die
Ausgabelatches schalten, Mucken machen. Ich hatte vorher schon
Schwierigkeiten, "sofort" nach der Schiebefunktion die Daten in die
Ausgaberegister zu schalten, der PIC war für diesen Schreibvorgang zu
schnell. Nun ja.
Wenn ich die drei auskommentierten Zeilen wieder in den Code nehme, dann
funktioniert es. Allerdings habe ich dann immer ein kurzes Zucken auf
den LEDs. Stattdessen muße es aber doch möglich sein, beide '595
gleichzeitig zu schalten, oder? Ich könnte zwar mit einer weiteren
Port-Leitung alle Register im '595 löschen aber das ist ja nicht der
Sinn der Sache.
Compiler: Hitech + PIC 18F4550
Anbei der Code, bitte mal über die Funktion void showInt595 (unsigned
uPattern) drüber kucken, ob da vielleicht was fehlt.
Besten Dank für die Mithilfe
*/
3,3V Ausgänge und 5V 74HC Eingänge passen nicht sehr gut zusammen. 74HCT
oder die im Schaltplan aufgeführten 74LS wären passender.
Teste die 595er mal mit 3,3V. Oder den PIC mit jenen 5V, die er laut
Datasheet offiziell benötigt.
Mal einen anderen SPI-Modus getestet?
Die 3,3V hatte ich gleich zu Beginn auf 5V angehoben.
Hab alle vier Modi getestet, auch aufm Oszi. Die anderen Modi, (Idle auf
high, Verschiebung um ein halbes Bit von data und clock) bringen nur
Fehler.
Ich schiebe immer 16 bit. Denke ich. Als ob es aber 24 bit wären oder
so...
Aber 24bit int gibt's ja nicht, oder? Zumal C18 default in einem 24-bit
Speichermodell läuft...
Seltsam.
Joachim ... schrieb:> //while (1) {> PORTCbits.RC0=1; // Einschalt-LED
.
.
.
> while (1);> } // Ende main
Machen die beiden whiles denn auch das, was sie sollen? Zumindest das
Obere ist nach derzeitigem Stand überflüssig.
Joachim ... schrieb:> unsigned uDummy1,uDummy2; // = unsigned int> unsigned char ucPattern;> //'595 No1> //die 16bit in 2x 8bit zerlegen, unteres Byte:> uDummy1 = uPattern;> uDummy1= uDummy1 & 0x00FF;> uDummy1 = (unsigned char) uDummy1; //ist das eigentlich erlaubt bzw.> notwendig???
Ich kenne die PICs ja nicht, aber ist SPI bei denen 16 bit?
Normalerweise schiebt SPI ja immer 8 bit raus.
Du solltest das mal mit uint8_t in 8 bit Portionen zerlegen. VerUNDen
mitt FF ist nicht nötig; geht auch mit 8 bit shiften.
> //wait (1); // PIG zu schnell...?
Ob das Schwein zu schnell ist, wer weiß ...
Joachim ... schrieb:> Ich schiebe immer 16 bit. Denke ich. Als ob es aber 24 bit wären oder> so...> Aber 24bit int gibt's ja nicht, oder? Zumal C18 default in einem 24-bit> Speichermodell läuft...
Na wenn Du es nicht weißt ...
>Der RCK noch nen Pulldown nach GND und der CLK könnte noch nen guten>PullUp nach Vcc vetragen, 10k wäre gut.
Eigentlich nicht, die Leitungen liegen ja direkt am Port. Oder hat etwa
der PIC kein Totem-Pole Ausgang? Das Dumme: im Datenblatt ist darüber
nichts explizit erwähnt, lediglich n Bild "Generic IO Operation" hab
ich.
Danke für eure Hilfe, aber das ist es alles nicht...
Ich bin nochmal mitm Speicher-Oszi ran (kann so was anzuschaffen nur
jedem empfehlen!)... und siehe da: Der PIC schickt beim zweiten Aufruf
der Funktion nur 8 anstatt 16 Taktbits weg. Als ob es ein SPI
Hardware-Feature wäre... werd' wohl noch n bisschen lesen müssen.
Problem erschlagen.
Für den Nächsten der drüberstolpert:
Offensichtlich ist im PIC ein Bit (Buffer leer o.ähnl.) das SSPBUF(?)
nutzt und damit ein sofortiges Wiederbeschreiben ins Leere laufen läßt.
Dadurch wird auch kein 8-bit Taktzyklus erzeugt was genaugenommen das
eigentliche Problem war.
Zwei Aufrufe von WriteSPI(Value); müssen durch eine Verzögerung getrennt
werden.
Wär es nicht einfacher, statt Trial&Error, das Datenblatt zu lesen?
Und dann einfach das Bit testen, welches anzeigt, daß alle Daten
herausgeschoben sind. Denn erst danach darfst Du die RCK-Flanke
erzeugen.
Peter
>Wär es nicht einfacher, statt Trial&Error, das Datenblatt zu lesen?
Oha... das sag' ich auch immer ;-)
>Und dann einfach das Bit testen, welches anzeigt, daß alle Daten>herausgeschoben sind.
Das irritierende war ja, daß es am Anfang ohne diese Bit zu testen
(wußte nicht das es das gibt) funktioniert hat... Auch im Example (Array
mit EEPROM r/W) hab ich nichts gefunden.