Seltsamer Takt bei Hardware SPI

Gast #3743161
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
Angehängte Dateien:
Gast #3743200
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
Gast #3743218
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
}
Angehängte Dateien:
#3743234
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.
Moderator Persönliche Seite #3744900
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).

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren