Hallo,
Ich habe heute bereits eine Frage ins Forum, bezüglich Counter/Timer
gestellt. Sorry, aber ich dachte ein anderer Betreff passt besser zu
meinem neuen/alten Problem.
Ich möchte gern die Antworten von einem Modem auswerten. Allerdings bin
ich noch Anfänger und hab meine Probleme. Vor allem springt mein
Programm nicht aus der for-Schleife wenn BUSY gesendet wird.
Also im Grunde will ich eine Nummer anrufen und
wenn die/der nach 15 Sekunden ran geht, die Verbindung beenden und eine
andere Nummer wählen.
Ich hab also zwei Nummern, die abwechselnd anrufen will, bis jemand ran
geht, bzw. durch Auflegen bemerkbar macht, dass er da ist. Ich erhalte
dann vom Modem die Antwort BUSY.
Mit gsm_ans = 1 springe ich in
gsm_antwort()und warte/werte die Antwort des Modems ab/aus. Wenn nicht
BUSY detektiert wurde soll der Anruf nach 15 min mit ATH beendet und das
Ganze von vorne beginnen. Wenn das Modem nach ATD+xxxxx; sendet erhöhe
ich init_step um eins.
Ich habs nun mal mit einer Nummer versucht und es klappt nicht
richtig...Ich seh den Fehler nicht...zum Haare raufen!
Es wäre wirklich nett wenn mir jemand weiterhelfen könnte. VG
do
if ( gsm_ans == 0 )
{
if ( init_step == 0 )
{
uarts( "ATD" );
uarts( number1 );
uarts( ";" );
gsm_ans = 1;
}
if ( init_step == 1 )
{
for( int i = 0; i<15000; i++)
{
_delay_ms(1);
if( busy == 1 )
{
break;
}
}
if( busy == 1 )
{
uarts("BUSY detektiert");
busy = 0;
}
else
{
uarts( "ATH" );
init_step = 0;
}
gsm_ans = 1;
}
}
else
gsm_antwort();
while( init_step <= 1 );
Peter II schrieb: > init_step wird nie auf 1 gesetzt Post mal den kompletten Code. Wo wird denn z.B. "busy" aktualisiert? mfg.
1.Es gibt Code-Tags, die deinen Code lesbar machen. 2.Schreib deinen Code nicht ab, sondern kopiere ihn, allein die do-while-Schleife zeigt, dass du nur grob abgeschrieben hast. 3.Miese Einrückungstiefe. Thomas Eckmann schrieb: > Wo wird denn z.B. "busy" aktualisiert? Und wo wird es verändert? Muss ja ein Interrupt (Empfangs-/Zustands-routine fürs Modem?) sein, sonst wäre die if-Abfrage in der for-Schleife sinnlos.
ole schrieb: > Muss ja ein Interrupt (Empfangs-/Zustands-routine fürs Modem?) sein, > sonst wäre die if-Abfrage in der for-Schleife sinnlos. Danke für deinen Hinweis. mfg.
Hallo, danke für die Antworten! in gsm_antwort() werte ich die vom Modem empfangenen Antworten aus- interruptgesteuert über UART. Wenn ich BUSY erhalte setze ich in gsm_antwort() die globale Variable busy = 1. Bei OK erhöhe ich init_step. sprich, wenn ich ATD+xxxx; gesendet habe, warte ich auf die Antwort OK und gehe zu init_step. Es scheint als ob erst nach Ablauf der 15 sec ich aus der Schleife komme. Wenn ich nun mit wenn ich die 15 sec durchlaufen lasse, sprich nicht Auflegen erscheint am Hyperterminal natürlich erst ATD+xxxxx; dann das OK und nach den 15 sec läuten, das Auflege-Kommando ATH, das sich dann aber immer wieder gesendet wird. Wenn ich nun den Anruf unterbreche und zwar durch das Auflegen, wird zunächst ATD+xxxxxx; dann ATH, dann nochmal ATD+xxxxxx; und schließlich "BUSY detektiert" angezeigt. Ich habe meine Sendefunktion angehängt. Ich darf den Rest allerdings nicht online stellen. Das k.... mich etwas an. Vielleicht kann mir aber trotzdem jemand weiterhelfen. Würde mich echt freuen, steh total auf dem Schlauch.
Michel schrieb: > Ich habe meine Sendefunktion angehängt. Das ist bestimmt nicht deine Sendefunktion. Der Codefetzen compiliert ja nicht mal. (Do ... while(..)) Michel schrieb: > Ich darf den Rest allerdings nicht online stellen. Ein paar Details musst du schon rausrücken. Michel schrieb: > Vielleicht kann mir aber trotzdem jemand weiterhelfen. Im Moment ist nur die Ratestunde eröffnet. mfg.
Michel schrieb: > in gsm_antwort() werte ich die vom Modem empfangenen Antworten aus- > interruptgesteuert über UART. Wenn ich BUSY erhalte setze ich in > gsm_antwort() die globale Variable busy = 1. Das sehe ich nicht in Deinem Code. Unterschlagen? Ist die "globale Variable" namens busy denn auch volatile deklariert? Immerhin wird sie durch eine Interruptroutine geändert. Wenn Du das dem Compiler nicht explizit sagst, optimiert er die busy-Abfragen aus Deiner main-Funktion komplett weg, denn da ändert sich ja augenscheinlich nichts. Das solltest Du übrigens mit allen globalen Variablen so machen, die in einer Interrupt-Routine modifiziert werden. Gruß, Frank
Frank M. schrieb: > Ist die "globale Variable" namens busy denn auch volatile deklariert? > Immerhin wird sie durch eine Interruptroutine geändert. Wenn Du das dem > Compiler nicht explizit sagst, optimiert er die busy-Abfragen aus Deiner > main-Funktion komplett weg, denn da ändert sich ja augenscheinlich > nichts. Das nächste Problem ist, dass die Auswertung ja angeblich gsm_antwort() macht (*), aber in der for-Schleife nie aufgerufen wird. Ob gsm_antwort() wirklich interrupt-gesteuert ist, wage ich zu bezweifeln, denn er ruft sie auch explizit auf. (*) Michel schrieb: > in gsm_antwort() werte ich die vom Modem empfangenen Antworten aus- > interruptgesteuert über UART Wo wird init_step erhöht? Ich vermute, dass sollte irgendwo in
1 | if ( init_step == 1 ) |
2 | {
|
3 | /*...*/
|
4 | }
|
passieren.
Hallo Ihr,
zunächst einmal vielen Dank für eure Antworten! init_step == 1 wird in
gsm_antwort erhöht.
sprich, bei einem empfangenen OK erhöhe ich die Variable init_step.
die Funktion ist im Grunde so aufgebaut:
void gsm_antwort(void)
{
.
.
.
if( gsm_ans == 1 )
{
else if( strncmp( gsm_buffer, "BUSY", 4 ) == 0 )
{
gsm_ans = 0;
busy = 1;
}
.
.
.
}
}
Das Problem liegt wohl hier:
if ( init_step == 1 )
{
for( int i=0; i < 15000; i++ )
{
_delay_ms(1);
if( busy == 1 )
break;
}
if( busy == 1)
{
uart0_sends("HAB ICH");
busy = 0;
}
gsm_ans = 1;
}
Ich will ja nun entweder 15sec warten und dann mit uarts("ATH") auflegen
oder bei busy == 1 was senden. Allerdings springt meine erst nach 15sec
in busy == 1 bzw. wartet also erst ab bis die 15 sec abgelaufen sind.
Ich kapiers nicht mehr!
Das mit strncmp und auch strcmp ist so eine Sache, vielleicht wäre strstr() besser? Das Problem sehe ich eher beim Aufruf von gsm_antwort(), wird das ganz sicher in einem Interrupt aufgerufen? Und wenn ja, warum steht es oben nochmal im Quellcode? Dürfte ja nicht nötig sein, oder? Nicht das nur der Empfang über UART im Interrupt ausgelöst wird und die Analyse der UART-Daten gar nicht stattfindet? Ich würde mich nicht wundern, wenn nach dem_delay_ms(1) ein gsm_antwort() gehört. Michel schrieb: > Allerdings springt meine erst nach 15sec > in busy == 1 bzw. wartet also erst ab bis die 15 sec abgelaufen sind. Vermutlich wird das mit den Interrupts nicht funktionieren. Ich vermute, mehr geht nicht ohne Quellcode, dass die Interrupts nur die Daten vom UART abholen und du sie nie analysierst, da der Aufruf gsm_antwort() doch nicht so erfolgt, wie du vermutest. Oder busy ist nicht volatile und wird vom Compiler wegoptimiert. Beim Verstehen von Interrupts kann man schon mal was falsch verstehen. ;-) Frag mal deinen Betreuer (Firma oder DA-Arbeit?).
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.