Atmega 16 Funktion in sich selbst aufrufen

Gast #3849463
Lesenswert?

Hey Leute.

Ich habe hier mit einem Programm auf einem Atmega 16 etwas 
schwierigkeiten.

Ist es möglich eine Funktion in sich selbst als "Loop" aufzurufen?

Wenn nein, wie würde man sowas am besten lösen?

Die Funktion und somit der Loop überprüfen ob ein Pegel für eine gewisse 
Zeit auf low sind. ist dies gegeben soll die Funktion beendet werden. 
Der Microkontroller stürzt mir aber nach einer sekunde ab und gibt mir 
auf dem Display nur noch Müll raus.

Wenn ich die Funktion nicht aufrufe läuft das Programm.

zum Progi:
1
void dcf_sync(void)
2
{
3
  show_matched_date(0,1);
4
  show_matched_time(0,2);
5
  //LED_DATA |= (1<<4);
6

7
  set_cursor(19,1);
8
  lcd_data('?');
9
  //LED_DATA |= (1<<4);
10
  //LED_DATA &= ~(1<<5);
11

12
  if(!(PINA & (1<<PA0)))
13
  {
14
    if(counter_low>=1750 && counter_low<=1950)
15
    {
16
      set_cursor(19,1);
17
      lcd_data('!');
18
      //LED_DATA &= ~(1<<4);
19
      //LED_DATA |= (1<<5);
20

21
      counter_reset();
22
      dcf_date_reset();
23
      dcf_time_reset();
24
    }
25
    else
26
    {
27
      counter_low=0;
28
      dcf_sync();
29
    }
30
  }
31
  else
32
  {
33
    dcf_sync();
34
  }
35
}
Gast #3849471
Lesenswert?

>Ist es möglich eine Funktion in sich selbst als "Loop" aufzurufen?

Ja, das nennt man rekursiv.

>Der Microkontroller stürzt mir aber nach einer sekunde ab und gibt mir
>auf dem Display nur noch Müll raus.

Kein Wunder. Wenn man die Anzahl der rekursiven Aufrufe
nicht begrenzt frisst es dir den Stack auf. Folge: Absturz.

Das hab ich dem Typen der den Code geschrieben hat aber glaube
ich vor langer Zeit schon mal gesagt;)
#3849472
Lesenswert?

Blauer Blitz schrieb:
> Ist es möglich eine Funktion in sich selbst als "Loop" aufzurufen?
>
> Wenn nein, wie würde man sowas am besten lösen?

Also ob man sowas macht weiß ich nicht aber wenn dann würde ich auf 
jeden Fall einen Watchdog mit laufen lassen damit man auch wieder raus 
kommt. Bisher war ich aber nie in der Verlegenheit eine Funktion in sich 
selbst aufzurufen.

Blauer Blitz schrieb:
> Die Funktion und somit der Loop überprüfen ob ein Pegel für eine gewisse
> Zeit auf low sind. ist dies gegeben soll die Funktion beendet werden.

Klingt nach typischer Aufgabe für einen Timer. Ist es ein 
Digital-Eingang? Dann würde ich das über die Interrupt-Funktionen (z.B. 
über INT0 und nen Timer) lösen.
Gast #3849507
Lesenswert?

Michael Köhler schrieb:
> Also ob man sowas macht weiß ich nicht aber wenn dann würde ich auf
> jeden Fall einen Watchdog mit laufen lassen damit man auch wieder raus
> kommt. Bisher war ich aber nie in der Verlegenheit eine Funktion in sich
> selbst aufzurufen.

Die Sache dem Watchdog zu überlassen, ist eine ziemlich blöde Idee. Der 
einzige Vorteil wäre, dass der µC nicht nur einmal, sondern regelmäßig 
abstürzt ;-(
Gast #3849524
Lesenswert?

Das angenehme in dieser Implementierung ist, dass es sich um eine 
Tail-Recursion handelt, sogar in beide Fällen, in denen eine Rekursion 
stattfindet. Das kann man dann ganz einfach umschreiben in:
1
void dcf_sync(void)
2
{
3
repeat:
4
  ...
5
  if ...
6
  {
7
    if ...
8
    {
9
    }
10
    else
11
    {
12
      counter_low=0;
13
      goto repeat:
14
    }
15
  }
16
  else
17
  {
18
    goto repeat:
19
  }
20
}
womit wir die Rekursion in eine Schleife umgewandelt hätten. Bleibt als 
Hausaufgabe nur mehr, das ganze in (z.B.) eine While-Schleife 
umzumodeln...
Gast #3849525
Lesenswert?

Ok danke für die sehr schnellen und hilfreichen Antworten :)

Ich hab das Problem mit nem while(1) ner "if" Abfrage einer Variabel und 
men break; gelöst. Ist zwar nicht die feine Art aber funktioniert :D

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren