Hallo zusammen, ich habe aus dem Atmel Beispiel folgenden Interrupt erstellt: ISR(USART0_RX_vect) { unsigned char data; unsigned char tmphead; /* Read the received data */ data = UDR0; /* Calculate buffer index */ tmphead = (USART0_RxHead + 1) & USART_RX_BUFFER_MASK; /* Store new index */ USART0_RxHead = tmphead; if (tmphead == USART0_RxTail) { /* ERROR! Receive buffer overflow */ } /* Store received data in buffer */ USART0_RxBuf[tmphead] = data; //USART0_RxBuf_global[tmphead] = data; } Der Interrupt wird mehrmals durchlaufen, solange Daten empfangen werden. Kann ich das Ende des Interruptes feststellen, denn da wollte ich ein Flag setzen? Vielen Dank. Gruß datatom
vor der letzten Klammer ist doch das Ende und dort kann dein Flag oder Counter rein, aber wozu? Ich mache das selten am Anfang und Ende einen Port wackeln lassen um mit dem Oscar Zeiten zu messen.
:
Bearbeitet durch User
das "Ende des Interrupts" ist am Ende des ISR() Kontextes, ich vermute also du meinst etwas anderes. Welchen Zustand möchtest du genau erkennen?
Wenn der ATMega Daten empfängt die zusammen gehören, Beispiel "AT+CPIN=0000", dann wird jeder Ascii-Wert der Buchstaben und Zahlen in das Array USART0_RxBuf geschrieben: USART0_RxBuf[tmphead] = data; bis das Ende erreicht ist. Da ich nicht weiß welcher Wert als letztes kommt, muss ich also wissen, wann das Ende des Interrupt erreicht ist, um das Flag zu setzen. Wenn ich das AT-Kommando absetze und auf die Antwort warte, läuft das Programm solange weiter, das soll es aber nicht. Das Programm soll das At-Kommando absetzen und auf Antwort warten und dann erst weitermachen.
Thomas H. schrieb: > Da ich nicht weiß welcher Wert als letztes > kommt, muss ich also wissen, wann das Ende des Interrupt erreicht ist, > um das Flag zu setzen. Der Interrupt dient zum Abholen der empfangenen Zeichen vom USART. Die Interpretation des Datenstroms ist ein ganz anderes Thema und hat mit dem Interrupt nichts zu tun. Gewöhnlich schiebt die ISR die Zeichen in einen Ringpuffer und über die Position von Schreib- und Lesezeiger wird der Puffer koordiniert.
Also gibt es keine Möglichkeit das Ende des Interrupts zu ermitteln?
Thomas H. schrieb: > Also gibt es keine Möglichkeit das Ende des Interrupts zu ermitteln? nein, der Interrupt wird für jedes Zeichen aufgerufen. Es gibt kein "ende". > Da ich nicht weiß welcher Wert als letztes > kommt, muss ich also wissen, wann das Ende des Interrupt erreicht ist, > um das Flag zu setzen. doch das weißt du. Am ende eines AT-Befehles kommt eine '\n'. Dann ist der Befehl abgeschlossen.
Thomas H. schrieb: > Also gibt es keine Möglichkeit das Ende des Interrupts zu ermitteln? Wurde doch schon gesagt, die letzte Zeile der ISR. Aber Du meinst was völlig anderes, nämlich das Ende eines Datenpakets. Und das kann man nur feststellen, wenn man das Protokoll kennt. Du mußt also zuerst mal ein Protokoll festlegen.
Thomas H. schrieb: > Wenn der ATMega Daten empfängt die zusammen gehören, Beispiel > "AT+CPIN=0000", dann wird jeder Ascii-Wert der Buchstaben und Zahlen in > das Array USART0_RxBuf geschrieben: > > USART0_RxBuf[tmphead] = data; > > bis das Ende erreicht ist. Da ich nicht weiß welcher Wert als letztes > kommt, muss ich also wissen, wann das Ende des Interrupt erreicht ist, > um das Flag zu setzen. Du suchst also gar nicht das Ende des Interrupts sondern willst wissen, wann dein Datenempfang vollständig ist. Dazu musst du dir ein Protokoll überlegen, das kannst du nicht in der ISR abfangen. Typisch beim UART/RS232 ist ein Carrige Return + Linefeed ('\r\n')die das Ende eines Datensatzes markieren. In der ISR kannst du bestenfalls ein Flag setzen, dass aussagt: "Hey, ich hab die Zeichenkombination für das Ende eines Datensatzes empfangen."
Hallo Thomas, Deine AT-Antwort wird am Ende des ASCII-Textes auch Steuerzeichen enthalten, die das Ende der Nachricht kennzeichnen. Dies ist meist 0x0A oder 0x0D, schau mal in eine ASCII-Tabelle im Internet. Auf diese Zeichen, kannst Du in Deiner ISR, die eigehenden Zeichen hin prüfen und dann mit einem Flag die Nachricht in der main() verarbeiten. Mach dies nie in der isr, da dies zu Zeitaufwändig ist. Die isr immer so kurz wie möglich halten. Ich mache das immer so: ACHTUNG: Der Code ist nur fürs Verständnis runtergeschrieben. Er ist nicht compiliert und kann Fehler enthalten! Gruß Florian
1 | #define RX_BUFFER_SIZE 64
|
2 | char RxBuffer[RX_BUFFER_SIZE]; // In dieses Array (Buffer) werden die empfangenen Zeichen in der isr gespeichert |
3 | uchar RxIndex = 0; // Laufvariable für den Buffer |
4 | uchar RxCompleteFlag = 0; // Flag, um ein empfangenes Kommando in der main zu signalisieren |
5 | |
6 | |
7 | // ggf. RxBuffer[] initialisieren
|
8 | |
9 | main() |
10 | {
|
11 | if(RxCompleteFlag) |
12 | {
|
13 | // verarbeite hier Dein Kommando aus dem Buffer
|
14 | if(strcmp(RxBuffer, "AT+CPIN=0000") == 0) |
15 | {
|
16 | // Do something
|
17 | }
|
18 | |
19 | // Am Ende! wieder zurücksetzen
|
20 | RxCompleteFlag = 0; |
21 | // Wenn Du magst, kannst Du hier das Buffer-Array auch noch löschen
|
22 | |
23 | }
|
24 | }
|
25 | |
26 | |
27 | USART_isr() |
28 | {
|
29 | unsigned char data; |
30 | |
31 | data = UDR0; |
32 | |
33 | // Nur wenn Daten in den Buffer geschrieben werden können
|
34 | if(!RxCompleteFlag) |
35 | {
|
36 | if((data == 0x0D) || (data == 0x0A) || (RxIndex >= RX_BUFFER_SIZE)) |
37 | {
|
38 | // Zeilenende erreicht, oder Bufferoverflow vermeiden
|
39 | RxCompleteFlag = 1; |
40 | // Laufvariable wieder auf 0 setzen
|
41 | RxIndex = 0; |
42 | }
|
43 | else
|
44 | {
|
45 | // Solange Zeichen ankommen, in den Buffer schreiben
|
46 | RxBuffer[RxIndex] = data; |
47 | // Laufvariable inkrementieren
|
48 | RxIndex++; |
49 | }
|
50 | }
|
51 | }
|
ich würde ja noch
1 | // Solange Zeichen ankommen, in den Buffer schreiben
|
2 | RxBuffer[RxIndex] = data; |
3 | // Laufvariable inkrementieren
|
4 | RxIndex++; |
1 | // Solange Zeichen ankommen, in den Buffer schreiben
|
2 | if(isprint(data)) |
3 | {
|
4 | if( data != '/r' && && data != '/n' ) |
5 | {
|
6 | RxBuffer[RxIndex] = data; |
7 | // Laufvariable inkrementieren
|
8 | RxIndex++; |
9 | var_str_complete = 0; |
10 | }
|
11 | else
|
12 | {
|
13 | RxBuffer[RxIndex] = '\0'; |
14 | var_str_complete = 1; |
15 | }
|
16 | }
|
oder ähnlich einfügen
:
Bearbeitet durch User
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.