Forum: Compiler & IDEs Seltsamer Takt bei Hardware SPI


von Florian (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammmen,

ich stehe gerade vor einem seltsamen Problem. Ich versuche derzeit das 
Hardware SPI an einem ATmega328P zu laufen zu bringen. Habe das Beispiel 
aus dem Datenbaltt des uC übernommen, aber der Scan meines 
LogicAnalyzers zeigt mir dort wo eigentlich der Takt beim SPI sein 
sollte nur Quatsch an (siehe Bild). Auch mit verschiedenen Clock Rate 
Selects habe ich das selbe Phänomen.

Vielleicht kann mich einer von euch mit der Nase auf meinen Fehler 
stupsen?
1
#define F_CPU 16000000UL
2
3
#include <avr/io.h>
4
#include <util/delay.h>
5
6
void spi_init() {
7
  DDRB = (1<<PB3) | (1<PB5) | (1<<PB2); //MOSI,SCK,SS as output
8
  SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR1); //SPI Enable, master-mode
9
  //SPSR |= (1<<SPI2X); //Double Speed 8MHz
10
}
11
12
void spi_send_data(char data) {
13
  PORTB &= ~(1<<PB2); //SS to low
14
  SPDR = data;
15
  while(!(SPSR & (1<<SPIF)));
16
  PORTB |= (1<<PB2); //SS to high
17
}
18
19
int main(void)
20
{
21
spi_init();
22
    while(1)
23
    {
24
        spi_send_data(0x02);
25
    _delay_ms(200);
26
    }
27
}

MFG Florian

von Stefan E. (sternst)


Lesenswert?

Du denkst, du hättest den SCK-Pin auf Ausgang konfiguriert, hast du aber 
in Wirklichkeit nicht. ;-)

von Florian (Gast)


Lesenswert?

Hallo,

danke schon mal für die Antwort, aber irgendwie verstehe ich das nicht 
ganz. Setze ich nicht die Art eines Pins, und damit ob er ein Ausgang 
oder Eingang ist, mit dem DDR des jeweiligen Ports?

MFG Florian

von René K. (cyprius)


Lesenswert?

Florian schrieb:
> Hallo,
>
> danke schon mal für die Antwort, aber irgendwie verstehe ich das nicht
> ganz. Setze ich nicht die Art eines Pins, und damit ob er ein Ausgang
> oder Eingang ist, mit dem DDR des jeweiligen Ports?
>
> MFG Florian

Guck dir die Zeile für das Portregister noch mal gaaaaanz genau an..

von Stefan E. (sternst)


Lesenswert?

Florian schrieb:
> Setze ich nicht die Art eines Pins, und damit ob er ein Ausgang
> oder Eingang ist, mit dem DDR des jeweiligen Ports?

Ja, aber du hast an Port B die Pins 0, 2 und 3 auf Ausgang geschaltet, 
und SCK ist Pin 5.

von Florian (Gast)


Angehängte Dateien:

Lesenswert?

Ohh Mann! Ich bin fast verzweifelt und dann sowas.

Vielen dank!

Zur Vollständigkeit nochmal der jetzt lauffähige Code
1
#define F_CPU 16000000UL
2
3
#include <avr/io.h>
4
#include <util/delay.h>
5
6
void spi_init() {
7
  DDRB = (1<<PB3) | (1<<PB5) | (1<<PB2); //MOSI,SCK,SS as output
8
  SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR1); //SPI Enable, master-mode
9
  //SPSR |= (1<<SPI2X); //Double Speed 8MHz
10
}
11
12
void spi_send_data(char data) {
13
  PORTB &= ~(1<<PB2); //SS to low
14
  SPDR = data;
15
  while(!(SPSR & (1<<SPIF)));
16
  PORTB |= (1<<PB2); //SS to high
17
}
18
19
int main(void)
20
{
21
  spi_init();
22
    while(1)
23
    {
24
        spi_send_data(0x02);
25
    _delay_ms(200);
26
    }
27
}

von Kai S. (hugstuart)


Lesenswert?

Du setzt den SS-Pin manuell auf high bzw. low. Sollte das der uC nicht 
automatisch machen?

von Florian S. (snairolf)


Lesenswert?

Hab mich jetzt mal angemeldet. Ist doch ein wenig einfacher dann.

Kai S. schrieb:
> Du setzt den SS-Pin manuell auf high bzw. low. Sollte das der uC nicht
> automatisch machen?

Kann er ja gar nicht. Da du am SPI mehr als nur einen Slave haben 
kannst, musst du im Programm entscheiden mit welchem du gerade 
kommunizieren willst. Das kann der uC von alleine gar nicht wissen.

von asdf (Gast)


Lesenswert?

Wobei es durchaus auch Controller gibt wo man CS# per Hardware toggeln 
lassen kann (per Register-Settings konfigurierbar welches von den X 
möglichen CS# Signalen verwendet werden soll).

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

asdf schrieb:
> Wobei es durchaus auch Controller gibt wo man CS# per Hardware toggeln
> lassen kann

Hat aber nur begrenzten Wert: in aller Regel benötigen
SPI-Transaktionen, dass man /CS am Anfang der Transaktion
aktiviert, dann N Bytes für die Transaktion austauscht, und am Ende
dann /CS wieder deaktiviert.   Da die Anzahl der Bytes pro
Transaktion variieren kann, wird dann schnell die Soße teurer als
das Fleisch, wenn man versucht, das irgendwo in der Hardware zu
konfigurieren.  Kommt hinzu, dass das Setzen oder Löschen einer
Ausgabeleitung beim AVR vergleichsweise „billig“ ist (wenig Code,
wenig Takte).

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.