Wie verwende ich UART-RX-Daten von ISR zur Hauptschleife?

Ich verwende PIC18F und versuche derzeit, es mit SIM900 zu verbinden. Ich verwende UART Rx-Interrupt. ISR funktioniert korrekt, aber ich frage mich, wie ich Daten in die Hauptschleife bekomme. Sagen wir :

#pragma interrupt hi_prioriint
void hi_prioriint(void)
{
   if(PIR1bits.RCIF==1)
   {
      Rx = ReadUSART();  //store the received byte in Rx
   }
 }

RxJetzt möchte ich in der Hauptschleife verwenden . Wenn ich zum Beispiel ATeinen Befehl sende, muss ich prüfen, ob ich ihn erhalten habe OKoder ERRORvon SIM900. (Im Moment teste ich es nur mit einem einzelnen Byte und werde es später in Empfangszeichenfolgen umwandeln, da die Antwort vom SIM900 in Zeichenfolgenform vorliegt.)

Beispiel:

 putrsUSART("AT\r");        //sending AT command
 delay(500)                 //delay of 500ms
 if(strcmp(Rx,"OK")==0)     //checking the response
 {
    //if received OK then proceed further
 }

Wie verwendet man RX-Daten von ISR in der Hauptschleife?

Antworten (2)

Der herkömmliche Weg, dies zu tun, ist die Verwendung eines Ringpuffers (manchmal auch als Ringwarteschlange bezeichnet). Die Rx-Unterbrechungsroutine fügt empfangene Datenbytes unter Verwendung ihres Eingangszeigers/Index in die Warteschlange ein. Der Hauptcode verwendet den Ausgabezeiger/-index, um die Daten aus der Warteschlange zu extrahieren.

Der große Vorteil bei diesem Verfahren besteht darin, dass die Rx-Daten in Schüben ankommen können, die möglicherweise schneller kommen, als sie aufgrund von Latenzzeiten bei anderen Aufgaben von der Hauptschleife verbraucht werden können. Solange die Warteschlangentiefe ausreicht und der Mainline-Code in der Lage ist, die Rx-Daten mindestens so schnell wie die langfristige Datenflussrate zu verbrauchen, ist dies der richtige Weg.

Beachten Sie, dass es online eine Fülle von Informationen zum Design, zur Codierung und zum Betrieb von zirkulären Warteschlangen gibt. Ein Hinweis ist, dass es eine Leistungsverbesserung bei der Verwendung von kreisförmigen Warteschlangen geben kann, wenn die Tiefe der Warteschlange auf einer geraden Potenz von zwei Bytes gehalten wird. Wenn dies geschehen ist, kann der Umlauf des Warteschlangenindex von oben nach unten in der Warteschlange zu einer einfachen Maske des Index mit einem Wert von (Warteschlangentiefe – 1) werden.

Danke schön. Ich werde mehr darüber studieren circular buffer. Kannst du einen Democode dafür posten?

Eine Alternative besteht darin, im RX-Interrupt die empfangenen Zeichen in einem flüchtigen Puffer zu speichern und bei jedem Empfang einen Zeiger zu inkrementieren. Wenn ein CR/LF-Zeichen empfangen wird, setze ein globales Flag-Bit "Empfang abgeschlossen" und setze den Zeiger zurück. Rufen Sie dieses "Receive Complete" in der Hauptschleife ab. Wenn der Sender in einem CR/LF endet, kann die Hauptschleife dann den gefüllten Puffer lesen.