Forum: Mikrocontroller und Digitale Elektronik Stackproblem?


von Kurt B. (kurt-b)


Lesenswert?

Hallo Leute,

das hier macht doch sicherlich Probleme.

Mega32 BASCOM

wie kann ich das umgehen?



'--------------------------------------------------------
'----------------- (Timer 0 Interrupt)-------------------
'--------------------------------------------------------

Int_einsprung:

    Incr Takt_zaehler

  If Takt_zaehler > 10000 Then
     Takt_zaehler = 0
     Goto Int_aussprung
  End If


Return

' --------------------------------------------------------------------


Int_aussprung:

 '??? Stack-reparatur

 Goto Anfang


Kurt

von Stefanie B. (sbs)


Lesenswert?

Ähhh, ja

Goto ist eine feine Sache ;-)
1
'??? Stack-reparatur=return
Gruss
Stefan

von Kurt B. (kurt-b)


Lesenswert?

Stefan B. wrote:
> Ähhh, ja
>
> Goto ist eine feine Sache ;-)
>
1
> '??? Stack-reparatur=return
2
>
> Gruss
> Stefan

Ja schon Stefan,

da lande ich aber wieder da wo ich weggesprungen bin.
Ich will aber aus dieser -hängenden- Unterrutine raus
und einfach neu beginnen.

Kurt

von Axel R. (Gast)


Lesenswert?

So vielleicht?


1
Int_einsprung:
2
3
    Incr Takt_zaehler
4
5
  If Takt_zaehler > 10000 Then
6
     Takt_zaehler = 0
7
     Return
8
  End If
9
10
11
Return

von Philipp B. (philipp_burch)


Lesenswert?

Kurt Bindl wrote:
> da lande ich aber wieder da wo ich weggesprungen bin.
> Ich will aber aus dieser -hängenden- Unterrutine raus
> und einfach neu beginnen.

Dann solltest du deine Routine so programmieren, dass sie nicht hängt. 
Also in der betreffenden Schleife eine zusätzliche Abbruchbedingung in 
Form eines Flags einführen, welches du in der ISR setzt. Alles andere 
ist Murks und verhaut dir den Stack. Das würde allenfalls in ASM noch 
einigermassen funktionieren, bei einer Hochsprache bist du immer auf das 
Wohlwollen des Compilers angewiesen.

von Kurt B. (kurt-b)


Lesenswert?

Axel Rühl wrote:
> So vielleicht?
>
>
>
>
1
> Int_einsprung:
2
> 
3
>     Incr Takt_zaehler
4
> 
5
>   If Takt_zaehler > 10000 Then
6
>      Takt_zaehler = 0
7
>      Return
8
>   End If
9
> 
10
> 
11
> Return
12
>

Eigentlich nicht.
Es kommt darauf an das ich nicht mehr da lande wo der Absprung in die IR
gemacht wurde und trotzdem kein unerledigter IR-Rutine-Rest zurückbleibt
(Retten der Register, aufbewahren der Rücksprungadresse).

Kurt

Ps: jetzt ist mir grad was eingefallen.
Es müsste gehen wenn man einfach die Rücksprungadresse so hinbiegt das 
man am Programmanfang oder an einer festgelegten Adresse ankommt.

von Michael U. (amiga)


Lesenswert?

Hallo,

glaub es doch einfach: wenn Du zu solchen Aktionen gezwungen wirst, ist 
Dein Ablaufkonzpt prinzipiell falsch.

In der ISR ein Fehlerflag in einer Variablen setzen und im Hauptprogramm 
an der Stelle sinnvoll auswerten, wo es auf das Ergebnis der ISR 
ankommt.

Die wird ja sicher aus einem sinnvollen Grund aufgerufen...

PS: ich programmiere in ASM, da wäre es prinzipiell kein Problem, sowas 
zu realisieren, trotzdem mache ich es nicht, weil ich keine Lust habe, 
stundenlang selbstgebaute Fehler zu suchen, wenn an dem Programm später 
was geändert wird.

Gruß aus Berlin
Michael

von Karl H. (kbuchegg)


Lesenswert?

Kurt Bindl wrote:

> Ps: jetzt ist mir grad was eingefallen.
> Es müsste gehen wenn man einfach die Rücksprungadresse so hinbiegt das
> man am Programmanfang oder an einer festgelegten Adresse ankommt.


Das ist der sicherste Weg in ein Programm Chaos reinzubringen.
Du weist nicht wann genau die ISR kommt noch weiss die ISR welche
andere Aktion gerade unterbrochen wurde. Es kann sein, dass da gerade
eine Berechnung läuft, die den Stack mit ein paar Zwischenwerten
belastet hat. Es kann aber auch sein, dass genau das momentan nicht
der Fall ist. Niemand weiss das.
In Assembler könnte man das vielleicht noch grade biegen, indem
man bei einem Simulationslauf den benötigten Wert des Stackpointers
ermittelt. Trotzdem macht man das nicht. Aus gutem Grund. Den sowas
ist immer eine latente Gefahr, die nur darauf lauert zuzuschlagen.

Jede kleinste Programmänderung (das muss noch nicht mal heute sein,
dass kann auch in einem halben Jahr sein), wird dann zum Drahtseil-
akt.

von Kurt B. (kurt-b)


Lesenswert?

Hallo Michael, hallo Karl Heinz,

das dürfte wohl so stimmen.

Das "Problem" ist erst aufgetreten nachdem ich bemerkt hab das man unter
COMx.x xx  as Input
und SERIN xx
keine Zeichenpuffer einrichten kann, bzw. ich keinen Weg gefunden hab 
welche einzurichten.

Die Schnittstellen frag ich in jeweils eigenem UP ab.
Wenn nun keine Daten kommen dann wartet halt meine Inkey(#x) ewig.
Eine Pufferabfrage würde zeigen ob überhaupt genügend Zeichen vorhanden 
sind.
Auf Zeichen <> Null geht nicht weil auch das als Zeichen dabei sein 
kann.

Andernfalls müsste ich innerhalb der Rutinen abfragen 
(Ischcharwaiting(x)), aber das scheint auch selbst für ein einzelnes 
Zeichen nicht zu gehen.

Kurt

von Peter D. (peda)


Lesenswert?

Kurt Bindl wrote:

> Die Schnittstellen frag ich in jeweils eigenem UP ab.
> Wenn nun keine Daten kommen dann wartet halt meine Inkey(#x) ewig.
> Eine Pufferabfrage würde zeigen ob überhaupt genügend Zeichen vorhanden
> sind.


Ein Programmiersprachenentwickler kann nicht alles vorhersehen und dann 
muß man eben selber anfangen zu programmieren.
Schön ist es dann natürlich, wenn man für die Bibliotheksfunktionen den 
Quelltext hat, wie es bei C-Programmierung die Regel ist.
Ansonsten ist es besser, sich das Datenblatt zu nehmen und die 
Funktionen komplett selber zu schreiben.
Unter C gibt es reichlich Beispiele für ne UART mit oder ohne 
Software-FIFO inclusive einer Testfunktion, ob Bytes im Puffer sind.

Ich vermute mal, daß es diese Funktion auch unter Bascom gibt. Aber da 
mußt Du selber das Bascom-manual lesen.


> Andernfalls müsste ich innerhalb der Rutinen abfragen
> (Ischcharwaiting(x)), aber das scheint auch selbst für ein einzelnes
> Zeichen nicht zu gehen.

Ob etwas scheint, darauf sollte man als Programmierer nie vertrauen. 
Entweder im Manuel steht, es ist immer so. Oder man muß es selber 
programmieren, daß es so ist.
Es ist unter Bascom nicht verboten, selber zu programmieren und auf die 
Hardware zuzugreifen. Allerdings darf man die Bibliotheksfunktionen und 
die eigenen Funktionen nicht mischen, das gibt Chaos.


Peter

von Paul Baumann (Gast)


Lesenswert?

Man könnte mit:

If UCSRA.RXC=1 then
   Horst=UDR
End If

abfragen, ob ein neues Byte empfangen wurde und wenn das so ist, den 
UART-Inhalt nach "Horst" schieben, um den UART-Puffer wieder zu leeren, 
damit ein neues Zeichen kommen kann.

Guck mal in's Datenblatt, ob der Registername beim Atmega32 so stimmt, 
das
weiß ich aus dem Hut nicht.

MfG Paul

von Kurt B. (kurt-b)


Lesenswert?

Peter Dannegger wrote:


> Ich vermute mal, daß es diese Funktion auch unter Bascom gibt. Aber da
> mußt Du selber das Bascom-manual lesen.

Das gibts schon, jedoch für die Hardware-Uart(s).

Ich werd mirs Einfach machen.
Da die SER-Signale als Stromsignal ankommen ist es ein Leichtes diese 
einfach mit einem Transistor zu -killen-.
Die vorgesehenen Eingänge nehm ich her um die Transistoren zu schalten 
und nur jeweils den gewünschten Kanal freizugeben.
Über Diodenentkopplung kann ich dann auf den Hardware UART gehen und 
einfach so lange zu warten bis genügend Zeichen im Puffer sind.
Wenn nicht dann eben der Rücksprung in die Hauptschleife.


Gruss

Kurt

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
Noch kein Account? Hier anmelden.