Guten Tag Dieses kleine Programm sollte eigentlich die LEDs an PortD 0 und 1 jeweils beim Betätigen eines Tasters 0 oder 1 an PortB an- und umschalten und beim Betätigen eines dritten Tasters an PortB 2 ausschalten. Die Simulation im AVR-Studio funktioniert wie ich es mir vorstelle, der µC reagiert aber anders. Beim Anschalten sind beide LEDs schwach an und beim Drücken eines Tasters leuchtet die jeweilige LED heller und beim Drücken des Tasters 2 passiert nichts. Ich wäre dankbar, wenn mir jemand die Fehler in meinem Programm erklären könnte und einen passenden Code schreiben könnte. Lg Paul
Hi >Ich wäre dankbar, wenn mir jemand die Fehler in meinem Programm erklären >könnte und einen passenden Code schreiben könnte. Da fehlt die Stackinitialisierung. MfG Spess
Was sollte man nach einem rcall machen? Dieses wäre deine richtige Frage gewesen. Ist Dir die Antwort bekannt?
Und was soll das?
1 | led1: |
2 | sbi portd, 0 |
3 | cbi portd, 1 |
4 | rcall taster1 |
5 | |
6 | taster1: |
7 | sbic pinb, 1 |
Mein Tipp Kommentiere jeden Befehl mit deinem Gedankengang und Du wirst merken das du das zusammengestückelt hast. So wird das nix.
Bin ich leseschwach oder suche ich vergebens nach "RET"? Am Ende eines Unterprogramms nötiger Befehl.
Danke für die Antworten und Fragen. Ich habe mein Programm kommentiert und hoffe, dass Ihr es nachvollziehen könnt. Mir ist jetzt auch das Problem mit dem Stack aufgefallen, nur weiß ich nicht wie ich den sichern soll, ohne das er abläuft. LG Paul
Hi >Mir ist jetzt auch das Problem mit dem Stack aufgefallen, nur weiß ich >nicht wie ich den sichern soll, ohne das er abläuft. Nicht Sichern, sondern Initialisieren . MfG Spess
Schau dir mal die Reihenfolge beim Push und POP an! Richtig wäre z.B. push zl push zh; Speichere auf Stack pop zh pop zl; Vom Stack zurückholen. Stelle Dir den Stack vor als einen Stapel auf dem Du ein Blatt Papier nach dem anderen ablegst. Welches liegt dann immer oben? Richtig das zuletzt hingelegte!
Du hast nicht jede zeile Kommentiert sonst würde dir mehr auffallen. Mensch Maier wir sollen Dir helfen. So mach auch das was Dir gesagt wird. Hättest Du jeden Befehl kommentiert würdest du ein der schwachsinnigen aktionen wie led1: sbi portd, 0 cbi portd, 1 rcall taster1 taster1: sbic pinb, 1 sehen
Toni schrieb: > Bin ich leseschwach oder suche ich vergebens nach "RET"? > > Am Ende eines Unterprogramms nötiger Befehl. Net nachbabeln. Auch das Push würde Ihn nicht helfen. Genau so wenig eine Stackinitialisierung die aber sein muss. Er hat nicht verstanden was er hier macht. Und das verständniss sollte erst mal da sein. Auch wenn er die Stackinitialisierung macht haut es ihm sein PROGRAMM auseinander. wegen einem StackOverFlow
Hi Also, dein Stack ist ja initialisiert. Nun wird bei jedem RCAll die Rücksprungadresse dort eingetragen und bei einem Ret wieder weggenommen. Was dein Assemblerprogramm betrifft...... tja, da ist noch ein weiter Weg. Zuerst, ja, die Initialisierung gehört vor die Programmschleife. Aber was um himmelswillen haben Push und POP in der Schleife zu suchen ? Wer hat dir denn sowas gezeigt ? Zum anderen , es ist nicht grad geschickt, die Abfage der Taster in Unterprogramme zu packen, die du aufgrund der Tasterbetätigung aufrufst. Und wenn du die Taster nach GND schaltest, ist die Bedingung für den Aufruf immer da, solange du die Taster nicht drückst, weil die zugeschalteten Pull-Ups natürlich "1"-Signal auflegen. Mein Vorschlag: Lies zuerst die Eingänge in einer kleinen Sub-Routine in eine Variable.
1 | Read_IO: |
2 | In Reg_A, PIn(x) ; Irgendeinen Port lesen |
3 | LDI Reg_B, 0b11111111 ; Bits invertieren, da Abfrage nach GND |
4 | EOR Reg_A, Reg_B ; damit ist ein gedrückter Schalter auch "1" |
5 | ANDI Reg_A, 0b00001111 ; ungültige Bits ausmaskieren |
6 | STS New_In, Reg_A ; Bspw. die Portbits 0-3 sind Eingänge |
7 | RET |
Nun hast du einen ganzen Zyklus Zeit, mit diesen Informationen zu arbeiten. Es können ja nur die Bits 0-3 gesetzt sein, ja nachdem, welche Schalter dedrückt sind. Entsprechend bearbeitest du eine Variable auf, die für die Ausgabebits steht.
1 | Loop: |
2 | RCALL Read_IO ; Einlesen der Eingänge |
3 | LDS Reg_A, New_I |
4 | ANDI Reg_A, 0b00000001 ; ist Portbit 0 beschaltet ? |
5 | BREQ Next_Bit1 ; Wenn nicht nächsten Eingang prüfen |
6 | RCall Action_eins ; Reaktion auf Eingang 0 |
7 | ; Ausgang schreib in Variable z.B. Out_Port |
8 | Next_Bit1: |
9 | .... ; weitere Bearbeitung |
10 | RCALL Write_IO ; hier schreibst du die Bits aus Port_Out in |
11 | ; den Ausgabeport |
12 | RJMP Loop |
Das ist die klassische "EVA" Methode: Einlesen, Verarbeiten, Ausgeben Für die einzelnen Bearbeitungen rufst du Subroutinen auf.
1 | Action_eins: |
2 | .... |
3 | RET |
4 | |
5 | Action_zwei: |
6 | ..... |
7 | RET |
8 | usw. |
Niemals das RET vergessen und, bevor ich es vergesse: du brauchst kein Push und POP. Erst, wenn du dich an Interrupt-Programme heranwagst, mußt du Registerwerte sichern. Es gibt zwar auch noch andere Verwendung dieser Befehle, aber da bist du noch weit von weg. Gruß oldmax
@oldmax Meinst du so lernt er was? Selber hinter die Fehler kommen bringt was. Und wenn er es nicht schafft seine Gedankengänge aufzuzeigen will er wohl auch nix lernen sondern sucht nur eine fertige lösung.
Hi @Vivil Nun, so ein wenig Anleitung zur Vorgehensweise schadet nicht. So krass wie du seine Fähigkeiten beurteilst, würd ich nicht vorgehen. Jeder hat seine ersten Schritte mal getan und bis zum perfekten Samba sind dann doch ein paar Jährchen vergangen... auch mit viel (liebevoller) Anleitung. Also, gebt ihm eine Chance. Bisher hat er ja nicht gesagt: "Macht mir mal ein Programm....." Gruß oldmax
Vielen Dank oldmax, das weiß ich zu schätzen.
Paul H. schrieb: > Ich wäre dankbar, wenn mir jemand die Fehler in meinem Programm erklären > könnte und einen passenden Code schreiben könnte. oldmax schrieb: > Bisher hat er ja nicht gesagt: "Macht mir > mal ein Programm....." > Gruß oldmax
Walter schrieb: > Paul H. schrieb: > >> Ich wäre dankbar, wenn mir jemand die Fehler in meinem Programm erklären > >> könnte und einen passenden Code schreiben könnte. > > > > oldmax schrieb: > >> Bisher hat er ja nicht gesagt: "Macht mir > >> mal ein Programm....." > >> Gruß oldmax Das alles erbsenzählerei... Wenn man genau so viel Energie reinstecken würde, wie die negativen Bemerkungen, dann würden einige schneller und besser lernen. Respekt @oldmax, weiter machen... BR
Hätte der TE mal seine Gedankengänge aufgezeigt und sich die ARBEIT gemacht diese zu Kommentieren so wäre ihm schon mehr geholfen als er es bräuchte. Nur wer selbst nix machen möchte der sollte auch nix vor die Füsse geschmissen bekommen.Wie war das mit den Perlen????? Sein Code zeigt klar auf das er nicht die Bohne wusste was er da tat. Dieses sollte sich ändern aber nicht damit das man es Ihm schreibt. Selbsterkentniss ist der einzige weg wie man lernen kann. Nun eventuell bekommt er es hin seine Taster ab zu fragen aber gekonnt hat er nix da er vieles noch nicht verstanden hat. Und genau darum geht es das Verständniss schaffen. Aber Ihr macht das schon grins
Vivil ich verstehe ja, dass wenn man seine Fehler selbst korregiert mehr und besser lernt. Das Problem ist aber, dass ich sie nicht sehe, da ich wenig Erfahrung hab. So nun meine Fragen: Wie kann ich den Stack-Over-Flow beheben ? Mit einer Stack initialisierung ist es doch nicht getan oder ? Und die Sequenz von oldmax
1 | Read_IO: |
2 | In Reg_A, PIn(x) ; Irgendeinen Port lesen |
3 | LDI Reg_B, 0b11111111 ; Bits invertieren, da Abfrage nach GND |
4 | EOR Reg_A, Reg_B ; damit ist ein gedrückter Schalter auch "1" |
5 | ANDI Reg_A, 0b00001111 ; ungültige Bits ausmaskieren |
6 | STS New_In, Reg_A ; Bspw. die Portbits 0-3 sind Eingänge |
7 | RET |
wenn ich das richtig verstanden hab, muss man den Wert am Pinx einlesen mit einem EOR und 0xFF Filtern und den Rest der Bits löschen. Da mein Programm so wunderbar ist.. **hust** könnt ihr mir sagen, wo ich die Grundlagen erlernen kann? links oder Buchvorschläge wären sehr gut. Mit dem Tutorial auf dieser Seite komme ich nicht ganz zurecht. LG Paul
Ich kann wieder nur schreiben. Kommentiere jeden deiner Befehle in deinem Code und schon wirst du es bemerken und etwas lernen.
Hallo Paul Ich finde das Tutorial echt super hier. Angefangen zu programmieren hab ich ebenfalls in Assembler. Das ist für eine Simulation viel besser als "C". (Meine Meinung) Ich hatte damals das Buch "AVR-RISK Mikrocontroller" vom Franzis Verlag. Die darin verwendeten Controller sind zwar veraltet, aber dafür ist die Hardware super beschrieben und auch viele Programm Beispiele mit Erklärung dabei. Grüße Steffen
Hab dir mal eine Seite wo der Stack erklärt ist rausgesucht. Ich hoffe man kann es lesen..
Moin hast du dir das schon durchgelesen ? http://www.mikrocontroller.net/articles/AVR-Tutorial:_Stack Gruß Lordi
Hi Nun, die Tutorials hier sind auch für mich sehr hilfreich gewesen und haben mir den Einstieg in die µC Welt erleichtert. Allerdings muß ich gestehen, das ich bereits in den 80ern mit Assembler und Z80 erste Begegnungen hatte. Ok, genug Geschichte. Schau mal bei den Kollegen von AVR-Praxis rein. Die haben einen Artikel zu "Keine Angst vor Assembler" unter FAQ's. Vielleicht hilft er dir etwas weiter. Wie andere und auch ich bereits erwähnten, ist die Kommentierung von Programmen hilfreich. Wenn du deine Gedanken, wie der Schritt arbeiten soll, aufschreibst, wird dir manchmal schon bei der Programmierung klar, das es so nicht funktionieren kann. Zu meinen Erklärungen, Portbits einzulesen. Du musst wissen, wir alle sitzen zig Kilometer von dir und deinen Gedanken weit weg. Immer mitzuschreiben, welche Portbits du einliest ist müßig, daher schreib ich einfach PortX. Welcher Port das sein soll, keine Ahnung, aber du weißt es und brauchst also nur den Buchstaben dafür einzusetzen. Nun zu den Bits. Wenn du über In einen Port einliest, hast du immer die 8 Byte, also auch bits, die dich nicht interessieren. Wenn du aber deine Eingänge nach "0", also GND beschaltest, ist der Eingang immer wenn er nicht gedrückt ist "1" durch den internen Pull-Up Widerstand. Wenn du also ein Bitmuster 01011000 liest, ist der Schalter Bit 5 und Bit 7 möglicherweise betätigt. Die Bits 0-2 sind keine Eingänge, erscheinen aber wie gedrückte Schalter. Also mußt du alles, was nicht von Interese ist ert einmal ausblenden. Da aber "0"en zu Denkfehlern führen, drehe ich erst mal die Bits mit einer EOR Anweisung. Danach sind die Bits mit den betätigten Eingängen "1". Nun wird über eine Und-Anweisung noch ausgeblendet, was nicht zu den Eingängen gehört. Geht sicherlich auch anders, aber an dieser Stelle habe ich nun die Möglichkeit, eine Flanke von einem Signal zu erfassen. Wie auch immer, jeder hat so seine Vorlieben, was den Programmierstil betrifft. Die Autoren von Büchern schreiben so oft Liebesromane, aber alle unterschiedlich, obwohl am Ende Adam seine Eva kriegt.... Gruß oldmax
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.