Hallo, ich möchte einen Attiny841 als SPI Slave nutzen, der reagieren
soll, sobald sich etwas auf dem SPI Bus tut. Jedoch finde ich im
Datenblatt kein Register, welches für den SPI Interrupt zu nutzen ist.
"21 0x0014 SPI SPI Serial Transfer Complete" ist was anderes.
Herman Uh. schrieb:> Hallo, ich möchte einen Attiny841 als SPI Slave nutzen, der reagieren> soll, sobald sich etwas auf dem SPI Bus tut.
Wenn du mit 'sobald sich etwas tut' meinst 'sobald der Master mit seinen
Clock Pulsen anfängt', dann gibt es da auch nichts dazu.
Das einzige was es gibt, ist der Interrupt, so wie er in deinem
Codeausschnitt ohnehin schon drinn ist, der feuert, wenn ein Transfer
abgeschlossen ist.
Auszug aus dem Manual Seite 158:
-----------------------------------------------
SPSR – SPI Status Register
Bit 7 – SPIF: SPI Interrupt Flag
This bit is set when a serial transfer is complete. An interrupt is
generated if SPIE in SPCR is set and global interrupts are
enabled. If SS is an input and is driven low when the SPI is in Master
mode, this will also set the SPIF Flag. SPIF is
cleared by hardware when executing the corresponding interrupt handling
vector. Alternatively, the SPIF bit is cleared by
first reading the SPI Status Register with SPIF set, then accessing the
SPI Data Register (SPDR).
-----------------------------------------------
"This bit is set when a serial transfer is complete"
gilt für Senden und Empfangen ("transfer")
Normalerweise ist es bei den AVR so, dass nur weil man eine der
Alternativfunktionen für einen Pin aktiviert, die Basisfunktionalitäten
deswegen nicht abgeschaltet werden.
Abhängig welchen SCK Pin du benutzt, könntest du mal probieren, ob der
ganz normale PCINT3 bzw. PCINT4 Pin Change Interrupt (natürlich
flankengetrieben) da noch durchkommt.
Herman Uh. schrieb:> Ja das Problem ist, den Interrupt "SPI_STC_vect" gibt es beim Attiny841> scheinbar nicht.
? Warum soll es den nicht geben
Die Bits in den Konfigurationsregistern gibt es ja auch.
Der heisst vielleicht beim Tiny841 nur ein bischen anders.
ISR(SPI)
{
}
geht als Interrupt Vector nicht. avr/interrupt.h habe ich mit
eingebunden.
Warning 1 'SPI' appears to be a misspelled signal handler [enabled by
default]
Sieh dir mal die Dependency Liste in deinem Projekt an.
Dort müsste ein File namens iotn841.h aufgeführt sein (Oder so ähnlich.
Mein Studio kennt den Tiny noch nicht, drum kann ich nichts genaueres
sagen).
Machs auf und such nach "_vect". Irgendwo da drinn ist der korrekte Name
für den Interrupt Handler, wie er im gcc heisst.
Karl Heinz schrieb:> Sieh dir mal die Dependency Liste in deinem Projekt an.> Dort müsste ein File namens iotn841.h aufgeführt sein (Oder so ähnlich.> Mein Studio kennt den Tiny noch nicht, drum kann ich nichts genaueres> sagen).
Kann sein, dass das Header File auch anders heisst. Sein Name fängt
normalerweise jedenfalls mit "io" an.
Noch was:
Damit die Dependency List vollständig ist, musst du das Projekt
mindestens einmal compiliert haben. D.h. alles was Fehler wirft:
gnadenlos wegkommentieren. Es geht nur darum, dass der Compiler
durchkommt. Dann stimmt auch die Dependency List
Ach du Mist.
Du hast in deiner Überschrift ja das Stichwort 'Arduino' benutzt.
Na die IDE kann das nicht. Die ist dafür zu simpel gestrickt.
Da bleibt dir wohl nichts anderes übrig, als im Verzeichnis mit den
Include Files zu suchen, welches für den Tiny 841 passt. Ausser jemand
mit eine neuereren Atmel Studio als meines, erbarmt sich und sucht den
Namen raus.
Herman Uh. schrieb:> ISR(SPI)> {> }>> geht als Interrupt Vector nicht. avr/interrupt.h habe ich mit> eingebunden.>> Warning 1 'SPI' appears to be a misspelled signal handler [enabled by> default]
Probiers mal mit:
Karl Heinz schrieb:> Ach du Mist.> Du hast in deiner Überschrift ja das Stichwort 'Arduino' benutzt.> Na die IDE kann das nicht. Die ist dafür zu simpel gestrickt.
Ähm, gute Frage wieso da Arduino steht, dass sollte Attiny heißen.
SPI_vect ist in den h-Files vorhanden gewesen
So, hab nun ein bisschen rumgetestet, es wird zumindest schon etwas
übermittelt. Nur noch nicht ganz so wie gewollt.
Zur Verdrahtung, die beiden Geräte sind wie folgt miteinander verbunden
1
1(M)-2(S)
2
SCK-SCK
3
MOSI-MOSI
4
SS-SS
Master
1
#include<avr/io.h>
2
#include<util/delay.h>
3
#include<avr/interrupt.h>
4
5
#define SPI_DDR DDRA
6
#define SPI_PORT PORTA
7
#define SPI_MOSI PORTA6
8
#define SPI_MISO PORTA5
9
#define SPI_SS PORTA7
10
#define SPI_SCK PORTA4
11
12
voidspi_master_init(void)
13
{
14
SPI_DDR|=(1<<SPI_SS)|(1<<SPI_MOSI)|(1<<SPI_SCK);//MOSI und SCK als Ausgang, Rest ist Eingang
15
SPCR=(1<<SPE)|(1<<MSTR)|(1<<SPR0);//Aktivierung des SPI, Master, Taktrate fck/16
while(!(SPSR&(1<<SPIF)));//warte, bis Transmission abgeschlossen ist
23
SPDR=g;//starte Transmission
24
while(!(SPSR&(1<<SPIF)));//warte, bis Transmission abgeschlossen ist
25
SPDR=b;//starte Transmission
26
while(!(SPSR&(1<<SPIF)));//warte, bis Transmission abgeschlossen ist
27
SPI_PORT|=(1<<SPI_SS);
28
}
29
30
intmain(void)
31
{
32
spi_master_init();
33
sei();
34
spi_master_transmit(0,0,0);
35
36
while(1)
37
{
38
39
_delay_ms(1000);
40
spi_master_transmit(255,0,0);// rot
41
_delay_ms(1000);
42
spi_master_transmit(0,255,0);// gruen
43
_delay_ms(1000);
44
spi_master_transmit(0,0,255);// blau
45
}
46
}
Slave
1
#include<avr/io.h>
2
#include<util/delay.h>
3
#include<avr/interrupt.h>
4
5
#define SPI_DDR DDRA
6
#define SPI_PORT PORTA
7
#define SPI_MOSI PORTA6
8
#define SPI_MISO PORTA5
9
#define SPI_SS PORTA7
10
#define SPI_SCK PORTA4
11
12
volatileuint8_tdata0=0xff;
13
volatileuint8_tdata1=0xff;
14
volatileuint8_tdata2=0xff;
15
volatileuint8_tdata_out=0;
16
17
voidspi_slave_init(void)
18
{
19
SPI_DDR|=(1<<SPI_MISO);
20
SPCR=(1<<SPE)|(1<<SPIE);
21
}
22
23
uint8_tspi_slave_receive(void)
24
{
25
while(!(SPSR&(1<<SPIF)));
26
returnSPDR;
27
}
28
29
ISR(SPI_vect)
30
{
31
data2=data1;
32
data1=data0;
33
data0=255-spi_slave_receive();
34
35
VAL_RED=data0;
36
VAL_GREEN=data1;
37
VAL_BLUE=data2;
38
}
39
40
intmain(void)
41
{
42
spi_slave_init();
43
sei();
44
while(1)
45
{
46
}
47
}
Im Master möchte ich mit 3 gesendeten 0en die Register data0 - data2
zurücksetzen. Danach sende ich im Sekundentakt die Werte für eine RGB
Led. Es soll einzeln rot, grün und blau blinken.
Jedoch geschieht das nicht. Es kommt dauerhaft zur Farbvermischung. Habe
ich was vergessen?
Herman Uh. schrieb:> Zur Verdrahtung, die beiden Geräte sind wie folgt miteinander> verbunden1(M) - 2(S)> SCK - SCK> MOSI - MOSI> SS - SS
Auf den ersten Blick fällt auf dass MOSI an MISO muss.