mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik SPI Send Problem


Autor: Gerald (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hi,

ich sende daten über die spi schnittstelle wie folgt:

PSW_IEN = 0;      // Global Interrupt disable
SSC0_TB = command;    // send command with SPI interface
while (SSC0_CON_BSY == 0);  // wait until transmition starts
while (SSC0_CON_BSY == 1);  // while busy wait until transmition ready
response = SSC0_RB;
PSW_IEN = 1;

ich hab das problem das er manchmal in der ersten while schleife hängen 
bleibt -> while (SSC0_CON_BSY == 0);

wie kann das auftreten? ich schalte ja alle interrupts ab!!

der gepostete code wird im timer 2 interrupt ausgeführt!

lg

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gerald schrieb:
> ich hab das problem das er manchmal in der ersten while schleife hängen
> bleibt -> while (SSC0_CON_BSY == 0);
Ich würde sagen: die ist unnötig. Wenn schon, dann solte diese Abfrage 
vor das Beschreiben des SPI-Registers.
Aber warum schaust du dir nicht einfach mal an, wie andere das machen?

BTW: welcher uC?

Autor: Gerald (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Infineon XC164

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gerald schrieb:
> ich hab das problem das er manchmal in der ersten while schleife hängen
> bleibt -> while (SSC0_CON_BSY == 0);
Bist du sicher?
Nehmen wir mal dein Programm:
PSW_IEN = 0;      
SSC0_TB = command;          // Mit dem Beschreiben des Registers legt die Übertragung (früher oder später) los.
while (SSC0_CON_BSY == 0);  // was passiert hier, wenn die Übertragung sofort loslegt?
                            // Dann wartet er, bis die Übertragung fertig ist.
while (SSC0_CON_BSY == 1);  // Aber dann kommt er hier nie wieder raus, denn die Übertragung war ja schon fertig
response = SSC0_RB;
PSW_IEN = 1;
Ich glaube fast, du solltest das Datenblatt in Bezug auf das BUSY-Flag 
nochmal genauer anschauen...

Autor: Klaus B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gerald schrieb:
> SSC0_TB = command;    // send command with SPI interface
> while (SSC0_CON_BSY == 0);  // wait until transmition starts
> while (SSC0_CON_BSY == 1);  // while busy wait until transmition ready
> response = SSC0_RB;

Hallo,

das ist gaaaanz böser Code, da das Abfragen eines BUSY-Flags in dieser 
Art zu Problemen führen kann (die du gerade selbst erlebst). Es ist 
nämlich nirgends spezifiziert, wie lange es dauert zw. Schreiben des 
TB-Registers und Setzen des BUSY-Flags. Besonders, falls die internen 
Busse Writecaches besitzen.

Hier hängt es dann starkt davon ab, wie schnell deine CPU die Befehle 
abarbeitet und wie schnell deine internen Busse takten.

I.A. ist es empfehlenswerter, auf eine "Finish"-Flag abzufragen (zB. 
Transmit-Interruptflag). Das funktioniert dann immer, egal ob deine CPU 
mit 16MHz oder 200MHz läuft ...

Gruß.

Autor: Gerald (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hier habe ich noch folgendes gesehen: 
http://www.mikrocontroller.net/attachment/37448/sdc.c

void sdcard_write_byte(unsigned char data)
{
  SSC0_TB = data;  // ein Byte dem Sendeempfangsregister übergeben
  while((!SSC0_TIC_IR && SSC0_CON_BSY) == 1)  // wartet bis data 
gesendet wurde
  {
    ;
  }
  SSC0_TIC_IR = 0;  //Übertragungsflag löschen
  SSC0_RIC_IR = 0;


}

ist das auch böse? soll man nur auf SSC0_TIC_IR warten?

Autor: Klaus B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gerald schrieb:
> while((!SSC0_TIC_IR && SSC0_CON_BSY) == 1)  // wartet bis data

Wenn deine CPU zu schnell ist, ist das Busy-Flag noch 0 und du fällst 
sofort aus der Schleife raus. Laß das Busy-Flag einfach weg, das 
brauchst du hier nicht.
Wenn das Transmit-Finished Flag gesetzt ist, ist die Übertragung fertig. 
Punkt. Das Busy-Flag gibt dir nicht mehr Information...

Gruß und frohes Fest.

Autor: Gerald (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
habs gerade getestet:

so funktionierts nicht:
while(!SSC0_TIC_IR)  // wartet bis data gesendet wurde
{
  ;
}

so gehts aber:
while((!SSC0_TIC_IR && SSC0_CON_BSY) == 1)// wartet bis data gesendet 
wurde
{
  ;
}

anscheinend ist dieses BSY flag doch für was da ;)

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.