Forum: Mikrocontroller und Digitale Elektronik [MSP430] SPI funktioniert nicht richtig


von Roland N. (eroli)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,

ich versuche mit meinem MSP430F5438 mit einem MCP2515 CAN-Controller zu 
kommunizieren. Die Verdrahtung steht auch schon und ich konnte bisher 
noch keine Fehler identifizieren.

Ich verwende UCA1 als Hardware-SPI. Die Initialisierung läuft so ab:
Kurz zur Pin-Belegung (Mehr zu meiner Beschaltung findet ihr 
hier:Beitrag "[MSP430] Starthilfe zum MCP2515 CAN-Controller" )
UCA1SOMI  - P5.7
UCA1SIMO  - P5.6
UCA1CLK   - P3.6
UCA1STE   - P5.5
1
void Init_UCA1(void)
2
{
3
    P5SEL |= 0xC0;        // Activate UCA1SOMI, UCA1SIMO, UCA1STE is GPIO
4
    P5DIR |= 0x60;        // SOMI Input, SIMO, STE Output
5
6
    P3SEL |= 0x40;        // Activate UCA1CLK
7
    P3DIR |= 0x40;        // UCA1CLK Output
8
9
    P5OUT |= 0x20;        // UCA1STE to High (Chip select)
10
11
    unsigned int prescaler;
12
    UCA1CTL1 |= 0x01;         //UCSWRST = 1 (reset state enable)
13
14
     UCA1CTL0 = 0x69;  // Mode 0,0; MSB first, 8bit data, Master Mode, 3Pin-SPI, Synchronous mode
15
               // TI Mode 0,0 != Motorola Mode 0,0: Clock Polarity is inversed, so you have to set UCCKPL
16
    // 0x69 = 0110 1001 = Inactive State is High, MSB first, 8-Bit Data, Master Mode, 3-Pin SPI, Synchronous Mode
17
18
    UCA1CTL1 |= 0x80;   //clock source - SMCLK
19
    // 0x80 = 1000 0000
20
21
    prescaler = OSC_FREQ / MCP_BAUDRATE;
22
    UCA1BR0 = prescaler % 256;
23
    UCA1BR1 = prescaler / 256;
24
25
    UCA1CTL1 &= ~(0x01);       //UCSWRST = 0 (reset state disable)
26
}
27
28
// Anmerkung: OSC_FREQ = 18000000
29
// Anmerkung: MCP_BAUDRATE = 1000000

Nach der Initialisierung wird in einer while-Schleife versucht mit dem 
Controller zu reden. Es wird versucht der Status auszulesen und das 
Resultat ist immer 0.

Ich bin sehr neu in dieser Materie, aber ich habe mir die Geschehnisse 
mal auf dem Oszilloskop angeschaut. Das Ergebnis seht ihr in den zwei 
angehangenen Bildern.

Für mich sieht es so aus, als ob der Clock an sich funktioniert (Ist er 
vielleicht zu unsauber?). Auch werden Daten vom MSP an den 
CAN-Controller gesendet (Erstes Bild, untere Kurve).

Allerdings antwortet der Controller nicht (richtig). Wenn man sich das 
zweite Bild anschaut sieht man wieder die Clock oben und MISO unten. 
Achtet man hier auf die Skalierung sieht man ganz klar, dass da zwar 
"etwas" ist, aber viel viel viel zu schwach... Der MISO-Pin vom 
CAN-Controller hängt übrigens in der Luft, wird also eigentlich nicht 
von einer externen Beschaltung beeinflusst...

Ich bin mittlerweile mehr als ratlos... Habt ihr vielleicht irgendwelche 
Ideen, warum die Kommunikation nicht funktioniert?

: Bearbeitet durch User
von Roland E. (roland0815)


Lesenswert?

Der Pegel am Datenpin stimmt gar nicht ?!?

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Schaltung?

von Easylife (Gast)


Lesenswert?

Und was macht CS_N in dieser Zeit?

von Jim M. (turboj)


Lesenswert?

> P5OUT |= 0x20;        // UCA1STE to High (Chip select)

Bei den allermeisten Chips ist SPI CS active low.

Für CS = High sieht das Bild CLK_MISO OK aus, etwas Übersprechen hat man 
fast immer - MISO ist in dem Fall hochohmig.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Jim Meba schrieb:
> Bei den allermeisten Chips ist SPI CS active low.

So auch beim MCP2515, siehe Datenblatt, Seite 63, grauer Kasten.

von seb (Gast)


Lesenswert?

In der Init spielt der Chipselect Zustand noch keine Rolle.
Erst wenn der SPI-IC dann benutzt wird muss er low gesetzt sein, aber 
der Code fehlt ja noch.

von Roland N. (eroli)


Angehängte Dateien:

Lesenswert?

Hallo zusammen!

Erstmal vielen Dank für die weiteren Antworten :-)

Ich schreibe so auf die SPI Schnittstelle:
1
void write_mcp(char addr, char value)
2
{
3
  P5OUT &= ~0x20;      // Chip-Select Low ==> Enable
4
  UCA1TXBUF = 0x02;    // Schreibbefehl
5
  while(UCA1STAT & 0x01);  // Wait SPI Interrupt Flag to be set, i.e. transmission complete
6
  UCA1TXBUF = addr;
7
  while(UCA1STAT & 0x01);
8
  UCA1TXBUF = value;
9
  while(UCA1STAT & 0x01);
10
  P5OUT |= 0x20;      // Chip-Select High ==> Disable
11
}

Und so lese ich (was ja eigentlich dasselbe ist in etwa):
1
char read_mcp(char addr)
2
{
3
  char data;
4
5
  P5OUT &= ~0x20;
6
  UCA1TXBUF = 0x03;    // Lesebefehl
7
  while(UCA1STAT & 0x01);
8
  UCA1TXBUF = addr;
9
  while(UCA1STAT & 0x01);
10
  UCA1TXBUF = 0xAA;    // Dummy-Byte senden
11
  while(UCA1STAT & 0x01);
12
  data = UCA0RXBUF;
13
  P5OUT |= 0x20;
14
15
  DelayMicroSeconds(10);
16
17
  return data;
18
}

Außerdem ist mir noch ein Punkt eingefallen, wobei ich nicht weiß, ob 
der wirklich relevant ist, nämlich, dass das Board (Olimex MSP-5438STK) 
über USB mit Strom versorgt wird. Könnte es sein, dass der USB-Anschluss 
nicht mehr nachkommt? In diesem Bezug habe ich auch mal versucht, das 
Board über zwei USB-Anschlüsse zu speisen (USB --> JTAG-Adapter und USB 
an die USB-Buchse des Boards). Allerdings hat dies auch keine 
Veränderung ergeben...

Ein Bild von der Chip-Select-Line liefer ich euch gleich nach...

EDIT:
Ich habe euch jetzt mal einen Ausschnitt aus meinem Schaltplan mit den 
wensentlichen Komponenten angehangen. Bitter nicht direkt rummeckern, 
das ist nämlich das erste Mal, dass ich einen Schaltplan mit EAGLE so 
richtig aufgemalt habe...
Außerdem findet ihr jetzt auch ein Bild vom CLK und der CS-Line. Ich 
denke dies dürfte das Problem sein, da die CS-Line ja anscheinend nach 
jeder Bit-Übertragung den Pegel ändert... Ich frage mich nur warum?
Aufgezeichnet wurde dieses Bild übrigens direkt am Board - das heißt 
ohne die zusätzliche angeschlossene Hardware, damit ich Schaltungsfehler 
auf meiner Zusatzplatine ausschließen kann (Allerdings sah das Bild 
direkt am MCP aufgezeichnet genau so aus).

Wenn ihr noch weitere Informationen braucht, dann meldet euch doch 
einfach. Nochmals vielen Dank für euer Engagement :-)

: Bearbeitet durch User
von Roland N. (eroli)


Angehängte Dateien:

Lesenswert?

Nochmal Hallo zusammen!

Bisher habe ich den Baustein immer regelmäßig in einer while-Schleife 
abgefragt. Das sah in Etwa so aus:
1
void CAN_Update(void)
2
{
3
  volatile char state;
4
  state = can_state();
5
  /*
6
  m_Status = can_chk();
7
  if (m_Status)
8
  {
9
      ...
10
  }
11
  */

Sobald ich die zweite Abfrage (can_chk()) auskommentiert habe, sieht 
meine Chip-Select-Leitung auf einmal viel besser aus. Man sieht 
deutlich, wie sie während der Übertragung fast konstant auf GND bleibt, 
obwohl auch da leichte Störungen (?) von der Clock-Leitung erkennbar 
sind...

Unter denselben Bedingungen, also mit der anständigen CS-Leitung, habe 
ich dann auch nochmal ein Bild der MISO-Leitung aufgenommen. Für mich 
sieht es so aus, als ob der IC reagieren wollte, aber es irgendwie nicht 
so richtig schafft... Danach fällt der MISO-Pegel langsam aber sicher 
wieder auf GND ab...

Man beachte beim zweiten Bild wieder den angepassten Wertebereich. Auf 
der Y-Achse ist dieser doppelt so hoch aufgetragen für die MISO-Kurve. 
Der höchste Peak beträgt aber nur 560mV (dieser wird ungefähr dreimal 
annähernd erreicht). Außerdem habe ich zur besseren Darstellung auch die 
X-Achse anders skaliert.

EDIT: Ich habe nochmal ein neues Bild unter den gleichen Bedingungen 
aufgenommen. Hier sieht man deutlicher, wie der Pegel mit der Zeit immer 
weiter abfällt. Außerdem sind hier die Cursors gesetzt, damit ihr mir 
den Peak von ca. 560mV auch glaubt ;-)

EDIT2: Um die Stromlimitierung des JTAG-Adapters ausschließen zu können, 
habe ich dieselbe Messung nochmal gemacht, wenn das Board direkt über 
den USB-Anschluss versorgt wird. Dies macht jedoch keinen Unterschied: 
Die Messung ergab genau dasselbe Verhalten...

: Bearbeitet durch User
von Roland N. (eroli)


Angehängte Dateien:

Lesenswert?

Nochmal Hallo!

Ich habe jetzt der Vollständigkeit halber auch mal die GND und 
VCC-Leitungen zusammen mit der Clock aufgenommen. Die Ergebnisse findet 
ihr wie immer im Anhang...

Sind die Schwankungen auf diesen Leitungen im Rahmen?

Viele Grüße,
Roland

von Knobikocher (Gast)


Lesenswert?

Benutzt du Tastköpfe oder nur einfach Laborleitungen zum Messen?
Diese Störungen (Übersprechen des Taktes) sehen ein wenig danach aus. 
Keine vernünftige bzw. zu lange Verbindung zum GND der Messleitung-> 
Überschwinger im Signal und auch gerne Übersprechen. Diese Verbindung 
zum GND muss so kurz wie möglich sein.

Oder messe mal ein Signal ohne gleichzeitig auch CLK zu messen.

von Roland N. (eroli)


Lesenswert?

Hallo zusammen,

ich bin mittlerweile einige Schritte weiter gekommen... Das Problem war 
mein Quarz, der wohl nicht richtig geschwungen hat und was ich leider 
nicht ordentlich genug überprüft habe :-/
Den Hinweis dazu habe ich hier gefunden: 
http://www.microchip.com/forums/m511643.aspx

Nachdem dieses Problem erledigt war, konnte ich nun auch endlich 
feststellen, dass der CLKOUT-Ausgang meines CAN-Controllers funktioniert 
:-)

Über die Initialisierungsroutine konnte ich feststellen, dass der 
CLKOUT-Ausgang deaktiviert wird, sobald man in den Configuration-Mode 
geht. Daraus schließe ich, dass der Controller meine SPI-Befehle korrekt 
lesen kann.

ALLERDINGS: Ich kann weiterhin nichts lesen... Das alte Problem des 
niedrigen, kaum erkennbaren MISO-Pegels bleibt bestehen... Hat jemand 
vielleicht eine Idee zu dieser Problematik?

von Holm T. (Gast)


Lesenswert?

Wo liegt denn der MISO Pin Gleichspannungsmäßig?

Gruß,

Holm

von Roland N. (eroli)


Lesenswert?

Ich bin mir nicht sicher, ob ich das gemacht habe, was du meinst, aber 
wenn ich mit Multimeter an den MISO Pin gehe, dann schwankt die 
(Gleich-)Spannung zwischen 0,003V und 0,006V...

Irgendwie finde ich mich sehr stark hier wieder:
Beitrag "SPI-Poblem MISO erreicht Pegel nicht"
Und dort konnte keine Lösung gefunden werden... :-(

Auch hier finde ich dieselbe Problematik wieder - auch ohne Lösung...
Beitrag "MCP2515 sendet kein SO Signal an MISO (SPI)"

: Bearbeitet durch User
von Roland N. (eroli)


Lesenswert?

Hallo zusammen,

ich möchte hiermit mein Problem als gelöst melden, damit sich keiner 
weiterhin den Kopf hierüber zerbricht...

Mein erstes Problem war, wie bereits gesagt, dass mein Quarz nicht 
richtig funktionierte. Er war halt doch ein Stück zu weit vom Controller 
entfernt. Dass der Quarz ordentlich funktioniert und der Chip "lebt" 
erkennt man daran, dass der CLKOUT-Ausgang (ohne Konfiguration, also per 
Default) eingeschaltet ist mit einem Divider von 8. Wenn man hier eine 
Oszillation messen kann, sollte der Chip an sich funktionieren.

Das SPI-Problem habe ich testweise mit einem externen Pull-Up-Widerstand 
versucht zu lösen. Damit konnte ich wunderbar erkennen, dass der 
Controller versucht mir zu antworten. Ohne Pull-Up waren nur Änderungen 
um die 300mV erkennbar. Mit PullUp wurde die gesamte Breite von 0V-3.3V 
angefahren.

Das nächste Problem war, dass ich nichts empfangen konnte, obgleich das 
Oszilloskop mir bestätigte, dass da auf jeden Fall Daten auf der Leitung 
vorhanden sind...
Ungefähr eine Stunde später fiel mir folgende Zeile im Code auf, nachdem 
mein SPI sogar im Loopback-Mode nichts empfangen konnte:
1
[...]
2
  while(UCA1STAT & 0x01);
3
  data = UCA0RXBUF;
4
[...]

Ich denke hierzu muss ich nichts weiter sagen ;-)

Jedenfalls funktioniert es jetzt - auch mit den internen PullUps ;-)

Wieso man jedoch sagt, warum PullUps bei diesem Chip nicht notwendig 
wären, bleibt mir weiterhin ein Rätsel...

: Bearbeitet durch User
von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Roland M. schrieb:
> Ungefähr eine Stunde später fiel mir folgende Zeile im Code auf

Glückwunsch ...

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.