Wenn ich mich nicht irre, soll ein ISR eine minimale Verarbeitung durchführen, wenn er Daten seriell (über UART) empfängt. Ich plane die Implementierung eines solchen Protokolls für die Kommunikation zwischen 2 Systemen über UART. Dies ist eine grobe Situation, wie ich die ISR codieren möchte. Angenommen 2 System A & B, wo A eine Nachricht an B sendet: Das Schlüsselwort wird verwendet, um den Beginn der Nachricht anzugeben (festgelegte Daten/Länge kann nicht das Schlüsselwort sein). Kanal OK, Datenlänge, RxLength, RxData, Paketempfangs-Flag im Prozess von B sind standardmäßig 0. Datenlänge = nein. von (allen Daten) in Bytes (z. B. wenn alle Daten = 1, Länge der Daten = 1)
A's Process
Send Keyword
Send Length of data
Send all data
B's Process
Rx Interrupt
enter ISR
ISR: if(Received Byte == Keyword && !ChannelOK)
{
Set ChannelOK
}
if(ChannelOK && RxLength)
{
Set Length of data=received byte
ChannelOK=0
RxLength=0
}
if(Length of data != 0 && RxData)
{
Store Data
--Length of data
if(Length of data==0)
{
Set Packet received flag
RxData=0
}
}
if(ChannelOK)
{
Set RxLength
}
if(Length of data)
{
Set RxData
}
Reset to Interrupt Again
Mein Zweifel ist: B hat im ISR so viel zu tun, während A ununterbrochen sendet. Unter der Annahme, dass A Daten mit 7,5 Mbit/s (11 Bit pro Übertragung) sendet, muss der ISR den Interrupt alle (11/7,5 Mio.) Sekunden zurücksetzen. Dies scheint sehr sehr klein. Gehen Daten verloren, wenn ich den Interrupt nicht rechtzeitig zurücksetze, oder werden sie im 16-Byte-FIFO gespeichert, sodass ein Interrupt sofort ausgelöst werden kann, sobald ich den Interrupt zurücksetze, oder muss ich einen Tx-Prozess verlangsamen, indem ich auf ein ACK warte? für jedes Byte (verlangsamt viel)???
Ich bin ein Neuling bei ISR. Bitte helfen Sie ISR-Designs oder -Protokolle für die serielle Datenkommunikation wären nützlich
Danke
Ich werde eine Methode vorschlagen, die Sie mit einigen Modifikationen an Ihre Bedürfnisse anpassen können.
Bei diesem Verfahren ist die ISR so klein, dass sie nur Daten in einem Array für die spätere Dekodierung im Hauptprogramm speichert, zwei Zähler werden verwendet, um empfangene Daten und dekodierte Daten zu erkennen. Natürlich können Sie anstelle der Zähler Zeiger verwenden.
ISR:
{
Receivedbytes[i++]= Rxbuffer;
dataReceived++;
}
main:
void UARTdecode{
if (dataDecoded<dataRecived)
{
Received byte = Receivedbytes[j++];
///// where routine
if(Received Byte == Keyword && !ChannelOK)
{
Set ChannelOK
}
..
..
..
//// end of routine
dataDecoded+=x; (where x is the amount of data decoded or message length)
}
}
PS: Es ist SEHR WICHTIG, dass i und j als statische Variablen deklariert werden
Sie können auch den Quellcode der Arduino-Hardwareserienbibliothek überprüfen, es ist Open Source und verwendet ISR, um Daten „HardwareSerial.h“ im Installationsverzeichnis zu empfangen
B hat in der ISR so viel zu tun
Nein, zumindest nicht, wenn Sie das System richtig gestalten. Ich würde jede Dekodierungslogik aus dem ISR heraushalten. Normalerweise greift mein UART-Interrupt-Handler das Byte von der Hardware, löscht die Interrupt-Bedingung und stopft das Byte in einen FIFO. Der Vordergrundcode kann es von dort übernehmen. Machen Sie den FIFO groß genug, damit der Vordergrundcode in Bursts ausgeführt werden kann und der FIFO zwischen Bursts nicht überläuft.
Wenn pro Byte einfach zu viel zu tun ist, haben Sie ein grundlegendes Problem, das die Firmware nicht beheben kann. Sie benötigen einen schnelleren Prozessor oder eine langsamere Kommunikation.
Olin Lathrop
AlphaGoku
Löffel
AlphaGoku