hi, mein projekt wächst und immer wieder befinden sich neue steine auf dem weg zur großen erleuchtung. vorab möchte ich auf meinen anderen beitrag hinweisen in dem ihr mir schon geholfen habt und der für die weitere problemlösung vielleicht hilfreich ist. Beitrag "UART empfängt nur einmal." nun möchte ich ja auch gerne per sms befehle schicken können, auf die der µC dann reagiert. dafür würde ich ja wie immer uart_gets() benutzem um etwas vom modem einzulesen. jedoch weiß ich ja nicht wann eine sms eintrifft und um dies zu erkennen müsste der µC ja permanent an der seriellen schnittstelle auf text warten. dies wäre mit dem aufruf von uart_gets() erledigt da die funktion erst beendet wird wenn die max string länge erreicht wurde oder ein string endzeichen erkannt wird. eine ausgabe vom modem wäre z.B. +CMTI:"SM",3 diese zeile sagt mir das eine neue sms im speicherbereich 3 gespeichert wurde. die darauf folgende antwort vom µC wäre dann (öffne SMS 3)-->AT+CMGR=3. folglich wird der inhalt der sms ausgegeben mit dem sich dann arbeiten ließe. mein problem ist nun: nach dem aufruf der funktion uart_gets() wartet der µC auf zeichen. falls aber keine sms eintrifft empfängt der µC keine zeichen vom modem, wartet bis ins nächste jahrhundert und beendet nicht die uart_gets() funktion um mit dem weiteren programm fortzufahren. heißt: in der zeit zwischen aufruf der funktion und eingehender sms beobachtet der µC nicht den status von pinX. das ist aber fatal da der µC ja eine sms verschicken soll wenn sich was an pinX verändert. kurz gesagt in zwei fällen soll reagiert werden: wenn sich pinX verändert und wenn eine sms mit befehl eintrifft. wie löse ich dieses problem?
eine notlösung wäre den sms speicher des modems abzufragen um zu gucken ob irgendwann mal eine neue sms eingetroffen ist. es wäre aber besser wenn das ding direkt reagiert immerhin teilt das modem einem ja auch mit das gerade eine neue sms eintrifft. und bei dieser lösung hätte man ja wieder das problem mit den nichtausgelesenen zeichen im buffer......
ja interupts...... arbeite ich nicht schon damit? und wenn nicht wie setze ich das um?? ich programmiere noch nicht allzulang in c.
schön wäre etwas wie kein hinweis auf zeichen am uart: das programm fragt in dauerschleife pinX ab um zu sehen ob sich was verändert. zeichen kommen an: erst alles empfangen und dann gucken auf was die empfangenen zeichen zutreffen.... neue befehle (empfangene sms) pin anfrage error message e.t.c. das könnte man ja mit einer case schleife machen nachdem alles abgearbeitet ist sofort wieder gucken ob pinX immer noch so ist wie es sein sollte....
ja das bin ich aber schon mehrfach durchgegangen... irgendwie bekomm ich das nicht so einfach hin wie das da steht deshalb ja auch schon den anderen thread
Hi Habe das gleiche Problem wie du! Ich habs so gelöst:
1 | unsigned char neu[10]; |
2 | |
3 | while (1) |
4 | {
|
5 | // Auf UART-Eingabe prüfen
|
6 | if((UCSR0A & (1<<RXC0))) |
7 | {
|
8 | gets(neu); //Speichert den String auf neu ab. |
9 | printf("Hallo\n"); //Gibt Hallo an die Serielle Schnittstelle aus. |
10 | }
|
11 | |
12 | }
|
eventuell eine if-Abfrage nach if((UCSR0A & (1<<RXC0))). Wenn das erste Zeichen ein "+" ist, dann den String mit gets(neu) einlesen. Den String dann mit den entsprechenden Stringfunktionen behandeln. mfg
geht denn nicht öfters bei dieser variante ein zeichen am anfang verloren, weil zu spät angefangen wurde einzulesen??
ich benutze ja schon diese interrupt routine..... kann man die nicht einfach verwenden??
1 | // Interruptroutine, die Zeichen aus dem UART sofort ausliest, wenn empfangen
|
2 | SIGNAL (SIG_UART_RECV) |
3 | {
|
4 | udr_data= UDR; //Byte auf jeden Fall abholen, sonst Endlosinterrupt |
5 | |
6 | if(rbuffcnt < RBUFFLEN) // keinen Zeichen in einem vollen Ringpuffer überschreiben |
7 | rbuff[(rbuffpos+rbuffcnt++) % RBUFFLEN] = udr_data; // welche Position? Gelesene Zeichenpos + Anzahl Zeichen MODULO Pufferlänge |
8 | // (von 0 wieder anfangen, wenn Ende erreicht)
|
9 | }
|
10 | |
11 | // Nächstes zu lesendes Zeichen aus Ringpuffer zurückgeben
|
12 | unsigned char ser_getc (void) |
13 | {
|
14 | unsigned char c; |
15 | |
16 | while(!rbuffcnt); // Warte bis ein Zeichen vorhanden ist |
17 | |
18 | cli(); // Interruptbehandlung kurz aussetzen. Ab jetzt muß es schnell gehen (wenig Befehle), damit Zeichen, die |
19 | // ab jetzt eintreffen nicht verloren gehen.
|
20 | rbuffcnt--; // anschl. ein Zeichen weniger zum ausgeben |
21 | c = rbuff [rbuffpos++]; // Zeichen holen, was nach dem bereits gelesenen liegt |
22 | if (rbuffpos >= RBUFFLEN) rbuffpos = 0; // wenn hinterstes Zeichen (rechts im Puffer) gelesen wurde, dann wieder vorne anfangen |
23 | |
24 | sei(); // Interruptbehandlung wieder aktivieren |
25 | |
26 | return (c); // Zeichen zurückgeben |
27 | }
|
Und dann rufe ich uart_gets() auf um die antwort vom modem zu empfangen und da liegt doch dann irgendwo der fehler oder??
1 | void uart_gets( char* Buffer, uint8_t MaxLen ) |
2 | {
|
3 | |
4 | |
5 | |
6 | |
7 | uint8_t NextChar; |
8 | uint8_t StringLen = 0; |
9 | |
10 | do { |
11 | |
12 | NextChar = ser_getc(); |
13 | |
14 | if (NextChar=='\n' || NextChar=='\r') { |
15 | if (!StringLen) |
16 | continue; // erstmal alle \r und \n am Anfang ignorieren |
17 | else
|
18 | break; // danach makiert das erste \r oder \n das Ende |
19 | }
|
20 | |
21 | *Buffer++ = NextChar; |
22 | StringLen++; |
23 | |
24 | } while (StringLen < MaxLen-1); |
25 | |
26 | *Buffer = '\0'; |
27 | }
|
der holt ja scheinbar alle zeichen direkt in den buffer falls da welche sind und die uart_gets() funktion übergibt ja nur die zeichen aus dem buffer irgendeiner variablen oder nicht??? kann ich dann nicht einfach was machen von wegen wenn buffer leer ist dann rufe nicht uart_gets() auf? wäre das nicht die sauberste lösung?? wie würde man das realisieren?
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.