Fragen zu SPI mit AVR

#7044108
Lesenswert?

Hallo zusammen,
ich versuche gerade SPI auf meinem Atmega1284p zum laufen zu bekommen. 
Ich habe das Datenblatt gelesen, allerdings hilft es mir nicht wirklich 
weiter.
Im Datenblatt wird erklärt, wie man ein Byte schickt, aber wie genau ist 
das Vorgehen, wenn ich mehr als ein Byte schicken will, zum Beispiel ein 
Byte Adresse und ein Byte Daten. Setze ich zwischen die einzelnen 
"Übertragungen" ein Delay?
Wenn ja, wie lang?
Im Datenblatt steht habe ich leider nur diesen Beispielcode gefunden:
1
void SPI_MasterTransmit(char cData){
2
/* Start transmission */
3
SPDR = cData;
4
/* Wait for transmission complete */
5
while(!(SPSR & (1<<SPIF)));
6
}
Dazu muss ja noch Slave select auf low gelegt werden.
Hat jemand ein Stück Beispielcode für mich?
Gruß David
#7044135
Lesenswert?

Hallo,

dein gezeigter Code macht das schon.

SPDR ist das SPI Datenregister für Bytes.

Und die Zeile sorgt dafür das es erst weiter geht wenn das SPDR wieder 
leer ist, also gesendet wurde und bereit ist für die Aufnahme des 
nächsten Bytes. Einen Buffer gibts nicht.
1
while(!(SPSR & (1<<SPIF)));

und vorher konfigurierst du das SPI Modul noch wie benötigt, Bsp.
1
//     enable SPI,   LSB first,      Master,       fck/4
2
SPCR = (1 << SPE) | (1 << DORD) | (1 << MSTR);
3
SPDR = 0;   
4
sei();

Und vorm Datentransfer Chip Select auf Low und wenn alle Daten gesendet 
sind und SPDR leer wieder auf High.
#7044307
Lesenswert?

Leider funktioniert es immer noch nicht.
Zur Initialisierung mache ich das:
1
DDRB |=  (1<<PB1)| (1<<PB5)| (1<<PB7);
2
PORTB |= (1<<PB1); //pull CS high
3
SPCR = 0b01010000;
4
_delay_ms(100);

Weiter unten im Code folgt:
1
while(1){
2
    
3
    
4
    PORTB &=~(1<<PB1);
5
    _delay_us(100); //wait vor cs to be low
6
    PORTD=0;    //turn off leds for diagnostic purposes
7
    _delay_ms(100);
8
    SPDR=0x81; //send register
9
    while (!(SPSR &(1<<SPIF)));    
10
    SPDR=0x00;    //send data
11
    while (!(SPSR &(1<<SPIF)));
12
    PORTD=0xFF; //turn on leds for diagnostic purposes
13
    PORTB|= 1<<PB1;
14
    
15
    _delay_ms(1000);
16
    
17
  }

Der Atmega kommt gar nicht erst bei der Zeile : PORTD=0xFF; an.
Gast #7044335
Lesenswert?

David P. schrieb:
> Und wie spreche ich dann 2 verschiedene slaves an?

Nacheinander oder gleichzeitig.
Wenn du die Slaves nacheinander ansprechen willst, braucht jeder sein 
eigenes CS-Signal. Wenn du die Slaves in Serie schaltest (Daisy-Chain), 
brauchst du nur eins, aber die Slaves müssen die Daten immer 
durchreichen.
Gast #7044338
Lesenswert?

Es heißt ja nur, dass B4 ein Ausgang sein muss, damit der SPI-Master 
nicht (versehentlich) in den Slave-Modus geschaltet wird. B4 braucht 
nicht notwendigerweise eine CS-Funktionalität zu haben, auch wenn dies 
im Regelfall sinnvoll ist.
Gast #7044343
Lesenswert?

Wolfgang schrieb:
> David P. schrieb:
>> Und wie spreche ich dann 2 verschiedene slaves an?
>
> Nacheinander oder gleichzeitig.
> Wenn du die Slaves nacheinander ansprechen willst, braucht jeder sein
> eigenes CS-Signal. Wenn du die Slaves in Serie schaltest (Daisy-Chain),
> brauchst du nur eins, aber die Slaves müssen die Daten immer
> durchreichen.

Es ist aber sinnvoller, es mit 2 CS-Signalen zu machen (keine 
Daisy-Chain), da Du dann unabhängiger bist; und es müsste doch noch ein 
Ausgang als 2.tes CS Signal zur Verfügung stehen

NB - was willst Du per SPI ansteuern?
Gast #7044372
Lesenswert?

Heiner schrieb:
> Es ist aber sinnvoller, es mit 2 CS-Signalen zu machen (keine
> Daisy-Chain), da Du dann unabhängiger bist;

Das kommt sehr auf den Anwendungsfall an.
Wenn es z.B. darum geht, ein paar mehr LEDs per 74hc595 anzusteuern, ist 
Daisy-Chain ausgesprochen sinnvoll. Genauso sieht es aus, wenn du 
irgendwelche Eingänge über PISO-Schieberegister einlesen willst. 
Unabhängigkeit macht die Sache in so einem Fall nur komplizierter.

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