Forum: Mikrocontroller und Digitale Elektronik SPI Send Problem


von Gerald (Gast)


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

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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?

von Gerald (Gast)


Lesenswert?

Infineon XC164

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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:
1
PSW_IEN = 0;      
2
SSC0_TB = command;          // Mit dem Beschreiben des Registers legt die Übertragung (früher oder später) los.
3
while (SSC0_CON_BSY == 0);  // was passiert hier, wenn die Übertragung sofort loslegt?
4
                            // Dann wartet er, bis die Übertragung fertig ist.
5
while (SSC0_CON_BSY == 1);  // Aber dann kommt er hier nie wieder raus, denn die Übertragung war ja schon fertig
6
response = SSC0_RB;
7
PSW_IEN = 1;
Ich glaube fast, du solltest das Datenblatt in Bezug auf das BUSY-Flag 
nochmal genauer anschauen...

von Klaus B. (Gast)


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ß.

von Gerald (Gast)


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?

von Klaus B. (Gast)


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.

von Gerald (Gast)


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 ;)

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.