Forum: Mikrocontroller und Digitale Elektronik C-Programmierung - µC verrent sich


von Michael (Gast)


Angehängte Dateien:

Lesenswert?

Hallo,

warum funktioniert dieses einfache Unterprogramm nicht (siehe Anhang)?
Es dient dazu, einen Variableninhalt seriell an einem Portpin
auszugeben. Die wait-Routinen sind einfache, nichtstuende Schleifen.

Wird das Unterprogramm Show() im Hauptprog. aufgerufen und durch einen
Interrupt unterbrochen, so stürzt bzw. verrennt sich der µC.

Gibt man nur 8 Bit große Variablen aus, ändert also u16 nach u8 und
i<=15 in i<=7, so funktioniert.

Hat jemand eine Erklärung dafür????

Gruß,
Michael

von Christian (Gast)


Lesenswert?

Hallo Michael,


for(i=0;i<=15;i++)
  {
    if(reg&(1<<i))

Ich vermute das dein Problem da liegt:

        i<=15

Bin mir aber nicht sicher ober der ATMega dort sich weghängt wenn er 15
mal ein bit verschiebt ...


Lg


Christian

von Jens M. (jensbert)


Lesenswert?

Hallo Michael,

andere Theorie: Die 1 wird als Byte betrachtet, mehr als 7 mal
geschoben, wird sie immer zur Null - Schluß mit lustig.

Schlage vor, Du schaust Dir den Assemblercode an, dort sollte das recht
schnell zu erkennen sein.

Als Alternative, die noch dazu schneller ist, empfehle ich Dir eine
Hilfsvariable u16, die Du als Maske benutzt und die bei jedem
Schleifendurchlauf um einen weitergeschoben wird. Natürlich mit 1
initialisiert und schieben nach der Verwendung.

Vielleicht so:
1
void Show(u16 reg)
2
{
3
  u16 mask=1;
4
5
  while ( mask )
6
  {
7
    if(reg&mask)
8
    { SetBit(SHOWPORT,SHOWOUT);
9
      wait100us();
10
      ClrBit(SHOWPORT,SHOWOUT);
11
      wait20us();
12
      wait50us();
13
    }
14
    else
15
    {
16
      SetBit(SHOWPORT,SHOWOUT);
17
      wait20us();
18
      ClrBit(SHOWPORT,SHOWOUT);
19
      wait100us();
20
      wait50us();
21
    }
22
    mask <<= 1;
23
  }
24
}

Gruß

Jens

von billy (Gast)


Lesenswert?

eigentlich logisch dass sich dein controller verrennt, wenn du keine
endlosschleife zum schluß hast. mal überlegt was er nach der
for-schleife machen soll????

wie wär's wenn du danach noch
while(true){}
einfügst???

von Michael (Gast)


Lesenswert?

Hallo zusammen,

zuerst vielen Dank für eure Anregungen!

@Christian: Warum meinst du, dass er mit 15 mal eine for-Schleife
durchlaufen ein Problem haben könnte? Probleme mit 15 mal schieben wäre
die gleiche Theorie wie sie Jens hat.

@Jens: Deine Theorie kann ich nachvollziehen und hört sich logisch an.
Leider funktioniert dein Vorschlag mit der Hilfsvariable als Maske auch
nicht. Die gleichen Symptome stellen sich ein.

@billy: In meinem Hauptprogramm ist die für µC zwingend notwendige
Endlosschleife versteckt. In dieser wird das Unterprogramm Show
aufgerufen und man kann einfach mit einem Oszi die 1er und 0er
auslesen.

Als Anmerkung: Die Unterroutine funktioniert, auch mit Hilfsvariable
mask, solange, bis sie durch einen Timer-Interrupt unterbrochen wird.

Grüße,
Michael

von Jens Mundhenke (Jensbert) (Gast)


Lesenswert?

Hallo Michael,

es verdichtet sich der Eindruck, dass es an Deiner Interrupt-Routine
liegt. Ist natürlich schwierig zu raten, aber vielleicht hat sie ein
Problem mit dem Stack, der ja für die lokale Variable und besonders die
Rücksprung-Adresse verwendet wird.

Ich fürchte, da sind wir mit unserem Latein am Ende...

Gruß

Jens

von Michael (Gast)


Angehängte Dateien:

Lesenswert?

Moin,

noch als Nachtrag den betroffenen Assemblercode im Anhang.

von Michael (Gast)


Angehängte Dateien:

Lesenswert?

Ich denke auch, dass es mit dem Interrupt zusammen hängt. Ich hatte
schon mal etwas Ähnliches. Damals ist ein zweiter Interrupt während des
Ausführend der ersten ISR aufgetreten und hat den µC aus der Bahn
geworfen. Ich verwende übrigens den AVR Tiny26.

Ist es vielleicht ein Problem, dass der Interrupt und das Unterprogramm
Show dieselben wait-Routinen aufruft?

Der Stack umfasst 16 Ebenen.

Gruß,
Michael

von Christian (Gast)


Lesenswert?

@Michael

Ich weiß nicht wie sich der µC verhällt, wenn er über 0
hinausschiebt...

Ich kann es zur Zeit auch nicht testen, da mein Mega16 beim Umzug
flügge geworden ist ...

Poste doch bitte mal den ganzen code ...


Lg


Christian

von Michael (Gast)


Lesenswert?

So, ich glaub ich habs gefunden;

Zum einen, wenn ich die wait-Schleifen nicht per Unterprogramme
realisiere sondern die warteschleifen direkt einbaue funktionierts.
Zum anderen, wenn ich die Werte CSTACK auf 0x2f und RSTACK auf 32 Level
verdopple (IAR-C-Compiler), dann funktionierts auch mit Warteschleifen
in Unterprogrammen.

Verstanden hab ichs aber noch nicht...
Auser, dass der Stack zu klein ist und dadurch Rücksprungadressen
verlohren gehen. Wozu braucht man zwei Stellen,an welchen man den Stack
definieren kann?

@Christian: Den kompletten Code posten fänd mein Cheffe nicht so
toll...

Gruß,
Michael

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.