Forum: Compiler & IDEs SPI -> ATmega32


von Seb (Gast)


Lesenswert?

Moin zusammen,

ich habe ein Problem mit der SPI und dem ATmega32 - Und zwar habe ich 
folgenden Code geschrieben bzw aus dem Datenblatt übernommen
1
void SPI_Transmit(uint16_t Data)
2
{
3
4
SPI_DDR = 0xFF;
5
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);    /* Enable SPI, Master, set clock rate fck/16 */
6
7
8
Data_H = ((Data >>8) & 0x00FF);
9
Data_L = Data & 0x00FF;
10
11
SPDR = Data_H;                /* Start transmission */
12
while(!(SPSR & (1<<SPIF)));
13
                      /* Wait for transmission complete */
14
15
SPDR = Data_L;                /* Start transmission */
16
while(!(SPSR & (1<<SPIF)));          /* Wait for transmission complete */    
17
18
19
20
}

Bei dem Code wird in die Funktion ein 2Byte Datum übergeben.
Dieser Wert wird ersteinmal in Data_H und Data_L augesplittet und danach 
in 2 kleinen häppchen dem SPI-Data Register übergeben.

Am Anfang der Funktion wird wie ich schon überallgelesen habe mit 
SPI_DDR der gesamte PORTB auf Ausgang geschaltet damit sollte auf 
jedenfall MOSI,SCLK und /SS auf Ausgang stehen und der übertragung 
sollte nichts mehr im wege stehn.

Der ganze code wird in einer Endlosschleife abgespielt aber ich bekomme 
weder ein Signal auf der CLK oder Mosi Leitung. MOSI ist die ganze zeit 
auf 5V - Mit oszilloskop gemessen.

Habe ich irgendwas übersehn ?

wäre super wenn jmd den code mal grade überfliegt.


Vielen Dank schonmal.

Ich teste auch mal weiter

von Seb (Gast)


Lesenswert?

Achja an /SS ist auch nichts angeschlossen ich messe da dauerhaft 0V 
Pegel.

von Michael U. (amiga)


Lesenswert?

Hallo,

angesehen davon, daß es unsinnig ist, den SPI jedesmal beim Senden neu 
einzuschalten (wenn der initialisiert ist, bleibt er das natüröich auch, 
soalnge nichts anderes ins SPCR programmiert wird), sehe ich keinen 
offenkundigen Fehler.

SS muß bei reinem Masterbetrieb Ausgang sein, Pegel ist egal, kann als 
normaler Ausgangspin genutzt werden.
Um um die Richtung von MOSI/MISO/SCK kümmert sich SPI selbst, sobald es 
eingeschaltet ist.

Gruß aus Berlin
Michael

von Stefan E. (sternst)


Lesenswert?

Michael U. schrieb:

> Um um die Richtung von MOSI/MISO/SCK kümmert sich SPI selbst, sobald es
> eingeschaltet ist.

Nein. Stimmt im Master-Mode nur für MISO.

von Lutz (Gast)


Lesenswert?

>> Am Anfang der Funktion wird wie ich schon überallgelesen habe mit
>> SPI_DDR der gesamte PORTB auf Ausgang geschaltet

>> damit sollte auf jedenfall MOSI,SCLK und /SS auf Ausgang stehen und
>> der übertragung sollte nichts mehr im wege stehn.

Zum ersten Teil: Das gilt natürlich nur, wenn Du irgendwo ein
#define SPI_DDR DDRB
stehen hast (und auch wirklich PORTB bzw. dessen Pins PB4 = /SS, PB5 = 
MOSI, PB6 = MISO und PB7 = SCK nutzt).

Zum zweiten Teil wurde schon was gesagt.
Die Tabelle lautet:

PIN        Direction, Master SPI      Direction, Slave SPI

MOSI       User defined               Input
MISO       Input                      User defined
SCK        User defined               Input
/SS        User defined               Input

Also schau Dir nochmal die Bedeutung/Folgen Deiner SPI_DDR-Anweisung an 
(sofern Du mit der SPI-Schnittstelle auch mal was empfangen willst).

When configured as a Master, the SPI interface has no automatic control 
of the SS line. This must be handled by user software before 
communication can start.

DATA_H und DATA_L hast Du vermutlich als uint16_t definiert, könntest 
zum RAM-Sparen aber auch uint8_t nehmen und nur mit 0xFF verUNDen. Müßte 
aber sowieso ein Problem geben, wenn Du SPDR (8 bit) einen 16 bit Wert 
(DATA_x) übergeben willst ohne zu casten.

Am besten noch mal in aller Ruhe das Datenblatt lesen (SPI ist ja zum 
Glück wirklich nicht viel). Wie auch schon gesagt wurde, solltest Du die 
SPI_Init-Funktion separat lassen und eine SPI_Transmit-Funktion separat 
haben.

Du schriebst "Oszilloskop und Endlosschleife", weshalb ich ein zu 
schnelles Senden ohne ein Pause zum Pegelmessen ohne Oszilloskop mal 
ausschließe.

von Sebastian B. (sebastian86)


Lesenswert?

Guten Tag zusammen,

Ich habe jetzt mal ne Nacht drüber geschlafen und  bin den Code nochmal 
durch gegangen und mir ist aufgefallen das MISO NICHT auf eingang 
geschaltet hatte.
Und der Fehler hatte sich so ereignet und zwar steht im Datenblatt das:
1
void SPI_MasterInit(void)
2
{
3
/* Set MOSI and SCK output, all others input */
4
DDR_SPI = (1<<DD_MOSI)|(1<<DD_SCK);
5
/* Enable SPI, Master, set clock rate fck/16 */
6
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
7
}

Das hatte dann bei mir nicht funktioniert, ich habe dann auch hier im 
Forum gelesen das der /SS-Pin(PB4) als Ausgang geschaltet werden muss 
und ich habe dann um sicher zu gehen (aus Verzweilung ;)) einfach nen 
0xFF ins DDRB geschoben, aber damit habe ich mir dann der Fehler gebaut 
weil MISO dann auchn Ausgang ist. Somit läuft die SPI nicht.
Aber vielen Dank für die Hilfe nun läufts ;)

Achja - Die Initialisierung in die Transmit schleife zu packen war auch 
nur eine Verzweiflungstat weil ich nicht mehr den überblick darüber 
hatte ob VIELEICHT irgendwas am PortB rumgurkt und mir so die SPI 
abschaltet.

Die SPI initialisierung wird gleich in eine eigene Funktion gepackt.


Gruß

Sebastian

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.