www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik SPI-Datenübertragung Problem /SS-Leitung


Autor: Alexander Liebhold (lippi2000)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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.
#define F_CPU 16000000L                    //CPU-Frequenz
#define BAUD 9600L                      //Baudrate
#define UBRR_VAL ((F_CPU+BAUD*8)/(BAUD*16)-1)        //Runden für Prescaler
#define BAUD_REAL (F_CPU/(16*(UBRR_VAL+1)))          //reale Baudrate
#define BAUD_ERROR ((BAUD_REAL*1000)/BAUD-1000)        //Fehler in Promille
//Compilerausgabe bei Fehler
#if ((BAUD_ERROR>10)||(BAUD_ERROR<-10))
#error Systematischer Fehler der Baudrate ist größer 1% und damit zu hoch!
#endif



#include<avr/io.h>
#include<avr/interrupt.h>

unsigned char temp=0;


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

 //Hauptprogramm
 UCSRB = (1<<RXCIE)|(1<<RXEN)|(1<<TXEN);            //RX-IRQ enable;TX & RX enable
 sei();
 while(1);
   {};

 };


ISR(USART_RXC_vect)
{cli();
 PORTB &= ~(1<<PORTB2);                      //slave select = low
 SPDR=UDR;                            //daten von RS232 an SPI schreiben
                         
 while(PINB&(1<<PINB0))                      //warte auf ACK = low
      {};
 while(!(PINB&(1<<PINB0)))                    //warte auf ACK = high
      {};
 SPDR=0x00;
 while(!(SPSR & (1 << SPIF)));      //Warte bis daten gesendet 
 
 PORTB |=(1<<PORTB2);
 UDR = SPDR;                          //daten von SPI an RS232 schreiben
 while(!(UCSRA&(1<<UDRE)))                    //TxD complete
           {};
 sei();
}

Anbei noch eine Messung...siehe data2 da sollte /SS noch low sein.

Autor: Deejay (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Alexander Liebhold (lippi2000)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.
ISR(USART_RXC_vect)
{cli();
 PORTB &= ~(1<<PORTB2);                      //slave select = low
 SPDR=UDR;                            //daten von RS232 an SPI schreiben
                         
 while(PINB&(1<<PINB0))                      //warte auf ACK = low
      {};
 while(!(PINB&(1<<PINB0)))                    //warte auf ACK = high
      {};
 temp=SPSR;
 temp=SPDR;
 SPDR=0x00;
 while(!(SPSR & (1 << SPIF)));
 
 PORTB |=(1<<PORTB2);
 UDR = SPDR;                          //daten von SPI an RS232 schreiben
 while(!(UCSRA&(1<<UDRE)))                    //TxD complete
           {};
 sei();
}

So geht's jetzt.

Trotzdem Danke.

Autor: Daniel J. (deejay)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

also in dem Datenblatt, dass ich kenne, steht das genau so drin ;-)
Aber freut mich, dass es jetzt geht.

Bye
 Deejay

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.