SPI-Datenübertragung Problem /SS-Leitung

OP #965662
Hallo,
habe eine SPI-Master-Slave Schnittstelle zwischen zwei AVR aufgebaut.

Die Daten für den Master (ATMega8) kommen von der RS232 und sollen an 
den Slave (ATMega32) versendet werden. Damit der Master weiß, wann die 
Ausführung am Slave abgeschlossen ist und ein datenbyte zurückgelesen 
werden kann, habe ich eine zusätzliche /ACK-Leitung eingebaut. Diese ist 
für 50us LOW und wechselt dann wieder auf HIGH. Anschließend schreibt 
der Master eine 0x00 an den Slave um die Antwortdaten über MISO zu 
empfangen.

Nun mein Problem: Der Master erkennt nicht wann er die 8Bit übertragen 
hat und nimmt dann zu früh das /SS zurück.
1
#define F_CPU 16000000L                    //CPU-Frequenz
2
#define BAUD 9600L                      //Baudrate
3
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)        //Runden für Prescaler
4
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))          //reale Baudrate
5
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000)        //Fehler in Promille
6
//Compilerausgabe bei Fehler
7
#if ((BAUD_ERROR>10)||(BAUD_ERROR<-10))
8
#error Systematischer Fehler der Baudrate ist größer 1% und damit zu hoch!
9
#endif
10

11

12

13
#include<avr/io.h>
14
#include<avr/interrupt.h>
15

16
unsigned char temp=0;
17

18

19
int main(void)
20
{PORTB = (1<<PORTB2)|(1<<PORTB0);                //PB0,PB2 ist 1
21
 DDRB = 0x2C;                          //SCK,MOSI,/SS = Ausgang
22
  //UART Initialisierung
23
 UCSRC = (1<<URSEL)|(1<<USBS)|(3<<UCSZ0);            //8 Bit + 2 Stoppbit
24
 UBRRL = UBRR_VAL;                        //Baudrate setzen
25
 UBRRH = (UBRR_VAL>>8);
26
 //SPI-Initialisierung
27
 SPSR = (0<<SPI2X);
28
 SPCR = (1<<SPE)|(1<<MSTR)|(2<<SPR0);              //SPI-Mode 0; 250kHz
29
  
30

31
 //Hauptprogramm
32
 UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);            //RX-IRQ enable;TX & RX enable
33
 sei();
34
 while(1);
35
   {};
36

37
 };
38

39

40
ISR(USART_RXC_vect)
41
{cli();
42
 PORTB &= ~(1<<PORTB2);                      //slave select = low
43
 SPDR=UDR;                            //daten von RS232 an SPI schreiben
44
                         
45
 while(PINB&(1<<PINB0))                      //warte auf ACK = low
46
      {};
47
 while(!(PINB&(1<<PINB0)))                    //warte auf ACK = high
48
      {};
49
 SPDR=0x00;
50
 while(!(SPSR & (1 << SPIF)));      //Warte bis daten gesendet 
51
 
52
 PORTB |=(1<<PORTB2);
53
 UDR = SPDR;                          //daten von SPI an RS232 schreiben
54
 while(!(UCSRA&(1<<UDRE)))                    //TxD complete
55
           {};
56
 sei();
57
}

Anbei noch eine Messung...siehe data2 da sollte /SS noch low sein.
Angehängte Dateien:
Gast
Hi,

versuch mal das Flag SPIF im Register SPSR zurückzusetzen, bevor Du mit 
der While-Schleife auf das Ende der Übertragung wartest. Was genau Du 
zum Zurücksetzen tun musst, findest im Datenblatt bei der Beschreibung 
des Flags.

Bye
  Deejay
OP
Danke, habs gerade gefunden.
Im Datenblatt ist nichts genaues geschrieben. In ner APP von Atmel steht 
drinne, dass man erst SPSR und dann SPDR auslesen muss um das Flag zu 
löschen.
1
ISR(USART_RXC_vect)
2
{cli();
3
 PORTB &= ~(1<<PORTB2);                      //slave select = low
4
 SPDR=UDR;                            //daten von RS232 an SPI schreiben
5
                         
6
 while(PINB&(1<<PINB0))                      //warte auf ACK = low
7
      {};
8
 while(!(PINB&(1<<PINB0)))                    //warte auf ACK = high
9
      {};
10
 temp=SPSR;
11
 temp=SPDR;
12
 SPDR=0x00;
13
 while(!(SPSR & (1 << SPIF)));
14
 
15
 PORTB |=(1<<PORTB2);
16
 UDR = SPDR;                          //daten von SPI an RS232 schreiben
17
 while(!(UCSRA&(1<<UDRE)))                    //TxD complete
18
           {};
19
 sei();
20
}

So geht's jetzt.

Trotzdem Danke.

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 18 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.