Hallo,
kurz vorweg: die Forensuche habe ich benutzt und eine Vielzahl an Themen
gefunden, die allerdings mein Problem nicht lösen konnten.
Ich versuche seit einiger Zeit verzweifelt, SPI zum Laufen zu bringen,
allerdings bleibt das Ganze beim Senden vom ersten Byte hängen.
Es sollen zwei ATMEGA328P miteinander verbunden werden, der Eine "roh",
der Andere in einem 7-Segment-Anzeige-Breakout-Board (COM-09764 [1]).
Um genauer zu seien, ist dies hier die Zeile, in der das Ganze hängen
bleibt meiner Vermutung nach (erkennbar durch die eingeschaltene
Debug-LED):
Im Datenblatt vom COM-09764 steht, CPOL und CPHA werden als 0 benötigt.
Angeschlossen wurde das ganze wie folgt:
1
Hauptchip Breakout-Board
2
SCK SCK
3
MISO SI
4
SS CSN
5
VCC VCC
6
GND GND
Beim Programmieren werden vom Breakout-Board anscheinend Signale
empfangen, da es sich wild verändert. Das Bauteil scheint also noch zu
funktionieren. Allerdings wird beim Schreiben des ersten Bytes nichts
verändert.
Im Anhang ist der komplette C-Code, größtenteils aus dem ATMEGA328
Datenblatt entnommen.
Verwende SPI zum ersten Mal, also lasst bitte Gnade walten. ;-)
Wäre schön wenn jemandem einfällt, woran es liegen könnte!
[1] http://www.sparkfun.com/products/9764
Danke für den Hinweis, Stefan.
Habe im Forum einen Beitrag gefunden, der mich weitergebracht hat. [1]
Ich bin mir noch nicht ganz sicher wie das Konzept von
SlaveSelect(SS)/ChipSelect(CS) funktioniert, aber es scheint ja nicht so
sonderlich kompliziert zu sein:
SS low sagt dem angeschlossenen Gerät sich bereitzumachen, Daten zu
empfangen. SS high dementsprechend das Gegenteil.
Bin aber noch verwirrt von PINB2 (SS mit Dach). Eigentlich ist die
besondere Funktion nur interessant, wenn man den Chip als Slave benutzen
will und Daten empfangen/sich aus dem Sleep-Zustand wecken zu lassen,
oder?
Habe im Datenblatt vom Chip zu dem SS-Pin den erklärenden Text gefunden:
> SS: Slave Select input. When the SPI is enabled as a Slave, this pin is> configured as an input regardless of the setting of DDB2. As a Slave, the> SPI is activated when this pin is driven low.> When the SPI is enabled as a Master, the data direction of this pin is> controlled by DDB2. When the pin is forced by the SPI to be an input, the> pull-up can still be controlled by the PORTB2 bit.
D.h. ich kann einen beliebigen digitalen I/O-Pin (z.B. PINC5) nehmen, um
damit speziell einen Slave auszuwählen?
Habe das versucht in C umzusetzen, allerdings schein ich noch einen
Fehler drin zu haben. Der Code ist im Anhang.
Leider kommt kein Signal zurück von dem Gerät, ob ich SS low oder high
eingestellt habe (Zeile 44).
Danke schonmal für die Hilfe. :-)
[1] Beitrag "SPI Verständnisproblem"
P. Waldmann schrieb:> D.h. ich kann einen beliebigen digitalen I/O-Pin (z.B. PINC5) nehmen, um> damit speziell einen Slave auszuwählen?
Ja, aber es ist für die Funktion als Master wichtig, dass der SS-Pin
(PB2) auf Ausgang steht. Wenn es ein Eingang ist und er geht auf Low
(was bei einem floatenden Eingang auch schnell von alleine passiert),
wechselt der Master sofort in den Slave-Modus (auch mitten in der
Übertragung).
Wenn ist Hauptchip im Multislave mode (Master.SS verwendet nicnt, aber
als SS geht andere PC7), soll PB5(SS) als imput anschalten und mit VCC
verbinden (such mal ein PDF auf atmel.com mit Suchwort "SPI").
Dazu braucht noch manipulation SPCR.MSTR.
void SPI_MasterTransmit(char cData) {
/* Start transmission */
SPDR = cData;
/* Wait for transmission complete */
SPCR &= ~(1<<MSTR);
SPCR |= (1<<MSTR);
SS_P &= ~(1<<SS);
while(!(SPSR & (1<<SPIF)));
}
Danke für die vielen Antworten! Jetzt hab ich SPI endlich verstanden und
es scheint teils zu funktionieren.
Die 7-Segment Anzeige scheint Signale entgegenzunehmen, da sie sich bei
fast jedem Signal verändert. Irgendwie ist das ganze allerdings noch ein
bisschen komisch, weil ich es nicht richtig kontrollieren kann.
Im Datenblatt vom COM-09764 [1] steht, dass man Sonderbefehle in
2-Byte-Paketen verschicken soll, Zeichen hingegen in 4-Byte-Paketen.
Ich versuche also 4 Mal hintereinander über SPI Pakete etwas zu
verschicken:
1
SPI_MasterTransmit(0x01);
2
SPI_MasterTransmit(0x01);
3
SPI_MasterTransmit(0x01);
4
SPI_MasterTransmit(0x01);
5
_delay_ms(3000);
6
7
SPI_MasterTransmit(0x02);
8
SPI_MasterTransmit(0x02);
9
SPI_MasterTransmit(0x02);
10
SPI_MasterTransmit(0x02);
11
_delay_ms(3000);
Allerdings gibt das eine komische Kombination:
1
0111
2
2221
3
1121
4
2122
5
2111
6
2221
7
1121
8
2122
9
2111
10
...
Habe bei verschiedenen Kombinationen immer noch nichts herausgekriegt
und werde daraus auch nicht schlau. Wenn ich z.b. bei beiden Parts (vor
den Pausen) jeweils 0x01, 0x02, 0x03, 0x04 verschicke bekomm ich
folgendes Muster:
hi,
"The maximum speed of the SPI clock input is 250kHz.
The display is configured to use SPI mode 0 (CPOL =
0, CPHA = 0), so the clock line should idle low and
data is sampled on the rising edge."
Schau mal Datenblatt für dein Hauptkontroller. Da gibt es Information
über SPSR u. SPCR register. Im SPSR gibt es paar Bits welche
Haupkontrollertaktfrequez für SCK dividieren kann.
Eine eigene Frage?
Dieser Thread ist über 15 Jahre alt.
Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.