Hallo allerseits,
ich möchte gerne Daten übertragen zwischen einem Mega16 und einem Mega88
per SPI.
Um die Übertragung robust zu halten, packe ich nur 4 Datenbits je
übertragenem Byte und die vorderen Bits enthalten eine um 4 Bit
verschobene Adressierung der Nibbles. Das merke ich nur mal an, für den
Fall dass jemand den Beispielcode zu seltsam findet, ist eigentlich auch
nicht relevant.
In der Hauptschleife prüfe ich im (MasterSPI)AVR-Programm, ob die
Übertragung fertig ist, wenn nicht mache ich andere Sachen und komme
beim nächsten Durchlauf wieder.
Da ich noch eine UART-Verbindung zum PC habe, schreibe ich zu
DEBUG-Zwecken noch Bytes in den Ausgabe-Buffer (Antwort[11] - [15] habe
ich dafür noch frei).
1 | Antwort[11] = spi_pointer;
|
2 | Antwort[15]++;
|
3 | if (! (SPSR & (1<<SPIF)) )
|
4 | {
|
5 | Antwort[14] = SPSR;
|
6 | Antwort[12] ++;
|
7 |
|
8 | PORTB |= (1<<PB4);
|
9 | uint8_t data = 0;
|
10 | switch(spi_pointer)
|
11 | {case 0:
|
12 | data = TranferDaten[ TransferBank ][ 0 ] & 0x0f;
|
13 | break;
|
14 | case 1 :
|
15 | data = (1 << 4) + ((TranferDaten[ TransferBank ][ 1 ] << 4) & 0x0f);
|
16 | break;
|
17 | case 2 :
|
18 | data = (2 << 4) + (TranferDaten[ TransferBank ][ 1 ] & 0x0f);
|
19 | break;
|
20 | case 3 :
|
21 | data = (3 << 4) + ((TranferDaten[ TransferBank ][ 2 ] << 4) & 0x0f);
|
22 | break;
|
23 | case 4 :
|
24 | data = (4 << 4) + (TranferDaten[ TransferBank ][ 2 ] & 0x0f);
|
25 | break;
|
26 | case 5 :
|
27 | data = (5 << 4) + ((TranferDaten[ TransferBank ][ 3 ] << 4) & 0x0f);
|
28 | break;
|
29 | case 6 :
|
30 | data = (6 << 4) + (TranferDaten[ TransferBank ][ 3 ] & 0x0f);
|
31 | break;
|
32 | case 7 :
|
33 | data = (7 << 4) + ((TranferDaten[ TransferBank ][ 4 ] << 4) & 0x0f);
|
34 | break;
|
35 | case 8 :
|
36 | data = (8 << 4) + (TranferDaten[ TransferBank ][ 4 ] & 0x0f);
|
37 | break;
|
38 | default :
|
39 | break;
|
40 | }
|
41 | PORTB &= ~(1<<PB4);
|
42 | SPDR = data;
|
43 |
|
44 | Antwort[14] = data;
|
45 |
|
46 | spi_pointer++;
|
47 | if (spi_pointer > 8)
|
48 | {TransferBank = 1 - TransferBank;
|
49 |
|
50 | Antwort[13]++;
|
51 |
|
52 | spi_pointer = 0;
|
53 | }
|
54 | }
|
Der SPI wird initialisiert mit:
1 | DDRB = (1<<PB4)|(1<<PB5)|(1<<PB7); // MOSI,SCK,/SS
|
2 | PORTB = 0; // /SS löschen => SPI im Slave einschalten
|
3 | // set 'Enable SPI', set Master, set SPI clock rate fck/64
|
4 | SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR1);
|
Mit der Geschwindigkeit bin ich schon auf fck/64 runter von fck/16.
Nun lasse ich mir die Ausgabe am PC vom UART ausdrucken, da sieht man
dann als Hex-Wert:
xx = fortlaufend.
Also steht der spi_pointer auf 0, es sind 9 Bytes übertragen, einmal
wurde spi_pointer zurückgesetzt, 128(0x80) kam als letztes Byte aus dem
SPI(mir egal), das letzte Byte zählt ständig hoch, natürlich schneller
als der UART das ausgeben kann.
Es kann auch schon mal vorkommen, dass spi-pointer bei 1 stehen bleibt,
entsprechend wurden dann 10 Bytes gesendet.
MISO,MOSI,SCK und SS sind jeweils mit 1kOhm mit dem jeweiligen Port am
anderen AVR verbunden, SS ist am SPI-Master ein Ausgang, und ich schalte
ihn extra vor jeder Übertragung auf 0 um den SPI auf Slave-Seite
anzuschalten.
Sonderbar auch, dass ich mit
1 | if (! (SPSR & (1<<SPIF)) )
|
auf die Negation hin prüfe, eigentlich müsste ich ja auf ein gesetztes
SPIF weitersenden können !?! Wenn ich die Negation weglasse überträgt
das Programm garnichts.
Ich habe keine Ahnung, warum das Programm mit der Übertragung aufhört.
Sieht jemand den Fehler?
Gruß,
Olaf