hallo Leute
ich bin dabei eine C funktion zu implementieren
Das Programm ist in mehrere Routine aufgeteilt.
Die erste Routine soll abfaufen bis Zeichen zur Übergang zur nächte
kommt.
ich habe mir gedach in der Erste Routine eine while(1) schleife zu
setzen und eine Interrupt für die nächste Routine zu implementieren.
Nun so weiß ich nicht wie oder ob es machbar eine while schleife
innerhalb einer Interruptfunktion zu unterbrechen und in die nächte
einzuspringen.
Hat jemand eine Idee wie diese machbar ist ? oder eine andere
Möglichkeit vorzuschlagen?
Ich wäre für jeden Beitrag bankbar.
Karl
So macht man es sicher nicht, warum setzt du nicht in deiner ISR einen
Merker und wechselst daraufhin zur nächsten Routine. ISRs sollte man
immer so kurz wie möglich halten.
Die Interrups laufen nicht über die selbe Taste deswegen kann schlecht
unter Switsch gemach werden.
Jede interrupt hat sein Erzeuger(taste).
so meine ich :
void Einspritzen(void)
{
while(1)
{
// do many things
}
}
void vorbereitung(void)
{
while(1)
{
//do many things
}
}
int main()
{
vorbereitung();
einspritzen();
.
.
.
}
Hallo,
aus einer while(1) Schleife kommst Du nur noch über die brutalo Methode
"gehe zurück zu Los, ziehe keine 4.000" ein. Los ist in diesem Fall
RESET.
Wenn Du aus einer Schleife wieder rauskommen willst must Du schon als
Abruchbedingung eine Variable setzen.
Hans
Was du da hast ist doch Unsinn.
Da benutzt mn doch keine Endlos-while Schleifen nur um sie dann mit
Gewalt abzuschiessen.
Dafür benutzt man Schleifen, die von einer Bedingung abhängen. Welche
das sind musst du entscheiden.
Aber im Grunde
void vorbereiten()
{
while( !vorbereitung abgeschlossen )
mache vorbereitungsarbeit
}
Jetzt bist du drann. Woran kann man erkennen, dass die Vorbereitung
abgeschlossen ist?
(Selbiges auch für die anderen Funktionen)
jetzt ist mir was aus verschiedene Posten aufgefallen. ich mache eine
While mit Bedingung. und in der ISR setze ich die Bedingung zu 1. Dann
brich die Whileschleife ab und läuft normal weiter in die andere
Funktion.
Ich denke so geht.
so habe ich mir das nun vorgestellt:
ISR (einsptz)
(
arbeit_ende=1;
)
ISR (vorber)
(
wasser=1;
)
void vorbereitung(void)
{
while(arbeit_ende)
{
//do many things
}
}
void Einspritzen(void)
{
while(wasser)
{
// do many things
}
}
.
.
.
Was meint ihr . ich kann das nun nicht debuggen , aber ist plausibel
oder ??
lg
Karl
Wo wird arbeit_ende = 0 gesetzt, damit es nicht weiter ausgeführt wird
wenn wasser = 1?
Kannst Du bitte mal deine Leertaste entprellen. Das ist fürchterlich
mit den vielen Leerzeichen .
ach nööön ich habe ein Fehler gemacht
Verzeihung ich meinte in der ISR die variablen zu Null(Wasser=0 und
arbeits_ende=0) setzen damit die whilen abbrechen.
>Kannst Du bitte mal deine Leertaste entprellen. Das ist fürchterlich>mit den vielen Leerzeichen .
Ok ich bemühe mich die Leezeichen in griff zu bekommen.
lg
Karl
Hi Leute
mir ist was änhliches am brennen.
in der Schleife , die ich abbrechen will, warte ich auf 3 daten per
Pollin der UART (receive).
d h bei einem drduck an dem Taster würde ich zwar die ISR laufen lassen
aber das Programm wird beim Rückker auf das Ursprungliche warten zurück
kommen und ewig verhaaren.
ich schliesse mich als Beispiel an dem Code von Karl
1
2
volatileunsignedintarbeit_ende=0;
3
volatileunsignedintwasser=0;
4
ISR(einsptz)
5
(
6
arbeit_ende=1;
7
)
8
9
10
ISR(vorber)
11
(
12
wasser=1;
13
)
14
15
16
voidvorbereitung(void)
17
{
18
while(!arbeit_ende)
19
{
20
while(!(UCSR0A&(1<<RXC0)));
21
/* Get and return received data from buffer */
22
x=UDR0;
23
while(!(UCSR0A&(1<<RXC0)));
24
/* Get and return received data from buffer */
25
y=UDR0;
26
while(!(UCSR0A&(1<<RXC0)));
27
/* Get and return received data from buffer */
28
z=UDR0;
29
30
}
31
32
}
33
34
35
voidEinspritzen(void)
36
37
{
38
while(!wasser)
39
{
40
// do many things
41
42
}
43
44
}
45
46
47
intmain()
48
{
49
while(1)
50
{
51
vorbereitung();
52
53
Einspritzen();
54
55
}
56
57
}
Aber das möchte, dass es nach dem Interrupt zu der Funtion Einspritzen()
springt und die Kommunikation wieder initialisiert so dass es auf keine
Zeichen mehr wartet.
vieleicht hat eine ein Idee.
Danke
Du kannst nicht in einen While bereich hinein springen. Machs mit Goto:
beginn:
.
.
.
schleife1:
tuh irgendwas;
if (taster2) goto schleife2;
goto schleife1;
.
.
.
schleife2:
tuh irgendwas;
if (taster1) goto schleife1;
goto schleife2;
.
.
.
goto beginn;
Das sieht nur auf den ersten Blick einfach aus.
Oft verwandelt sich diese 'Einfachheit' ganz schnell in einen Bumerang,
der auf einen zurückschlägt.
Das Beispiel hier schreit doch schon förmlich danach, dass man die in
der ISR gesetzten Flags benutzt!
Goto in einem c-programm ???
leute, leute ... das geht unter "ganz böse", sollte mann vermeiden ...
wegen den zeichen an der UART:
warum empfängst du die zeichen nicht auch per interrupt? dannn
bräuchtest du die while() nicht.
innerhalb der uart_rx ISR in einen buffer schreiben und diesen zu den
richtigen zeiten entweder auswerten oder löschen ...
gruss Claudio
Im Hauptprogramm fragst du einfach zyklisch ab ob str_complete=1 ist und
holst dir die Zeichenkette aus string. Du darfst natürlich das
Rücksetzen der Variablen nicht vergessen.
PS an alle Nörgler: das ist nur ein Vorschlag
Da haben sich schon zwei gegen da "goto" ausgesprochen. Was ist so
schlimm daran? Im Assembler heisst der Befehl JMP oder RJMP und und wird
sehr häufig verwendet... Klärt mich mal auf... so als Neben-Topic...
@ Igor Ebner (anfaenger69)
>Da haben sich schon zwei gegen da "goto" ausgesprochen. Was ist so>schlimm daran?
Es führt meist zu Sphagetticode. Und es ist in C praktisch unnötig, von
gaaaaaaaanz wenige Ausnahmen mal abgesehen, wo man es als Vereinfachung
nutzen KÖNNTE!
Wird aber praktisch nie gemacht, denn man kann jeden Programmablauf
sauber duch die normalen Konstrukte if, for, while, Switch abbilden.
> Im Assembler heisst der Befehl JMP oder RJMP und und wird>sehr häufig verwendet...
Auch der Compiler nutzt die, ist auch OK. Aber sinnvollerweise nur, um
eben die oben genannten Konstrukte zu generieren, welche dann sauber
sind. Gleiches sollte man auch von hand in Assembler tun und solche
sauberen Konstruktionen schreiben. Wilde Sprünge quer durch die Botanik
gibt es auch nicht in einem sauberen Assemblerprogramm!
MfG
Falk
Igor Ebner schrieb:
> Da haben sich schon zwei gegen da "goto" ausgesprochen. Was ist so> schlimm daran?
Eine Analogie:
Man kann seine Kabel einfach zusammenknüdeln und in eine Kiste
schmeissen. Man kann aber auch die Kabel vorher sauber aufrollen und die
Rollen so sichern, dass sich in der Kabellade keine Rolle mit einer
anderen verheddert.
ok danke für Anrregungen.
gibt es nicht eine Möglichkeit es zu machen ohne ein ISR bei RX-Uart zu
nutzen?
Denn mommentan habe ich das gesamte Programm übernommen und es ist
überrall mit Pollin implementiert.
Und wenn ich es mit ISR machen sollte(aufwendig den gesamten Code zu
fummeln, na ja wenn nicht anders geht...), die Daten sind keine Strings
sondern Bytes-Pakette genauso wie ich es oben in meiner Vorgehensweise
dargestellt habe. Wie soll dann nun ihr ISR aussehen?
danke
Man könnte aber auch den immer gleichen Teil in eine eigene Funktion
rausziehen und so auf einfache Art die Fehlbelegung von y oder z
verhindern.
1
uint8_treadValue(uint8_t*pVal)
2
{
3
while(!arbeit_ende&&!(UCSR0A&(1<<RXC0)))
4
;
5
6
if(arbeit_ende)
7
returnFALSE;
8
9
*pVal=UDR0;
10
returnTRUE;
11
}
12
13
voidvorbereitung(void)
14
{
15
while(!arbeit_ende)
16
{
17
if(!readValue(&x))
18
return;
19
20
if(!readValue(&y))
21
return;
22
23
if(!readValue(&z))
24
return;
25
}
26
}
Möglichkeiten gibt es genug, ohne auf einen goto ausweichen zu müssen.
Was in der jeweiligen Situation vernünftig ist und was nicht, hängt zwar
immer von den Umständen ab, aber ein goto ist selten vernünftig (und
wenn dann nur in ganz bestimmten Situationen die hier aber nicht
vorliegen).
danke Karl,
diese Vorgehensweise habe ich auch versucht und es kalpptauch nicht.
Auch die Simulation auf dem Board hat nicht geklappt. an der Schleife
bleibt es bei der simulation hängen und es kann keine Pins mehr gesetzt
werden.
Bei dem Test auf dem wirklichen System läuft das Programm nicht weiter.
Ich habe schon alle mögliche Kombination durchgeführt, aber ohne erfolgt
•
übrigens
arbeits_ende ist in der main.c als globalvariable und volatile
deklariert. in der anderen ".c" wo es verwendet wird, wird er als :
extern volatile ... arbeits_ende.