Forum: Mikrocontroller und Digitale Elektronik MSP430 SPI Schnittstelle Pegel


von reflection (Gast)


Lesenswert?

Hallo zusammen

Ich habe ein Problem mit meinem MSP430F149 (ist ja nichts neues :o))

Habe hier noch einen Thread dazu, aber ich bin mir nicht mehr sicher ob 
es am MSP430F149 oder am MAX7221 liegt. MAX habe ich übrigens schon 
gewechselt, Hardware kann ausgeschlossen werden.

Beitrag "Problem mit Ansteuerung MAX7221"

Mit dem MAX steuer ich eine 8x8 Matrix an, oder besser gesagt ich möchte 
es...

Das Problem ist, dass der MAX, irgendwie gar nichts macht, sprich es 
leuchten alle LED, was komisch ist, denn wenn ich ihn nicht 
initialisiere, soll er laut Datenblatt in den Shutdown Mode gehen und 
alle LED löschen.

Die Daten kommen am MAX an, SCLK, DIN und CS (direkt am MAX gemessen)

Was mir nun aber komisch erscheint: Messe ich am MAX an DOUT, ist das
inaktive Level auf 0 (er soll laut Datenblatt die Daten 16.5 Clocks 
später an DOUT rausschieben nachdem sie an DIN ankamen), wenn ich aber 
am DIN messe ist das inaktiv Level 1. Ist das so korrekt? Ich kann so 
viel ich weiss den MSP gar nicht so einstellen das der inaktive SPI 
Level auf 0 liegt. Den SCLK habe ich so eingestellt, also dort ist der 
inaktive Level auf 0, wie im Datenblatt beschrieben, aber wie stelle ich 
ein, dass der inaktiv Level der Daten auf 0 ist?

Um Daten an den MAX zu senden, werden 8Bit Adresse und 8Bit Daten 
gesendet.
Der CS muss dazwischen nicht ausgeschaltet werden, also eigentlich 16Bit 
am Stück. Wenn ich am SCLK Pin messe kommen 8 Clocks, dann eine kurze
pause, da er ja wartet bis die Daten übertragen wurden, und dann wieder
8 Clocks. Habe eben nur ein 8Bit Register für die SPI Schnittstelle,
kein 16Bit. Kann das zu Problemen führen? Also ich meine, dass der Clock
"unterbrochen" wird? Die Daten müssten ja trotzdem ankommen, oder sehe
ich das falsch?

Wäre toll wenn ihr mir helfen könntet. Irgendwie kann es fast nur noch 
an der SPI Schnittstelle liegen, Code für den MAX habe ich im Netz genug 
gefunden und ich mache auch nichts anderes als die. Also von der 
Initialisierung usw.

Gruss

von Christian R. (supachris)


Lesenswert?

Das Inaktiv-Level des MOSI kannst du nicht einstellen, ist auch egal. 
Die Daten werden mit der steigenden Flanke des Taktes übernommen. Und 
ich glaub da liegt eventuell das Problem. Wenn ich den Code anschaue im 
anderen Thread, hast du CKPL und CKPH beide Null. Das heißt, zur 
steigenden Flanke schaltet der MSP430 die Daten am Ausgang um. Genau zu 
der Flanke liest der MAX die aber ein, also kommt Müll raus. Du müsstest 
entweder CKPH oder CKPL auf 1 setzen, dann aktualisiert der MSP den 
Ausgang bei der fallenden Flanke des taktes und die Daten liegen stabil 
an, wenn der MAX sie sampelt.

von reflection (Gast)


Lesenswert?

Das habe ich mir auch schon gedacht, aber ich habe bereits alle 
Varianten ausprobiert und es ist immer dasselbe. Es ändert sich nix :o(

von Christian R. (supachris)


Lesenswert?

Hast du ein Oszilloskop, mit dem du das mal überprüfen kannst?

Noch was:
1
// Definieren Chip Select MAX7221
2
3
#define CS_HIGH()    P2OUT |= 0x01
4
#define CS_LOW()    P2OUT &= 0xFC

Ist das Absicht? Das Komplement von 0x01 ist 0xFE und nicht 0xFC. Lass 
das doch den Kompiler machen:
1
// Definieren Chip Select MAX7221
2
#define CS                      0x01
3
#define CS_HIGH()    P2OUT |= CS
4
#define CS_LOW()    P2OUT &= ~CS

von reflection (Gast)


Lesenswert?

Das ist korrekt, also an P2.0 hängt der Max und an 2.1 der 74HCT244. 
Diesen benutze ich als Level Shifter, da der MAX 5V Level benötigt. dort 
ziehe ich den Enable Pin auf Low. Zuerst wird also bei einer Übertragung 
der 74HCT244 aktiviert, dann warte ich kurz und aktiviere den MAX.

Habe eben nur eine Sonde, darum kann ich das nicht messen wann genau der 
Puls kommt, aber wie gesagt, habe alle Varianten immer wieder 
durchprobiert.

Ein Kollege im anderen Thread meinte, der MAX sei sehr empfindlich und 
ein Layout wie ich es hätte, Lochrasterplatine würde niemals laufen. Was 
meinst Du. Habe eben nur den SMD Typ bekommen und musste ihm mit Wrap 
Drahten anschliessen. Habe aber schon sehr viele Schaltungen so 
aufgebaut und hatte noch nie Probleme

Gruss

von Christian R. (supachris)


Lesenswert?

Ahso, mit dem MAX kenn ich mich nicht aus. Kann aber sein. Wenn das SPI 
Zeugs richtig rauskommt, wird´s wohl am MAX liegen müssen.

von reflection (Gast)


Lesenswert?

Hab gerade gelesen der soll enorm empfindlich auf Störungen der Speisung 
reagieren. Werde mir wohl einen Adapter fräsen müssen

Gruss und merci für die Hilfe

reflection

von reflection (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen

Ich bin ein Stück weiter gekommen. Konnte endlich eine zweite Sonde für 
den KO holen und siehe da, folgendes:

Der CLK und die Daten kommen sauber am MAX an, habe ich mit zwei Sonden 
gemessen und die Daten stimmen mit dem gesendeten, der CLK ist so 
gelegt, wie im Datenblatt des MAX beschrieben.

Das Problem ist der CS. Dieser macht was er will! Der CS müsste LOW sein 
während der ganzen 16CLK Pulse eines Befehls. Der CS ist auch meist LOW, 
aber irgendwo im CLK stream geht er auf HIGH und kurz danach wieder auf 
LOW. Er ist alles in allem gesehen viel zu lang LOW, vor allem wenn auch 
die Senderoutine bereits abgeschlossen ist. Im Code den angehängt habe 
sieht man, wie ich es mache, zuerst CS auf LOW, dann Daten senden und 
dann CS auf High. Er macht alles andere, einfach invertiert ist es auch 
nicht. Der Pin zieht völlig asynchron zu den Daten auf LOW mit einer 
völlig anderen Zeit als er sollte.

Dachte ich mir, OK, vielleicht ist ja der Port im Eimer oder so. Habe 
also genau gleich wie ich hier Port2 für den CS einsetzte, Port4 
mitlaufen lassen. Sie sehen absolut identisch aus, also Port2 macht 
denselben Mist wie Port4

Wäre echt toll wenn mir jemand helfen könnte und den Code kurz 
durchschauen.

Gruss reflection

PS: Der CS des MAX ist auf P2.0, der des 74HC244 auf P2.1
Port2 ist folgendermassen initialisiert:

P2SEL &= 0x00;
P2DIR = 0x03;

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> Er macht alles andere, einfach invertiert ist es auch
> nicht. Der Pin zieht völlig asynchron zu den Daten auf LOW mit einer
> völlig anderen Zeit als er sollte.

Daß das auch an der "Messung" mit dem "KO" (was zum Teufel hat diese 
Abkürzung mit Oszilloskop zu tun?) liegen kann, ist Dir klar?

Welches Signal verwendest Du zum Triggern?

von Felix (Gast)


Lesenswert?

KO ->  K atodenstrahl O szilloskop

Kommt aus der Zeit als die Dinger noch Röhren hatten und nicht WinXPs..

Felix

von Udo (Gast)


Lesenswert?

Ich würde extern auf die positive Flanke des LOAD Signals triggern und 
mir dann das SCLOCK-Signal und das DIN-Signal gleichzeitig anschauen.
Wichtig dabei ist, dass am Ende der Datenübertragung (DIN) das 
SCLOCK-Signal mit einer steigenden Flanke endet. Sollte nach 16 
High-Flanken des SCLOCK-Signals, SCLOCK nochmals auf High gehen, bevor 
LOAD wieder auf High ist, verliert der 72xx die Data.

Gruß
Udo

von Stefan (Gast)


Lesenswert?

Dein Problem ist das hier:
1
void SPI0WaitForComplete(void)       // Warten bis Sende / Empfangs Buffer frei
2
{
3
  while (!(IFG1 & UTXIFG0));             // USART0 TX buffer ready?
4
  do
5
  {
6
    IFG1 &= ~URXIFG0;
7
  }
8
  while (URXIFG0 & IFG1); 
9
}

Zuerst sendest Du die Adresse (op).
In do-while setzt Du URXIFG0 zurück. Wenn dann die while-Bedingung 
abgefragt wird, ist die Datenübertragung noch nicht fertig und Du 
springst aus der Schleife raus, weil URXIFG0 immer noch null ist.
Danach wird das zweite Byte (val) in den TXBUF0 gelegt und gesendet. Das 
do-while-Problem wiederholt sich, Du springst zu früh aus der Schleife 
und setzt CS auf High, obwohl das zweite Byte noch gar nicht komplett 
übertragen wurde!

Ausserdem überprüft man UTXIFG0 bevor man Daten in TXBUF0 legt und 
nicht hinterher, das ist aber hier nicht das Problem!

von Guest (Gast)


Lesenswert?

Hallo zusammen

Danke für die Antworten. Das mit dem SPI prüfen ob gesendet habe ich 
jetzt schon in so vielen Variationen gesehen und mir wurde bestätigt, 
das der Code so korrekt ist. Kann mir in diesem Falle mal jemand sagen 
wie ich das dann absolut korrekt abfrage? Hatte mal selber was 
geschrieben und das lief auch, aber es sagte jemand das das nur Glück 
sei. (dieses im Code verwendete SPIWaitforComplete stammt von jemandem 
aus dem Forum) .

Wäre toll wenn ihr mir weiterhelfen könntet. Achja, habe es jetzt soweit 
am laufen, dass wenn ich jeweils nach dem LOW ziehen, resp. vor dem High 
setzen des CS ein 50uS Delay einbaue und siehe da es lauft. Würde mich 
aber schon noch interessieren wie ich es korrekt machen muss, will ja 
was lernen :o)

Gruss reflection

KO: Kathodenstrahl Oszilloskop :o) Sorry, komme aus der CH, da ist das 
ein gängiger Ausdruck, kennt man das in D nicht?

von Christian R. (supachris)


Lesenswert?

Guest wrote:
> KO: Kathodenstrahl Oszilloskop :o) Sorry, komme aus der CH, da ist das
> ein gängiger Ausdruck, kennt man das in D nicht?

Bei uns heißt das schlicht und korrekt Oszilloskop und Tastkopf. Mir war 
auch oft nicht klar, was ein KO und Sonde sein soll bei dir hier ;)

zumal man mit einem echten alten "KO" gar keine SPI-Übertragung sinnvoll 
angucken kann, das geht ja nur mit einem Speicher-Oszi.

von reflection (Gast)


Lesenswert?

Jaja, die Deutsch-Schweizer Unterschiede :o) Fängt ja schon bei Natel 
und Handy an :o)

von Stefan (Gast)


Lesenswert?

>dieses im Code verwendete SPIWaitforComplete
>stammt von jemandem aus dem Forum
Ja, ich weiß... und der hat's wiederum von TI... und die sind auch nicht 
gerade bekannt für fehlerfreie Beispielcodes ;-)

>Würde mich aber schon noch interessieren wie ich es korrekt machen muss
Z.B. so:
1
void spiSendByte(char op, char val)
2
{
3
  char   dummy;
4
5
  P2OUT &= 0xFC;                   // CS low
6
7
  while (!(IFG1 & UTXIFG0));       // USART0 TX frei?
8
  TXBUF0 = op;                     // Sende Adresse
9
  while (!(IFG1 & URXIFG0));       // Datenübertragung komplett? 
10
  dummy = RXBUF0;                  // RX-Buf lesen -> URXIFG0 wird gelöscht
11
12
  while (!(IFG1 & UTXIFG0));       // USART0 TX frei?
13
  TXBUF0 = val;                    // Sende Daten
14
  while (!(IFG1 & URXIFG0));       // Datenübertragung komplett?
15
  dummy = RXBUF0;                  // RX-Buf lesen -> URXIFG0 wird gelöscht
16
        
17
  P2OUT |= 0x01;                   // CS high
18
}

Zuvor (z.B. in der Init) würde ich sicherheitshalber URXIFG0 einmalig 
löschen, also z.B. auch ein Dummy-Read auf RXBUF0 anwenden.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

> KO ->  K atodenstrahl O szilloskop
>
> Kommt aus der Zeit als die Dinger noch Röhren hatten und nicht WinXPs..

Nee, das kann nur aus einer Zeit stammen, in der die Bildröhre eben 
nicht mehr der selbstverständliche Standard war.

> zumal man mit einem echten alten "KO" gar keine SPI-Übertragung sinnvoll
> angucken kann, das geht ja nur mit einem Speicher-Oszi.

Doch, das kann man schon, vorausgesetzt, daß die Übertragung ausreichend 
oft stattfindet.
Dann wird entweder ausreichend schnell "gechoppt" oder aber, wenn das 
nicht schnell genug ist, mit alternierender Strahldarstellung 
gearbeitet.
Oder ganz edel mit einem echten Zweistrahloszilloskop. Die ersten beiden 
Optionen setzen allerdings voraus, daß man weiß, wie man die 
Triggersteuerung des Oszilloskops zu bedienen hat.

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.