mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik MSP430 USART RX interrupt wird nicht aufgerufen.


Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hallo!

ich initialisiere meine serielle schnittstelle so:
void init_uart()
{
  P3SEL |= 0x30;                            // P3.4,5 = USART0 TXD/RXD
  
  BCSCTL2 |= DCOR;                          // Rosc
  _BIS_SR(OSCOFF);                          // XTAL not used
  ME2 |= UTXE0 + URXE0;                     // Enabled USART0 TXD/RXD
  UCTL0 |= CHAR;                            // 8-bit character
  UTCTL0 |= SSEL1;                          // UCLK = SMCLK
  UBR00 = 0x68;                             // 0x68 2MHz 19200
  UBR10 = 0x00;                             //
  UMCTL0 = 0x00;                            // 0x00 no modulation
  UCTL0 &= ~SWRST;                          // Initialize USART state machine
  IE2 |= URXIE0;                            // Enable USART0 RX interrupt 
}

eigentlich fast original-code von einem ti beispiel.
irgendwie wir aber die interrupt service routine nicht aufgerufen.
zeichen können jedoch gesendet und empfangen werden.

wenn ich den rxbuf0 im mein loop polle wird das zeichen, weches vom pc 
gesendet wird auch auf dem lcd des controllers dargestellt.

folgende interruptroutine wird benutzt, abern icht erreicht
#pragma vector=UART0RX_VECTOR
__interrupt void usart0_rx (void)
{
 position(4,1);
 printtext("intr");
  
  while (!(IFG2 & UTXIFG0));                // USART0 TX buffer ready?
  TXBUF0 = RXBUF0;                          // RXBUF0 to TXBUF0
}

hab ich irgendetwas nicht beachtet?

vielen dank für eure hilfe

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi,

hast du evtl. das globale Interrupt-enable Flag nicht gesetzt?

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das wars wohl...

jetzt habe ich nur ein anderes problem...

der controller startet immer neu, obwohl der wdt ausgeschaltet ist...

jetzt wird der meinloop nicht mehr erreinch :(
void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  
  _DINT(); // disable all interrupts
  
  init_uart();
  
  P1DIR = 0xFF;    // P1.x Output für LCD
  lcd_init();
  
  position(1,1);
  printtext("Temperatur Test");
 _EINT(); // enable all interrupts

while(1);

Autor: CHRiS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
main-loop natürlich... sry, war schon spät

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Chris (Gast)
#pragma vector=UART0RX_VECTOR
__interrupt void usart0_rx (void)
{
 position(4,1);
 printtext("intr");
  
  while (!(IFG2 & UTXIFG0));                // USART0 TX buffer ready?
  TXBUF0 = RXBUF0;                          // RXBUF0 to TXBUF0
}

AUA! So eine Warteschleife in einem Interrupt ist schlicht sträflich!
Ebenso die printtext() Funktion. Solche langsames Zeug hat in Interrupts 
nciht zu suchen.

>der controller startet immer neu, obwohl der wdt ausgeschaltet ist...

Wahscheinlich knallt es mit deinen Interrupts. Hast du einen Handler für 
den TX-Interrupt, wenn du ihn freigegeben hast?

>jetzt wird der meinloop nicht mehr erreinch :(

Welcher Mainloop? Du hast eine einmalige Sequenz und danach eine 
Endlosschleife ohne Inhalt.

MFG
Falk

Autor: CHRiS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> AUA! So eine Warteschleife in einem Interrupt ist schlicht sträflich!
>> Ebenso die printtext() Funktion. Solche langsames Zeug hat in Interrupts
>> nciht zu suchen.

das ist aus einem TI Beispiel und nur zum ausprobieren - auch die 
printtext war nur zum testen

>> Welcher Mainloop? Du hast eine einmalige Sequenz und danach eine
>> Endlosschleife ohne Inhalt.

den Inhalt hab ich rausgenommen, weil ich den thread nicht so 
vollballern wollte

>> Wahscheinlich knallt es mit deinen Interrupts. Hast du einen Handler für
>> den TX-Interrupt, wenn du ihn freigegeben hast?

weiss nicht genau was du meinst?!?!

Vielen Dank CHRiS

Autor: Michael (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Endlosloop ist schon richtig in diesem Fall. Dort wird überprüft, ob 
das Byte wirklich schon gesendet worden ist.

In den Code Examples geschieht dies aber nach jedem gesendeten Byte.

Autor: CHRiS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> In den Code Examples geschieht dies aber nach jedem gesendeten Byte.

Hier doch auch oder?

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ CHRiS (Gast)

>das ist aus einem TI Beispiel und nur zum ausprobieren - auch die
>printtext war nur zum testen

Das kann aber auch beim Testen daneben gehen.

>den Inhalt hab ich rausgenommen, weil ich den thread nicht so
>vollballern wollte

Mit solchen halben Fragmenten kann niemand was sinnvolles anfangen. 
Poste VOLLSTÄNDIGEN Quelltext als Anhang.

>> Wahscheinlich knallt es mit deinen Interrupts. Hast du einen Handler für
>> den TX-Interrupt, wenn du ihn freigegeben hast?

>weiss nicht genau was du meinst?!?!

???
Wenn ein Interrupt freigegben wird, zu dem kein Interrupthandler 
existiert, dann gibts beim Auftreten eben diese Interrupts eien Reset.

MFG
Falk

Autor: CHRiS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
wie sieht so ein Interrupthandler aus?
hab ich irgendwie leider noch nichts von gehört oder vielleicht unter 
einem anderen Begriff kennengelernt.

vielen Dank schonmal für deine Hilfe

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ CHRiS (Gast)

>wie sieht so ein Interrupthandler aus?
>hab ich irgendwie leider noch nichts von gehört oder vielleicht unter
>einem anderen Begriff kennengelernt.

Interrupthandler == Interruptroutine

;-)

MFG
Falk

Autor: CHRiS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
#pragma vector=UART0RX_VECTOR
__interrupt void usart0_rx (void)
{
 position(4,1);
 printtext("intr");
  
  while (!(IFG2 & UTXIFG0));                // USART0 TX buffer ready?
  TXBUF0 = RXBUF0;                          // RXBUF0 to TXBUF0
}


DING DING DING - 2 Runde!!! :D
hehe... stimmt ich hab ja nur RX... kein TX :D

das könnte es natürlich sein - werde ich ausprobieren sobald ich zu 
Hause bin!

Besten Dank nochmal!!!!!!

Autor: Chris (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert

#pragma vector=UART0RX_VECTOR
__interrupt void usart0_rx (void)
{  
  while (!(IFG2 & UTXIFG0));                // USART0 TX buffer ready?
  TXBUF0 = RXBUF0;                         // RXBUF0 to TXBUF0
}

#pragma vector=UART0TX_VECTOR
__interrupt void usart0_tx (void)
{
 asm("nop"); // ur zum testen
}


jetzt habe ich beide interrupthandler eingefügt - ok soweit! cpu 
resettet nicht mehr ständig, trotzdem werden die zeichen nicht empfangen 
/ gesendet!
Im prinzip müsste das programm dochein echo vom empfangenen Zeichen 
senden??!!??!?!?

Gruß CHRiS

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Chris (Gast)

>Im prinzip müsste das programm dochein echo vom empfangenen Zeichen
>senden??!!??!?!?

Neee, du vermischst Polling mit Interrupts. Das geht daneben! Wenn du 
Pech hast hängt die CPU ewig im TX-Interrupt fest (kann ich jetzt nicht 
genau sagen, kenn den MSP nicht so detailiert). Toggle mal ne LED im 
TX-Interrupt.

MFG
Falk

Autor: CHRiS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ihr werdet es nicht glauben....

ich schalte die schaltung heute morgen an.... OHNE ÄNDERUNGEN AM 
PROGRAMM
und die MCU resettet sich wieder ständig :(

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ CHRiS (Gast)

>ich schalte die schaltung heute morgen an.... OHNE ÄNDERUNGEN AM
>PROGRAMM
>und die MCU resettet sich wieder ständig :(

Wer weiss was du gestern WIRKLICh in den MSP geladen hast. Oder 
vielleicht hast den MSP gestern gar nicht gestartet.
Machs doch einfach mal ordentlich.

1.) Echo mit Polling.
2.) Echo nur mit RX Inerrupt (wenn gleich das nicht so schön ist)
3.) Echo mit RX+TX Interrupt, wobei die Übergabe der Daten über eine 
Variable + Flag erfolgen muss.

MFG
Falk

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich denke, die Baudrate stimmt einfach nicht.
In den geposteten Schnipseln hier steht nur, dass du den externen 
Widerstand an den DCO legst. Ist denn da überhaupt einer dran? Und was 
verleitet dich zu der Annahme, dass der DCO dann mit exakt 2MHz läuft? 
OHne jegliche weitere Initialisierung?
Und was hat diese Einstellung überhaupt in der UART-Init zu suchen?

Dann weiter: Wieo hältst du dich nicht an die Code-Beispiele und die 
User Guides? Bei der Init. der UART MUSS der Software-Reset-Bit die 
ganze Zeit gesetzt sein. Das Rücksetzen am Ende ist richtig, aber VOR 
der Init musst du es setzen.

Weiter: In der while(1) solltest du eine Zeile aufnehmen, in der du das 
globale Interrupt-Bit setzt, damit es nach Beenden der ISR auf jeden 
Fall an ist.

Den TX-Int brauchst du momentan noch nicht, das ist nur, wenn du 
energiesparend große Datenmengen verschicken willst. Da kannst du, 
während das Senden luft, die CPU schlafen legen.

Autor: CHRiS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das hab ich teilweise zum testen aus dem TI beispiel genommen
void main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  P3SEL |= 0x30;                            // P3.4,5 = USART0 TXD/RXD
  BCSCTL2 |= DCOR;                          // Rosc
  _BIS_SR(OSCOFF);                          // XTAL not used
  ME2 |= UTXE0 + URXE0;                     // Enabled USART0 TXD/RXD
  UCTL0 |= CHAR;                            // 8-bit character
  UTCTL0 |= SSEL1;                          // UCLK = SMCLK
  UBR00 = 0x68;                             // 2MHz 19200
  UBR10 = 0x00;                             //
  UMCTL0 = 0x00;                            // no modulation
  UCTL0 &= ~SWRST;                          // Initialize USART state machine
  IE2 |= URXIE0;                            // Enable USART0 RX interrupt

  _BIS_SR(LPM0_bits + GIE);                 // Enter LPM0 w/ interrupt
}

#pragma vector=UART0RX_VECTOR
__interrupt void usart0_rx (void)
{
  while (!(IFG2 & UTXIFG0));                // USART0 TX buffer ready?
  TXBUF0 = RXBUF0;                          // RXBUF0 to TXBUF0
}

Der Widerstand ist natürlich vorhanden.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ CHRiS (Gast)

>Der Widerstand ist natürlich vorhanden.

Mensch Chris, du hast es immer noch nicht kapiert. Gehs erstmal LANGSAM 
an. Und für den UART brauchst du einen Quarz, der DCO vom MSP geht 
nicht!

Wie beim AVR.

http://www.mikrocontroller.net/articles/AVR-Tutori...

Und mach es erst mal per Polling! Empfangen UND Senden!

MFG
Falk

Autor: CHRiS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> Mensch Chris, du hast es immer noch nicht kapiert.

Stimmt :(

ICh hab so ein Header Board hie aus dem Shop, reicht es wenn ich den 
32kHz  Quartz davon verwende? oder braucht man unbedingt einen externen?

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Alsooo....wenn du den DCO nutzen willst (höhere Bitraten als 9600 gehn 
nur mit HF-Quarz oder DCO), dann solltest du diesen unbedingt nach dem 
32khz Quarz einstellen. Dazu gibts folgenden Code:
//------------------------------------------------------------------------------
void Set_DCO (void)                         // Set DCO to selected frequency
//------------------------------------------------------------------------------
{

  unsigned int Compare, Oldcapture = 0;

  BCSCTL1 |= DIVA_3;                        // ACLK= LFXT1CLK/8
  CCTL2 = CM_1 + CCIS_1 + CAP;              // CAP, ACLK
  TACTL = TASSEL_2 + MC_2 + TACLR;          // SMCLK, cont-mode, clear

  while (1)
  {
    while (!(CCIFG & CCTL2));               // Wait until capture occured
    CCTL2 &= ~CCIFG;                        // Capture occured, clear flag
    Compare = CCR2;                         // Get current captured SMCLK
    Compare = Compare - Oldcapture;         // SMCLK difference
    Oldcapture = CCR2;                      // Save current captured SMCLK

    if (DELTA == Compare) break;            // If equal, leave "while(1)"
    else if (DELTA < Compare)               // DCO is too fast, slow it down
    {
      DCOCTL--;
      if (DCOCTL == 0xFF)
      {
        if (!(BCSCTL1 == (XT2OFF + DIVA_3)))
        BCSCTL1--;                          // Did DCO roll under?, Sel lower RSEL
      }
    }
    else
    {
      DCOCTL++;
      if (DCOCTL == 0x00)
        {
          if (!(BCSCTL1 == (XT2OFF + DIVA_3 + 0x07)))
          BCSCTL1++;                        // Did DCO roll over? Sel higher RSEL
        }
    }
  }
  CCTL2 = 0;                                // Stop CCR2
  TACTL = 0;                                // Stop Timer_A
}

DELTA gibts den Vervielfachungsfaktor an, z.b:
#define DELTA 256                           // target DCO = DELTA*(4096) = 1048576

Damit kannst du dir was aussuchen, der DCO wird auf diese Frequenz 
möglichst passend justiert. Damit kann man den UART verwenden. 
Allerdings sollte man das ab und zu wieder aufrufen, der DCO ist recht 
temperaturinstabil. Spannungsschwaknungen mag er auch überhaupt nicht.

Da musst du dann natürlich den passenden Teilerfaktor plus evtl. 
Modulation für deine UART ausrechnen.

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ CHRiS (Gast)

>ICh hab so ein Header Board hie aus dem Shop, reicht es wenn ich den
>32kHz  Quartz davon verwende?

Ja, aber dann musst du den UART so konfigurieren, dass er mit ACLK 
arbeitet. Und maximale Baudrate sind dann 9600. Ist in den Beispielen 
von TI dabei.

> oder braucht man unbedingt einen externen?

Der ist auch extern und nciht intern (im Chip).

MFG
Falk

Autor: Christian R. (supachris)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Übrigens gibts doch da direkt ein Beispiel bei TI, siehe Anhang.

Autor: CHRiS (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
hallo!

ich habe jetzt nach und nach mal alle beispielsourceoes ausprobiert.
leider funktionieren nur die wo kein externer quartz benötigt wird. 
also nur die mit dem 100 kOhm Widerstand.

Zur Zeit benutze ich die gleichen Einstellungen wie im angehängten 
Sourcecode.

Hat einer eine Idee warum die anderen Sources nicht laufen?

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielleicht schwingt der Quarz nicht? Kaputt? Falsche Last-Kapazität?
LAss dir doch mal den ACLK auf dem entsprechenden PortPin ausgeben und 
schau ihn dir an.

Autor: CHRiS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
-- kleines Zwischenergebnis --

Das Senden per polling funktioniert wunderbar 9600 Baud (mit Source von 
17:15) - kann ich daraus schliessen, dass die Schnittstelle richtig 
funktioniert?

Autor: CHRiS (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
wieder das alte problem :(
senden klappt wunderbar...
sobald ich das globale interrupt flag setze bleibts die cpu stehen

- Uart ist so initialisiert, dass nur der RX interrupt freigegeben ist
- senden per polling funktioniert wunderbar

kann einer nochmal einen blick über den code werfen?

und bitte nicht töten wenn ein paar Sachen noch unschön programmiert 
sind... aufräumen wollte ich wenn alles funktioniert

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ CHRiS (Gast)

>wieder das alte problem :(
>senden klappt wunderbar...
>sobald ich das globale interrupt flag setze bleibts die cpu stehen

Mensch Chris, du bist wirklich ziemlich lernresistent. Warum glaubst du 
immer alles anders machen zu müssen als die Beispiele? Was soll der 
Quark?
#pragma vector=UART0RX_VECTOR
__interrupt void usart0_rx (void)
{
  _EINT(); 
  _NOP();
}

Das ist würdig, in grosse Buch "How to shoot yourself in the foot" 
plaziert zu werden. Lies dir mal in Datenblatt vom MSP durch, wie der 
UART RX Interrupt funktioniert? Wie wird er ausgelöst? Wie wir er 
gelöscht? Und dann schau deinen Code an und weine.

Ich sags zum letzten Mal.

MACH ES ERSTNMAL NUR MIT POLLING (Senden und Empfangen)!

>- senden per polling funktioniert wunderbar

>und bitte nicht töten wenn ein paar Sachen noch unschön programmiert
>sind... aufräumen wollte ich wenn alles funktioniert

FALSCH!!!!
Wie sagt ein Kollege so schön. "Wir haben keine Zeit es richtig zu 
machen, aber viel Zeit es dreimal zu machen." :-(

MfG
Falk

Autor: CHRiS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> Mensch Chris, du bist wirklich ziemlich lernresistent. Warum glaubst du
>> immer alles anders machen zu müssen als die Beispiele? Was soll der
>> Quark?

ja die Zeilen darunter sind wirklich richtiger Müll.... liegt evtl. 
daran, dass ich seit heute Morgen 9 Uhr da dran sitze :(

Ich gelobe Besserung! Jetzt erstmal nur Polling!

Autor: CHRiS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
-> Eine Frage noch :)

ich habe jetzt alles was mit der UART zu tun hat auskommentiert und das 
globale Interrupt Flag gesetzt mit _EINT().
Trotztdem bleibt das Programm einfach hängen.... vor der while 
schleife...

Autor: CHRiS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
hab den Fehler gefunden!!

hab bei der Initialisierung des ADC das Interrupt Enable gesetzt obwohl 
ich es nicht brauche ... :D

Schluss für heute... Samstag gehts weiter.

Trotzdem Danke für EURE Hilfe und Geduld mit mir!!!

Autor: szimmi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Der Stoff aus dem schlechte Soaps gemacht werden :-)

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zumal man sowas mit dem Debugger doch rausbekommt. Die Adresse steht 
dann auf dem Interrupt-Vektor, der ja nicht belegt ist, dann einfach mal 
ins Datenblatt gucken und man wüsse, wer den Int ausgelöst hat.
Und in der ISR den Int wieder freigeben...naja, verschachtelte Ints, 
aber da muss man genau wissen, was man macht...

Autor: CHRiS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>> naja, verschachtelte Ints, aber da muss man genau wissen, was man macht...

jap - und da ich Anfänger in dem Bereich bin hab ich dadurch viel 
gelernt!

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ CHRiS (Gast)

>jap - und da ich Anfänger in dem Bereich bin hab ich dadurch viel
>gelernt!

Was denn? Wie man es NICHT macht?

MFG
Falk

Autor: CHRiS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>Was denn? Wie man es NICHT macht?

ja, das z.B.

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Kein Wunder übrigens, dass die Beispiele mit Quarz nicht funktionieren. 
Gleich als 2. Befehl im Init schaltest du den Quarz ja aus.

Autor: CHRiS (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ne ne...
da habe ich zum ausprobieren die original TI Beispiele genommen ohne 
meinen Kram drum herum!

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ CHRiS (Gast)

>da habe ich zum ausprobieren die original TI Beispiele genommen ohne
>meinen Kram drum herum!

Dan hast du wohl die falschen genommen.

MFG
Falk

Autor: Christian R. (supachris)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Oder der Quarz ist nicht richtig angeschlossen, kalte Lötstelle oder 
sowas. Ist ja schließlich billigst-Zeugs aus Bulgarien

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.