spi zwischen zwei AVRs überträgt nur wenige Bytes

Gast #2197762
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:
1
00 09 01 80 xx
 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
Meiermann schrieb:
> 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 !?!

Richtig, und das dürfte auch die Ursache deines Problems sein.

Meiermann schrieb:
> Wenn ich die Negation weglasse überträgt
> das Programm garnichts.

Ja, weil du erst mal was übertragen musst, bevor das Flag das erste Mal 
gesetzt wird.
Gast
Stimmt.

Ein SPDR = 0; vor der Hauptschleife löst das Probelm.
Dabei dachte ich, diese Möglichkeit hätte ich schon durchprobiert, aber 
wohl nur mit Negation statt nun ohne - perfekter Programmlauf.

Danke dafür.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 15 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.