Forum: Mikrocontroller und Digitale Elektronik Senden/Empfangen mehrerer Bytes über SPI


von Chris Sch. (Gast)


Lesenswert?

Hallo zusammen,

ich sitze vor dem Problem mehrere Bytes von AVR zu AVR zu übertragen. 
Ein Byte stellt kein Problem da, jedoch möchte ich mehrere Bytes 
hintereinander senden.

Senden:
8 Bit Timerinterrupt/ Prescaler 1024; Überlauf startet Datentransfer
Werte werden in Register gespeichert
Starten der Übertragung durch SS = low
Inhalt ins Übertragungsregister schieben
Warten bis Übertragung fertig
SS auf low halten
Inhalt ins Übertragungsregister schieben
Warten bis Übertragung fertig
SS auf low halten
...
...
...
SS auf high um Transfer zu beenden


Hier mein Code:
1
Timer0_OVF:
2
SPI_Transfer:  
3
  push      temp
4
  push      temp1  
5
6
  
7
  ldi       temp,      0x70        //    Testwert Low
8
  ldi       temp,      0x30        //    Testwert High
9
10
11
SPI_Transfer1:
12
  cbi       PORTB,       PB4         //    Low SS startet Übertragung
13
  out       SPDR,        temp        //    Low ins Register
14
Test_Wait_Transmit_1:                //    temp = Testwert Low
15
  sbis      SPSR,        SPIF        //
16
  rjmp      Test_Wait_Transmit_1     //
17
18
19
  out        SPDR,      temp1
20
Test_Wait_Transmit_2:
21
  sbis      SPSR,       SPIF
22
  rjmp      Test_Wait_Transmit_2
23
24
  
25
  sbi        PORTB,      PB4          //    SS High endet Übertragung
26
27
  pop        temp1
28
  pop        temp
29
30
  reti



Empfänger:
SS = low löst Interrupt Routine aus
Register Sichern
Warten bis Übertragung Fertig ist
Daten ins Register
Warten bis Übertragung Fertig ist
Daten ins Register
...
...
Register ins SRAM

Hier mein Code:
1
SPI_Transfer:    
2
  
3
  push    temp
4
  push    temp1
5
  push    temp2
6
  in       temp2, SREG       ; muss natürlich temp gesichert werden
7
8
9
10
SPI_Transfer_1:
11
; Wait for reception complete
12
  sbis     SPSR,        SPIF
13
  rjmp     SPI_Transfer_1
14
; Read received data and return
15
  in       temp,        SPDR
16
17
18
19
SPI_Transfer_2:
20
; Wait for reception complete
21
  sbis     SPSR,        SPIF
22
  rjmp     SPI_Transfer_2
23
; Read received data and return
24
  in       temp1,        SPDR
25
26
27
  sts      X_Soll_low,      temp
28
  sts      X_Soll_high,    temp1
29
30
31
  out     SREG, temp2       
32
  pop     temp2 
33
  pop     temp1
34
  pop     temp
35
  reti


Es stellt sich mir die Frage ob es überhaupt Sinnvoll ist die Daten in 
einer Interruptroutine zu senden. Die Daten per Interrupt zu Empfangen 
finde ich ganz elegant gelöst.

Ich habe dafür im Netz keine Hilfe gefunden, nur einen C Code der 
ähnliche Probleme hatte. Ich freue mich über Antworten.

von Matthias L. (Gast)


Lesenswert?

>Empfänger:
>SS = low löst Interrupt Routine aus

Ich wurde das SS nicht für den INt nehmen.

Der Sender ist schon korrekt. Beginn der Übertragung mit SS=LOW 
einleiten, Bytes senden, SS=HIGH ALs Ende-Markierung.

Beim Empfänger würde ichs so machen:

Es gibt nen Empfangszähler, rx_cnt genannt, der wird beim Aufstarten 
genullt.

Jetzt ist der SPI-BYTE-ist-empfangen-Interrupt freigeschaltet. Immer 
wenn dieser anspringt, kam ein Byte rein. Das kommt in ein Array:
1
rx_array[ rx_cnt++ ] = SPDR;
2
if ( ss == high )
3
{
4
  // Übertragung beendet, mach was mit den rx_cnt-Bytes.
5
  // danach:
6
  rx_cnt=0;
7
}

von Chris Sch. (Gast)


Lesenswert?

Danke für deine Antwort, hat mir den nötigen Denkanstoß gegeben. Meine 
Empfänger Routine war falsch. Natürlich wird nur dann der Interupt 
ausgeführt wenn ein Zeichen angekommen ist. Darauf in der Interupt 
Routine zu warten ist sinnlos :D

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.