www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik ATmega8: Grundlagen SPI


Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Profis,

ich hab mal wieder ein Grundlagenproblem:

Und zwar habe ich anhand des Datenblatts vom ATmega8 und einiger Threads 
dieses Forums den Controller nun so weit gebracht, dass er sendet.

Der Code:

********************************************************************

//HAUPTPROGRAMM
int main (void)
{
  SPI_MasterInit();
  sei();

  for(;;)
  {
    SPI_MasterTransmit(0xff);
    _delay_us(20);
    SPI_MasterTransmit(0x00);
    _delay_us(20);
  }

  return 0;
}




//Funktionen

void SPI_MasterInit(void)
{
/* Set MOSI and SCK output, all others input */
DDRB |= (1<<PB2) | (1<<PB3) | (1<<PB5);

/* Enable SPI, Master, set clock rate fck/16 */
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
}


void SPI_MasterTransmit(char cData)
{
/* Start transmission */
SPDR = cData;
/* Wait for transmission complete */
while(!(SPSR & (1<<SPIF)))
;
}

***********************************************************************

Nun meine Frage:

Ich will SPI nutzen, um einen Sensor auszulesen. Dazu muss erst ein char 
an den Sensor gesendet werden, damit dieser weiß was ich von ihm will. 
Anschließend sendet dieser ein 11Bit-Wort zurück an den Controller.

Nur: Wie empfange ich?? Vor allem ein 11Bit-Wort.

Danke für Eure Hilfe.

Gruß

Tom

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ist das so eine blöde Frage??

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Was ist mit dem /SS Signal. Benötigst du eins?
P.S. Is das ein VTI Sensor????

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So nochmal. Hatte das Problem auch mal mit nem VTI Sensor. Wenn der vom 
Sensor ein 11Bit Signal bekommen hat habe ich zuerst einen 8Bit Befehl 
gesendet und im Anschluss 2 Dummybytes gesendet (0x00). Die ausbleibende 
Frequenz war dem Sensor egal, da er seinen Takt vom Controller bekommen 
hat. Zwischen den Dummybefehlen natürlich den Speicher auslesen.

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja, es ist ein Sensor von VTI. Und zwar der SCA1000. Dieser wird dann in 
der Prototypenphase durch den SCA61T getauscht. Ich hoffe jedoch, dass 
beide identische Werte über SPI senden/erwarten.

Verwendest Du ähnliche Sensoren?

Bzgl. /SS:

Muss ich erst PB2 (also /SS) auf Low, dann senden und dann auf Antwort 
vom Sensor warten?

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Gast,

könntest Du mir das evtl etwas genauer erklären mit den Dummybytes?

Heißt das:

- 8Bit Kommando
- 1. Dummybyte
- Speicher auslesen
- 2. Dummybyte
- Speicher auslesen

Oder verstehe ich das falsch?

Autor: Michael Wilhelm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn der Mega8 als Master fungiert, kannst du einen X-beliebigen Portpin 
nehmen. Als Slave allerdings wird durch externes Low-ziehen des SS-Pins 
die Empfangsroutine angeworfen.

MW

Autor: Bruno (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich hatte den SCA100T.

1. /SS auf low (so war es bei mir mußte im Datenblatt gucken ob high 
oder low)
2. 8Bit-Befehl senden
3. Dummybyte 0x00 senden
4. Empfangsspeicher auslesen
5. Dummybyte 0x00 senden
6. /SS auf high

So war das bei mir. Habe leider kein Codebeispiel zur Hand, kann das 
aber heute Abend nachlegen bei Bedarf.

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Gast,

das wäre echt super nett von Dir, wenn ich den Code bekommen könnte. Es 
sind nämlich (fast) identische Sensoren.

Nun die vielleicht blödeste aller Fragen:

Wie sieht die Funktion fürs Empfangen aus und wo/was ist der 
Empfangsspeicher?

Vielen Dank und

Beste Grüße

Tom

Autor: Michael Wilhelm (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Empfangsspeicher ist das SPDR.

MW

Autor: Bruno (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Einfach das Register auslesen und feddich. Mußt event noch die SPI 
danach wieder freischalten (Flags)??!!?? Das weiß ich aber nicht so 
genau. Atmel is schon zu lange her. Werde den Code später mal posten.

Autor: Bruno (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Anbei wie versprochen der Code für den SCA100T

int read_x_channel(void)
{
short x1,x2;
int x3, xGes;

 PORTB = (0 << PB0);                   //SS auf low setzen
 SPDR = 0x10;                          //Befehl read X-Channel in SPDR
 while(!(SPSR & (1<<SPIF)));          //Warten bis Empfangsende
 x1 = SPDR;                            //Wert x1 aus DR wird gespeichert
 x3 = x1<<3                            //x1 wird um 3 verschoben
 SPDR = 0x0c;             //Dummybyte
 while(!(SPSR & (1<<SPIF)));           //s.o.
 x2 = SPDR;               //Wert x2 aus DR wird gespeichert
 x2 = x2 >> 5;    //x2 wird korregiert/ Verschieben um 5 Stellen
                       
 xGes = x3 + x2;           //Endwert wird berechnet    
 PORTB = (1 << PB0);                   //SS auf high setzen                 
 
 return (xGes);              //Endwert wird zurück gegeben
}                      

Nicht schön aber läuft

Autor: Kai Franke (kai-) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
oder du machst das ganze über Software SPI, dann kannst du tatsächlich 
genau 11 Bit auslesen, aber wie heißt es so schön: "Never change a 
working system"

Autor: Tom (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

nochmals vielen Dank für Eure Hilfe. Heute hab ich den neuen Sensor 
bekommen (SCA61T) mit folgendem Code will ich dem an den Pelz:

***********************************************************************+

//HAUPTPROGRAMM
int main (void)
{
  SPI_MasterInit();
  sei();

  DDRD = 0xff;

  while(1)
  {
    short x1, x2;
    int x3, xGes;

    PORTB = (0 << PB2);    //SS auf Low
    SPDR = 0x10;  //Kommando "Read X-Channel" in SPDR
    while(!(SPSR & (1<<SPIF)));  //Warten auf Empfangsende
    x1 = SPDR;  //Wert x1 aus SPDR auslesen
    x3 = x1>>3;  //x1 um drei Stellen verschieben
    SPDR = 0x0c;  //Dummybyte senden
    while(!(SPSR & (1<<SPIF))); //Warten auf Empfangsende
    x2 = SPDR; //Wert x2 aus SPDR auslesen
    //x2 = x2 >> 5; //Wert x2 um fünf Stellen verschieben
    xGes = x3 + x2; //Gesamtwert errechnen

    PORTB = (1<<PB2); // /SS auf High

    PORTD = x2;

    _delay_ms(50);
  }

  return 0;
}




//Funktionen

void SPI_MasterInit(void)
{
/* Set MOSI and SCK output, all others input */
DDRB |= (1<<PB2) | (1<<PB3) | (1<<PB5);

/* Enable SPI, Master, set clock rate fck/32 */
SPCR = (1<<SPE) | (1<<MSTR) | (1<<SPR1);
}

********************************************************************

Zur Visualisierung während den Tests will gebe ich immer ein Byte an 
PORTD aus (hier x2). x2 wird auch super ausgelesen, alles passt. Aber 
wenn ich x1 ausgebe, erhalte ich nur 1en. Was muss ich ändern, damit das 
funzt?

Beste Grüße

Tom

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.