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
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
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
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???
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
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
Moin, noch als Nachtrag den betroffenen Assemblercode im Anhang.
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
@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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.