Hallo,
ich will mit einem Olimex AT90CAN128 Board 16-Bit Werte eines
Winkelsensors RFC 4800 von Novotechnik über CAN-Bus senden. Der Bus
funktioniert und läuft mit der CAN-Lib von Marco Glietsch
Beitrag "CAN-Bibliothek für den at90CAN128 und das AVRStudio".
Angeschlossen ist der Sensor wie in der angehängten
Applikation-Note(Anhang) des Herstellers beschrieben. Als FET habe ich
den BS170 verwendet(Anhang).
MISO --> Drain
MOSI --> Gate
GNG --> Source
Die Wiederstände habe ich wie in Zeile 4 (Atmel AVR) der Tabelle
beschrieben gewählt. Sicherheitshalber hab ich die Schaltung nochmal
durch gemessen. Soweit ok.
Nun habe ich meine Quellcode auf Basis verschiedener Beispiele u.A. aus
dem Datenblatt vom Controller und AVR151(Setup And Use of The SPI)
aufgesetzt. So weit ich es verstanden habe muss der Sensor in SPI Mode 1
betrieben werden. Also CPHA=1 und CPOL=0. Laut Support des Herstellers
soll ich die SCK-Frequenz auf 50kHz stellen.
Dazu habe ich einmal den IO-Clock Prescaler (CLKPR) auf 4 und dann noch
den SPI-Clock Prescaler auf 128 gesetzt um von 16MHz CPU auf 62,5kHz
SCK-Frequenz zu kommen.
Nach langem rumgefummel habe ich es hin bekommen, dass der Anfrage-Frame
gesendet wird (0x55, 0x00...[Laut Hersteller soll ich die invertierten
Signale von dem was in der Appikationnote steht senden]). Dazu ziehe ich
den SS-Pin erst auf Low und warte 1,5ms damit sich Master und Slave
synchronsieren. Dann SS-Pin wieder hoch für Mastermode und
Master-Enable, weil durch SS:low Master disable (MSTR in SPCR). Dann
senden nach dem in Beispielen üblichen Schema.
Anschließend wechsel ich durch SS-Pin auf Low in den Slavemode um Daten
zu empfangen. Mit der ebenfalls nach üblichem Schema aufgebauten
receive-Methode empfange ich dann zwei Bytes, aber beim dritten
Durchlauf der Methode wird while(!(SPSR & (1<<SPIF))) nicht mehr
verlassen.
Nun verstehe ich nicht warum das passiert. Darf ich den SS-Pin nicht auf
Low ziehen? Ist die Frequenz ok? Nächst kleinere wäre 31,25kHz. Was ja
viel zu kurz wäre. Muss ich das DDR-Register im Slavemode umstellen?
Also "MISO output, all others input". Z.z sieht es so aus:
1
SPI_DDR=(1<<SPI_DDR_MOSI)|(1<<SPI_DDR_SCK);
Anbei der SPI-Quellcode, in dem ich zur Kontrolle Ausgaben auf ein LCD
mache. Anbei auch ein Bild des LCD, damit man sich das besser vorstellen
kann. Weitere Ausgaben in der Main...
Und noch die Mail vom Support:
> sie verwenden sicherlich den im Datenprotokoll angegebenen FET, da> wir die 3-Leitertechnik verwenden. Der eingesetzte chip ist ein> Melexis 90316 und bietet dieses 3-Leiter Version an.> Um den eingesetzten Transistor zu sperren um Daten zu empfangen senden> Sie anstatt (AA,FF,FF,..) bitte die invertierten Signale (55, 00,00,..)> um den Transistor zu sperren.> Dann müssten Sie die Daten empfangen können. Bitte achten Sie darauf,> dass die timings eingehalten werden.> Bei einer clock rate von 50kHz müsste dies automatisch der Fall sein.
So ich hoffe ich habe alles geschrieben was wichtig sein könnte. Danke
schon mal für die Hilfe und dafür dass du bist ganz unten gelesen hast
:)
>Dazu ziehe ich>den SS-Pin erst auf Low und warte 1,5ms damit sich Master und Slave>synchronsieren. Dann SS-Pin wieder hoch für Mastermode und>Master-Enable, weil durch SS:low Master disable (MSTR in SPCR).
So ein Unsinn. SS schaltet den Master nur auf Slave um
wenn es ein EINGANG ist. SS als Ausgang kann man
nutzen um das SlaveSelect des Slaves zu steuern. Dazu legt
man SS auf low wenn man den Slave ansprechen möchte.
Beim lesen UND beim schreiben.
Den Master hier auf Slave umschalten zu wollen macht gar
keinen Sinn. Wer soll denn dann den SPI Takt liefern?
Dein Slave macht das jedenfalls nicht. Der Master empfängt
indem er DummyBytes sendet. Nur so wird der SPI Takt erzeugt.
Also bleibt der SS-Pin die ganze Zeit auf Low in meinem Fall, weil nur
ein Master und ein Slave? So war ich drauf gekommen:
http://www.atmel.com/images/doc2585.pdf
Seite 3 SS-Pin Funcionality
>Also bleibt der SS-Pin die ganze Zeit auf Low in meinem Fall,
Nein, SS legt man nur low wenn etwas gelesen, geschrieben
werden soll. Wenn man damit fertig ist zieht man SS auf high.
So bleibt das SPI immer schön synchron.
holger schrieb:> Der Master empfängt> indem er DummyBytes sendet. Nur so wird der SPI Takt erzeugt.
Also so:
1
charSPI_receive(void)
2
{
3
LCD_displayInt8(3,4,i);
4
5
SPDR=0x00;
6
7
//Wait for transmission to complete
8
while(!(SPSR&(1<<SPIF)));
9
LCD_displayInt8(3,6,i);
10
i++;
11
return(SPDR);
12
}
holger schrieb:> Nein, SS legt man nur low wenn etwas gelesen, geschrieben> werden soll. Wenn man damit fertig ist zieht man SS auf high.> So bleibt das SPI immer schön synchron.
1
voidSPI_SS_high(void)
2
{
3
SPI_PORT|=(1<<SPI_PIN_SS);
4
5
SPCR|=(1<<MSTR);
6
}
7
8
voidSPI_SS_low(void)
9
{
10
SPI_PORT&=~(1<<SPI_PIN_SS);
11
12
_delay_us(1500);
13
}
Muss MSTR in SPCR nochmal gesetzt werden?
Jan schrieb:> http://www.atmel.com/images/doc2585.pdf> Seite 3 SS-Pin Funcionality
Dort steht:
A low level will switch the SPI into slave mode and the hardware of the
SPI will perform the following actions:
1. The master bit (MSTR) in the SPI Control Register (SPCR) is
cleared
In der Main sieht es jetzt so aus:
Hmm nach dem ersten Trasmit bleibts wieder hängen. Seltsamerweise blinkt
auch in der zweiten Zeile, jedesmal wenn ich das Netzteil ein- und
ausschalte eine 666 auf. Das Anweisung dafür ist längst gelöscht, weil
ich nur was testen wollte. Oo
Extra in AtmelStudio auch ganz sicher nochmal die Datei vorm flashen
ausgewählt. Seltsam oder?