Ich hab mich bisher ganz gut allein durchkämpfen können und einen holprigen, aber funktionierenden Code in Assembler vor mich hingeprogt. (Fragt bitte nicht wie lange ich dafür gebraucht hab ^^.) Jetzt hab ich ne kleine Frage zu Zählern. Ich habe im zu verwendenden AT90S2343 nur 8bit- register. muss aber bis 1220 (00000100 11000100) hochzählen und dann ein Ereignis auslösen. Dazu wollte ich bei Overflow von einem Register das nächste incrementieren und mir damit ein 16-bit Reg. simulieren. Ich bin mir sicher das das auch einfacher geht, das ist mir aber egal ^^. Nun die Fragen: Wenn ich in einem Register einen Overflow bekomme, wie lese ich den aus? Springt der beim nächsten Zählvorgang auf 0 zurück? oder bleibt das Overflow-bit gesetzt? Wie zum Teufel realisiert man eine If-Anweisung in Assembler??? So long, HariboHunter
Die if-Anweisung hab ich bislang in etwa so gemacht: cpi r16, 0x11 breq label1 rjmp label2 label1: ... label2: ...
Hallo HariboHunter, ich bin zwar kein Experte auf dem Atmel AVR, kann Dir aber hoffentlich trotzdem weiterhelfen: Es ist richtig, Du mußt den Überlauf deines LOW-Registers auswerten und dann dein HIGH-Register um eins hochzählen. Allerdings ist es nicht das Overflow-Flag, daß Dir einen Überlauf des Registers anzeigt. Das Overflow-Bit im Prozessor wird gesetzt, wenn ein Überlauf von 0x7F nach 0x80 auftritt. Du aber suchst den Wechsel von 0xFF nach 0x00. Dazu kannst Du am besten das Zeroflag auswerten. In Assembler tust Du das mit dem Befehl BREQ bzw BRNE (Verzweige wenn null / verzweige wenn nicht null). Gruß, Markus_8051 P.S.: laß die armen Haribos in Ruhe!
Ah soo, g kein Wunder wenn ich beim Overflow nix bekomme, na das hilft mir sehr weiter, thx Zur If -anweisung von Marco, breq bedeutet *branch if equal.* Branch bedeutet laut leo.org verzweigen. ahh siehe post von Markus ^^. Das bedeutet das der Pointer nur auf die Sprungadresse geht, wenn der Vergleich des Registers r16 mit der Konstanten Hex.= 1 ist? Wenn ja, dann bin ich fast fertig mit meiner Laboraufgabe, danke für die schnelle Hilfe.
Am einfachsten machst du dir das, wenn du ein niedriges Register (0-15) für eine "0" bereithälst. Anfangs das Register deklarieren .def r15 = null ; oder wie du das nennen willst .def r24 = low_byte .def r25 = high_byte ; nach dem Reset clr null ; und zum hochzählen machste dann einfach inc low_byte ; +1 adc high_byte, null ; wenn überlauf, diesen dazurechnen.. sonst +0 ; zum compare: ldi r16, high(1220) cpi low_byte, low(1220) cpc high_byte, r16 brne label1 ; if... rjmp label2 ; else überspringen label1: ; else label2: ; hier gehts weiter Außerdem kann man sinnvollerweise auch das Carry-Flag benutzen, welches genau für Überläufe gedacht ist.. das funktioniert dann nacher auch in die andere Richtung. Ich habe deine Zahl bewusst auf r25:r24 gelegt, denn dort sollte man auch einfach: adiw low_byte, 1 anwenden können.. es addiert 1 zu einem Doppelregister. Beim Compare mit 16bit-Zahlen muss natürlich auch das Carry berücksichtigt werden.. schade, dass es kein CPCI (compare with carry and immediate..) gibt.
das mit der Variablendeklaration klappt net. wenn ich diese Textzeilen im sourcecode eingebe, .def r23 = null ; oder wie du das nennen willst .def r24 = low_byte .def r25 = high_byte gibt mir das AVR.Studio diese Fehlermeldung. AVRASM: AVR macro assembler 2.0.28 (build 121 Jan 11 2005 10:28:51) Copyright (C) 1995-2005 ATMEL Corporation C:\WINDOWS\Garagentor.asm(8): error: syntax error, unexpected REGISTER, expecting SYMBOL or FUNCTION or REGDEF Assembly failed, 1 errors, 0 warnings Ich würde aber gerne meinen Registern Namen geben, weil das Funktional und elegant ist.
@Dave: Ganz so einfach wie du es beschreiben hast, funktioniert es leider nicht: der INC-Befehl beeinflußt das Carry-Bit nicht! @HariboHunter: Aber ich habe noch einen tollen Befehl in der Befehlsliste gefunden: ADIW ist der Befehl, den Du brauchst: Er behandelt zwei aufeinander folgende Register als 16bit-Wert und addiert eine Konstante hinzu. So einfach, keine Abfrage von irgendwelchen Overflow-bits etc. Gruß, Markus_8051
Ok, dat Teil ist soweit fertig, und wenn ich das nächste mal im Labor bin, kann ich es auch hardwaremäßig ausprobieren. Aufgabenstellung war: Schreiben sie ein Assembler Programm zur Realisierung einer typischen Garagensteuerung. Als Vorgabe war zu Realisieren: Antrieb mit eigenständiger Endabschaltung des Antriebs in beide Laufrichtungen. Ein-Tasten-bedienung der Steuerung. Zeitgesteuerte Beleuchtung der Garage mit Hilfe eines Timer- Interrupts(ca. 80 sec). Kontaktleiste zur vermeidung von verletzungen unten am Tor. das ganze mit einem At90S2343 (Da ich unter eigenständiger Endabschaltung eine Selbsthaltung verstehe, gebe ich nur einen Kurzen Impuls auf die Motoren (hoffe das reicht sonst gebe ich halt noch nen haufen Nop´s dazu ^^.) Damit das Tor Net aufgeht wenn die Kontaktleiste berührt wird, sollte man noch hardwaremäßig eine Verriegelung einbauen (Leiste inaktiv wenn Motoren inaktiv, oder so) Ansonsten denke ich das ich mich von der Assembler- Programierung verabschieden werde, und mich den C-Compilern zuwende... (sind irgendwie praktischer) Ich bedanke mich für die schnelle und gute Hilfe hier im Forum und bleibe sicherlich treu, Vieleicht kann ich auch bald ein paar Fragen beantworten. Greez Florian
und hier ein Garagendingsi was funktioniert so wie der dozent das haben will... ich fand meins aber schöner ^^
Hi Jungs, Bin fertig geworden. Sourcecode auf Anfrage. Greez, Florian
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.