Kann mir bitte einer sagen warum dieses Programm sich nicht Assemblieren lässt? Es erscheint immer der Fehler "Operand 2 Out Of Range". Kann diesen Fehler jemand beheben? mfg. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;; .include "m8def.inc" ldi r16, 0xff out DDRB, r16 ldi r16, 0x00 out PortB, r16 out DDRC, r16 out PortC, r16 ldi r16, LOW(RAMEND) out SPL, r16 ldi r16, HIGH(RAMEND) out SPH, r16 ; ;:::::::::::::Timerwahl:::::::::::: ; loop: sbis PortC, 0b00000001 rjmp Timer1 sbis PortC, 0b00000010 rjmp Timer2 sbis PortC, 0b00000100 rjmp Timer3 sbis PortC, 0b00001000 rjmp Timer4 sbis PortC, 0b00010000 rjmp Timer5 rjmp loop ; ;::::::::::::::Timer::::::::::::: ; Timer1: sbis PortC, 0b00100000 rjmp Timer1A rjmp Timer1 Timer2: sbis PortC, 0b00100000 rjmp Timer2A rjmp Timer2 Timer3: sbis PortC, 0b00100000 rjmp Timer3A rjmp Timer3 Timer4: sbis PortC, 0b00100000 rjmp Timer4A rjmp Timer4 Timer5: sbis PortC, 0b00100000 rjmp Timer5A rjmp Timer5 ; ;:::::::Ausführen::::::::::::::: ; Timer1A: ldi r16, PortC push r16 ldi r16, 0b00000001 out PortB, r16 ;::::::::Zeitschleife einfügen::::::: ldi R17, $BF WGLOOP01: ldi R18, $A7 WGLOOP11: ldi R19, $D0 WGLOOP21: dec R19 brne WGLOOP21 dec R18 brne WGLOOP11 dec R17 brne WGLOOP01 ldi R17, $02 WGLOOP31: dec R17 brne WGLOOP31 nop nop ;:::::::::::::::::::::::::::::::::::::::: pop r16 out PortC, r16 rjmp Timer1 Timer2A: ldi r16, PortC push r16 ldi r16, 0b00000001 out PortB, r16 ;::::::::Zeitschleife einfügen::::::: ldi R17, $BF WGLOOP02: ldi R18, $A7 WGLOOP12: ldi R19, $D0 WGLOOP22: dec R19 brne WGLOOP22 dec R18 brne WGLOOP12 dec R17 brne WGLOOP02 ldi R17, $02 WGLOOP32: dec R17 brne WGLOOP32 nop nop ;:::::::::::::::::::::::::::::::::::::::: pop r16 out PortC, r16 rjmp Timer2 Timer3A: ldi r16, PortC push r16 ldi r16, 0b00000001 out PortB, r16 ;::::::::Zeitschleife einfügen::::::: ldi R17, $BF WGLOOP03: ldi R18, $A7 WGLOOP13: ldi R19, $D0 WGLOOP23: dec R19 brne WGLOOP23 dec R18 brne WGLOOP13 dec R17 brne WGLOOP03 ldi R17, $02 WGLOOP33: dec R17 brne WGLOOP33 nop nop ;:::::::::::::::::::::::::::::::::::::::: pop r16 out PortC, r16 rjmp Timer3 Timer4A: ldi r16, PortC push r16 ldi r16, 0b00000001 out PortB, r16 ;::::::::Zeitschleife einfügen::::::: ldi R17, $BF WGLOOP04: ldi R18, $A7 WGLOOP14: ldi R19, $D0 WGLOOP24: dec R19 brne WGLOOP24 dec R18 brne WGLOOP14 dec R17 brne WGLOOP04 ldi R17, $02 WGLOOP34: dec R17 brne WGLOOP34 nop nop ;:::::::::::::::::::::::::::::::::::::::: pop r16 out PortC, r16 rjmp Timer4 Timer5A: ldi r16, PortC push r16 ldi r16, 0b00000001 out PortB, r16 ;::::::::Zeitschleife einfügen::::::: ldi R17, $BF WGLOOP05: ldi R18, $A7 WGLOOP15: ldi R19, $D0 WGLOOP25: dec R19 brne WGLOOP25 dec R18 brne WGLOOP15 dec R17 brne WGLOOP05 ldi R17, $02 WGLOOP35: dec R17 brne WGLOOP35 nop nop ;:::::::::::::::::::::::::::::::::::::::: pop r16 out PortC, r16 rjmp Timer5
> Es erscheint immer der Fehler "Operand 2 Out Of Range". > Kann diesen Fehler jemand beheben? Wie wärs mit dir selber? Bei einer Fehlermeldung steht immer die Zeilennummer dabei. Dann suchst du im Quelltext besagt Zeile und siehst nach bei welcher Operation das ist. Wenn du die Operation hast, schaust du in der Doku (entweder online-Doku oder heruntergeladene Papierdoku) nach, welche Einschränkungen für den Operanden 2 in besagtem Befehl gelten. Und dann vergleichst du das mit dem was du hast.
Ich kenne Deine Programmierumgebung nicht, aber: Die Meldung müsste eigentlich eine Zeilennummer enthalten. Dort muss der 2. Operand überprüft werden Ich vermute mal, Du hast einen 16-Bit Operanden genommen, wo nur 8 Bit gehen. Viel Spaß beim Suchen. Wird nicht so schlimm sein!
Nebenbei: ldi r16, PortC push r16 ... pop r16 out PortC, r16 ist nicht ganz das, was dir dabei vorschwebt.
Du solltest Dir in der Befehlssatzdokumentation mal ansehen, was für Operanden der Befehl sbis erwartet. Kleiner Tip: Der zweite Operand muss im Bereich 0...7 liegen! 0b00100000 ist aber deutlich außerhalb davon...
So hab das Programm neu geschrieben! Nun funktioniert es! ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: .include "m8def.inc" ldi r16, 0xff out ddrb, r16 ldi r16, 0x00 out ddrc, r16 out portc, r16 ldi r16, LOW(RAMEND) out SPL, r16 ldi r16, HIGH(RAMEND) out SPH, r16 ; ;:::::::::::::::::::Timerwahl:::::::::::: ; PortEinlesen: in r16, pinc Timer1: cpi r16,0b00000010 brne Timer2 rjmp Timer1W Timer2: cpi r16,0b00000100 brne Timer3 rjmp Timer2W Timer3: cpi r16,0b00001000 brne Timer4 rjmp Timer3W Timer4: cpi r16,0b00010000 brne Timer5 rjmp Timer4W Timer5: cpi r16,0b00100000 brne PortEinlesen rjmp Timer5W ; ;::::::Auf Befehl warten::::::::::::: ; Timer1W: sbic pinc, 0b00000001 rjmp Timer1A rjmp Timer1W Timer2W: sbic pinc, 0b00000001 rjmp Timer2A rjmp Timer2W Timer3W: sbic pinc, 0b00000001 rjmp Timer3A rjmp Timer3W Timer4W: sbic pinc, 0b00000001 rjmp Timer4A rjmp Timer4W Timer5W: sbic pinc, 0b00000001 rjmp Timer5A rjmp Timer5W ; ;::::::::::::::Ausführen::::::::::::: ; Timer1A: in r16, pinc push r16 ldi r16, 0b00000001 out portb, r16 ;::::::::::Zeitschleife hier einfügen:::::::: nop ;:::::::::::::::::::::::::::::::::::::::::::: pop r16 out portc, r16 rjmp Timer1W Timer2A: in r16, pinc push r16 ldi r16, 0b00000001 out portb, r16 ;::::::::::Zeitschleife hier einfügen:::::::: nop ;:::::::::::::::::::::::::::::::::::::::::::: pop r16 out portc, r16 rjmp Timer2W Timer3A: in r16, pinc push r16 ldi r16, 0b00000001 out portb, r16 ;::::::::::Zeitschleife hier einfügen:::::::: nop ;:::::::::::::::::::::::::::::::::::::::::::: pop r16 out portc, r16 rjmp Timer3W Timer4A: in r16, pinc push r16 ldi r16, 0b00000001 out portb, r16 ;::::::::::Zeitschleife hier einfügen:::::::: nop ;:::::::::::::::::::::::::::::::::::::::::::: pop r16 out portc, r16 rjmp Timer4W Timer5A: in r16, pinc push r16 ldi r16, 0b00000001 out portb, r16 ;::::::::::Zeitschleife hier einfügen:::::::: nop ;:::::::::::::::::::::::::::::::::::::::::::: pop r16 out portc, r16 rjmp Timer5W
> sbic pinc, 0b00000001
Immer noch nicht kapiert? sbis und sbic erwarten als zweiten
Operanden keine Bitmaske, sondern die Bitnummer! Und eine Nummer
schreibt man nicht im Binärformat! Du verwechselst das mit sbrs und
sbrc, bei denen braucht's ne Bitmaske.
Außerdem steht in den Forenregeln klipp und klar, dass längerer Code als
Anhang gepostet werden soll und nicht im Thread! Und es gibt hier auch
die Möglichkeit, Code so zu formatieren, dass er besser als solcher
erkennbar und auch besser lesbar ist! Und die Möglichkeit sollte man
auch nutzen...
Im Prinzip ja. Was soll das Programm eigentlich machen? Dein Programm sieht etwas seltsam aus. zb. sind alle TimerxA identisch (oder hab ich da was übersehen)
1 | Timer5A: |
2 | in r16, pinc |
3 | push r16 |
4 | ldi r16, 0b00000001 |
5 | out portb, r16 |
6 | |
7 | ;::::::::::Zeitschleife hier einfügen:::::::: |
8 | nop |
9 | ;:::::::::::::::::::::::::::::::::::::::::::: |
10 | |
11 | pop r16 |
12 | andi r16, 0b11111110 |
13 | out portc, r16 |
14 | rjmp Timer5W |
Die Sequenz von PINC einzulesen und dann das Gelesene (ausser Bit0) auf dem PORTC auszulesen, sieht mehr überhaupt nicht koscher aus. Letztendlich bedeutet das doch, dass du alle Pins (ausser Pin 0) sowohl als Eingang als auch als Ausgang ansiehst (bzw. dort die Pullups von Eingangspins umschaltest). Das ganze ist mehr als undurchsichtig (oder ich bin einfach schon müde). Ich denke mal, das kann man auch wesentlich einfacher machen.
> Ich denke mal, das kann man auch wesentlich einfacher machen.
Richtig. Aber dazu müsste der "Autor" sein Programm verstehen. Dies
scheint hier nicht der Fall zu sein, ich vermute, dass hier
unverstandener fremder Code zusammenkopiert, dupliziert und
verschlimmbessert wurde.
...
Nope Das is eigenentwicklung! Die Timer sind gleich weil man einen Timer seiner Wahl reinmachen kann. Habe nur ein nop drinne weil es sich so besser simulieren ließ! Also wenns interressiert .... bei Conrad gibt es ein Bausatz mit dem man über einen LDR ein Relais bestimmte zeit lang anschalten und dann wieder aus schalten kann. Ich will diesen selbst bauen und ein paar extras noch! Aber abwarten wenn ich heute aufm stk getestet hab stell ich schaltplan noch rein und dann seht ihrs! Also geht mal an alle hier .. nicht immer mit ngativen kommentaren kommen wenn anfänger hier mal ein Code posten!!!! Auch wenn sie oft fehler beinhalten!!!!
Gut, dann ist es Eigenbau, den Begriff "Entwicklung" lasse ich mal außen vor, denn bis zu diesem Stadium fließt noch allerhand Wasser den Rhein hinunter... Ich habe mich nicht intensiv mit Deinem Code auseinandergesetzt, weil ich ihn beim groben Ansehen als sehr uneffizient eingestuft habe, was wohl in den vielen Wiederholungen gleicher Sequenzen, dem Fehlen einer Tastenentprellung und dem Vermeiden von Interrupt oder zumindest Unterprogramm-Aufruf begründet ist. Gut, es ist ein Anfängerprogramm, aber in einer Anfängerphase, wo es noch um das Lernen geht und noch nicht um das Realisieren von Projekten. Der nächste Lernschritt wäre dann das Verwenden eines Unterprogramms für die Warteschleife, die Du fälschlicherweise "Timer" nennst. Und dann sollte die Erkenntnis kommen, dass Du beim Mega8 drei Hardware-Timer mitbezahlt hast, von denen einer reicht, Dir im Hintergrund (also durch Hardware) einen "langsamen" Zeittakt zu generieren, der Dein gesamtes Programm synchronisiert und Warteschleifen unnötig macht. Wenn dann noch die Notwendigkeit einer soliden Tastenentprellung mit Flankenerkennung erkannt und realisiert wurde, dann kann man langsam über die Realisierung von Projekten nachdenken. Nein, ich will es Dir nicht mies reden, Du bist schon auf dem richtigen Weg, aber eben noch ganz am Anfang. Der Weg ist weiter als Du jetzt vermutest. Noch kämpfst Du mit dem Alphabet (Befehlssatz, erlaubte Register und Bereiche), also mit Selbstverständlichkeiten der AVR-Architektur, später wirst Du Dich dann damit beschäftigen, welche Algorithmen die Richtigen sind und wie man sie halbwegs effizient in Assembler formuliert. Vielleicht solltest Du nebenher auch mal schaun, wie es Andere machen. Dazu bieten sich diverse Tutorials an, z.B. das auf dieser Seite oder das AVR-ASM-Tutorial: http://www.mikrocontroller.net/articles/AVR-Tutorial http://www.avr-asm-tutorial.net/ Weiterhin bieten sich die Projekte Anderer in der Codesammlung an: http://www.mikrocontroller.net/forum/codesammlung Durch Analyse einzelner Codesequenzen und Vergleich mit eigenem Code für ähnliche Aufgaben kommt so manche Erkenntnis ganz von alleine, ohne dass man mehrere "persönliche Berater" beschäftigen muss. Noch'n Tip: Drucke Dir aus dem Datenblatt die Tabelle mit dem Befehlssatz aus. Mit dieser Übersicht und der Hilfe zum AVR-Studio geht das Erlernen des Befehlssatzes bedeutend besser und schneller. Gleiches gilt auch für die Tabelle mit der Beschreibung der I/O-Register. Diese ist sehr hilfreich beim Nachschlagen der Namen der I/O-Register und ihrer Bits, und dient dank der Angabe der Seiten-Nummern auch noch als Inhaltsverzeichnis zum Datenblatt-PDF. Dies spart (gerade in der Lernphase) allerhand Zeit und Frust. ...
Gast wrote: > Also geht mal an alle hier .. nicht immer mit ngativen kommentaren > kommen wenn anfänger hier mal ein Code posten!!!! Darum gehts nicht. Aber so wie das Programm aussieht, wärs vielleicht mal ganz gut, wenn dir jemand mit mehr Erfahrung zeigt, wie man das einfacher machen kann. Du willst ja auch was dabei lernen.
Danke Hannes Lux! Ich werde mich daran machen das von dir beschriebene mir anzueigenen! DIESER THREAD KANN GECLOSED WERDEN!!! Es steht nichts nütliches darin...
> DIESER THREAD KANN GECLOSED WERDEN!!!
Glücklicherweise bestimmst Du das nicht.
Dieser Thread kann nämlich immer noch als Beispiel für den nächsten
Anfänger dienen, der da meint, statt eigener Recherche ein halbes
Dutzend Helfer beschäftigen zu müssen.
...
Johannes M. wrote: >> sbic pinc, 0b00000001 > Immer noch nicht kapiert? sbis und sbic erwarten als zweiten > Operanden keine Bitmaske, sondern die Bitnummer! Und eine Nummer > schreibt man nicht im Binärformat! Du verwechselst das mit sbrs und > sbrc, bei denen braucht's ne Bitmaske. Nö, auch sbrc und sbrs wollen eine Bit-NUMMER. Den Unterschied, den du vermutlich meinst, betrifft cbi/sbi und cbr/sbr. /cbi und sbi erwarten eine Bitnummer, wohingegen sbr ein Alias für ori ist und genauso wie sbr eine Maske sehen will.
Sven P. wrote: > Nö, auch sbrc und sbrs wollen eine Bit-NUMMER. > Den Unterschied, den du vermutlich meinst, betrifft cbi/sbi und cbr/sbr. > /cbi und sbi erwarten eine Bitnummer, wohingegen sbr ein Alias für > ori ist und genauso wie sbr eine Maske sehen will. Jou, da haste wahr. Ich wollte noch zur Sicherheit eben nachschauen, hab das dann aber irgendwie nicht mehr gemacht...
Was auch noch auf den ersten Blick auffaellt, ist das Fehlen jeglicher Kommentare. Gast3
> Was auch noch auf den ersten Blick auffaellt, ist das Fehlen jeglicher > Kommentare. Ja, schon, aber diesen Satz habe ich mir verkniffen, da der Quelltext viele Trennzeilen aus Doppelpunkten enthält, die man evtl. als Kommentare bezeichnen kann. Und über den Sinn oder Unsinn dieser Kommentarzeilen möchte ich nicht diskutieren, da es schwer ist, die richtige Menge zu finden. Bei zuwenig geht die Formatierung verloren, bei zuviel ist auf dem Bildschirm zuwenig Platz für den eigentlichen Quelltext. Aber irgendwie habe ich noch nicht gerafft, was das Programm eigentlich mal tun soll. Die Aufgaben (Conrad-LDR-Relais) sind mir irgendwie nicht konkret genug formuliert. Daher kann ich auch nicht helfen, das Programm zu optimieren. Der wichtigste und aufwändigste Schritt bei der Entwicklung eines Programmes ist nunmal die eindeutige unmissverständliche Beschreibung der zu lösenden Aufgabe (mit normalen Worten, also ohne Einsatz einer Programmiersprache). Solange dies nicht klar definiert ist, lohnt es sich nicht, über die Programmierung in einer Programmiersprache nachzudenken. ...
Hallo Gast, meine Vorredner haben ja schon gesagt, das es in deinem Programm noch sehr viele Fehler gibt und vorallem UNGEREIMTHEITEN! Ich habe mich mal bei Conrad umgeschaut und ich glaube ich habe gefunden was du suchst .... Conrad Artikel-Nr.: 190951 - 62 Oder nicht? Dieser Bausatz sieht sehr interessant aus aber ist schwer realisierbar. Also für einen Anfänger! Wenn du möchtest könnte ich dir unter die Arme greifen :) Denn ich finde dieses Modul äuserst interessant ;) mfg. -crack-
So dein Programm ist nicht klar strukturiert aber ich denke wenn man es kommentiert wird es klarer, deshalb werde ich den ansatz so belassen und nur schnell ein paar Änderungen vornehmen! Schau doch einfach mal im AVR Tutorial unter Tasten nach ... da ist ein Beispiel von Peter Dannegger. Dieses werde ich aus Zeitgründen 1:1 übernehmen. Aber dafür sind Beispiele ja da ;) Das mit dem Timer musst du selbst programmieren, da ich wirklich wenig Zeit habe und dies nun nebenbei mache .... Bis heute abend sollte es fertig sein .... Ihr anderen haut mich nicht weil ich seine unübersichtliche Struktur lasse ;)
Sodale das Programm ist fertig ... Ich hab die Idee mit diesen Kommentar "Überschriften" beibehalten :) ist irgendwie witzig ;) Hoff das ist das was du versucht hast zu programmieren .... Du musst jetzt nurnoch die Timer einfügen, da wo das Programm dann einfach irgendwelche Werte an PortB ausgibt ... also bei Timer1A-Timer5A! Hab die ausgaben nur zum testen azfm stk reingemacht .... Wenn dir Timer zu schwer sind, dann nimm delay-loops. Aber das sollte nur eine Notlösung sein, denn elegant ist das nicht!!! mfg. -crack-
Danke für das Programm -crack-! Funktioniert einwandfrei! Aber nehme Delay schleifen da ich keine Timer programmieren kann.
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.