Hmm..nagut, nun erwartest du ja was von mir*zitter* *g*
Ich hoffe, ich bekomm es hin, will dich ja nicht enttäuschen.
Werd mich da noch ein wenig dran setzen, bevor ich schlafen geh.
Gruß
Thomas
Ja das wäre die Voraussetzung um die Aufgabe zu lösenNochmal zur Zeit. Wie weiß ich denn, wieviel Mhz ich hab?![]()
Was hast Du für ein Board ?
ist da kein Quarz zu sehen? wenn ja müßte es drauf stehen....
vielleicht steht Dein Mega noch auf Internen Takt![]()
Vielleicht kannst Du Deine Fusebits auslesen, aber mit auslesen meine ich auch auslesen und nicht setzen !!!!!!!
Wenn nicht dann gehe von 4 MHz aus.
Sehr gut überlegt =D>Ich muss ja irgendwie auf 1 Hz kommen, damit er im Sekundentakt abfragt, oder?
Es ist weder zu spät noch kanst Du nicht rechnen,Entweder es ist schon zu spät, oder ich kann nicht mehr rechnen, ich weiß einfach net, wie ich auf die 1Hz kommen soll. Also was ich anstatt von "255-254" eintragen soll.
die Frage habe ich erwartet, was meinst Du ? Ich wollte Dir die Aufgabe nicht zu leicht machen [-X
Ein kleiner Schupser auf den richtigen Gleis ->
Du kannst nicht mehr langsamer werden mit einem 8 Bit Timer, das hast Du richtig erkannt....
Das muß doch irgendwie anders zu lösen sein![]()
Vielleich einen geraden Teiler einer Sekunde![]()
1/50 vielleicht 1/100 ? 1/200![]()
![]()
Bedenke Du hast noch jedemenge Register frei , vielleicht eine Variable ? Man kann doch Register als Vabiablen Benutzen...... in so ein Register passt ja was zwischen 0 und 255
So schluß, gehe jetzt pennen, lass Dir Ruhig Zeit damit, wenn Du irgandwann die Tage
ein Programm mit der Lösung hast, dann bin ich stolz auf Dich, und auf mich auch, weil ich Dir dann doch was beigebracht habe...
Aber nicht schummeln ! wäre gut wenn Du das selber hinkriegst!!!!!
Gruß Sebastian
Hmm..nagut, nun erwartest du ja was von mir*zitter* *g*
Ich hoffe, ich bekomm es hin, will dich ja nicht enttäuschen.
Werd mich da noch ein wenig dran setzen, bevor ich schlafen geh.
Gruß
Thomas
Hallo Thomas!
Es ist wirklich nicht leicht, aber es ist auch für einen Anfänger zu schaffen!
Sebastian hat Dir das so schön erklärt, ich glaube an Dich! *g*
Am Besten nimmst Du Dir einen DIN A4 Zettel zum schmieren und kritzelst ersteinmal drauflos.
Es kann entweder leicht grafisch sein, oder eher Stichworte, Hauptsache Du verstehst, was Du da machst!
Noch ein kleiner Tipp, ich hoffe Sebastian verzeiht mir, auf http://www.avr-asm-tutorial.net/avr_...ner/index.html (siehe Seite 1) findest Du alles, was Du brauchst!
Ich finde die Seite sehr gut, zwar für manchen Anfänger etwas unverständlich, aber ich glaube an Dich! *g*
Wenn Du dort Zählroutinen mit Branchbefehlen findest, dann bist Du richtig! ;o)
Viel Erfolg und bleib uns bei den ASM'lern erhalten! *g*
Hab schon intensiv drüber nachgedacht, aber die Tipps von Sebastian helfen mir leide nicht. Ich weiß einfach nicht, wie ich da noch ein zusätzliches Register einbauen soll. Denn der Timer zählt ja im Hintergrund hoch und löst das Interrupt aus, wenn er überläuft. Ich muss dem Timer irgendwie sagen, dass er mehrmals hochzählen soll (sodass dann 1 Sekunde vergangen ist) und erst dann das Interrupt auslösen soll. Aber das geht ja nicht.
Obwohl..doch...man kann doch ein Register immer um 1 (dezimal) erhöhen. Ja, das ist es doch (glaub ich) Muss mir nachher mal den Befehl raussuchen. Und wenn er dann bei einem bestimmten Faktor angekommen ist, dann (und nur dann) soll er das Interrupt auslösen. Bzw. das Interrupt soll er ja eh auslösen, aber dann prüft er erst nochmal, ob 1 Sekunde vergangen ist.
@Florian: Die Seite befasst sich ja mehr mit dem Befehl "nop", ich solls aber (laut Anweisung) mit dem Interrupt Timer0 machen.
Hmm..nagut, ich hoffe ihr habt mein Durcheinander verstanden, wenn nicht, heut abend folgt auf jeden Fall Code (ob er funktioniert, weiß ich jetzt noch nicht *g*)
Gruß
Thomas
[edit]
Kann man im Debug-Modus (also beim Simulieren im AVR-Studio) irgendwie den Timer auch überlauen lassen? Denn ich kann so oft wie ich will F11 drücken, er löst nie den Interrupt aus. Deswegen kann ich auch nicht genau rüfen, wann und wie er meine Befehle ausführt.
Hallo Thomas!
Du bist schon auf dem richtigen Weg zum Ziel, Du hast verstanden, dass es nicht mehr darum geht den Timer zu verändern, sondern seine Interrupts zu zählen und bei einer Sekunde den interrupt weiterzuleiten!
Bei den nop's stehen aber noch ganz wichtige Befehle, die Branch-befehle!
Ja, ich kenne das Durcheinander, ich hab's verstanden! *g*
Das ist der wichtigste Punkt!Obwohl..doch...man kann doch ein Register immer um 1 (dezimal) erhöhen. Ja, das ist es doch (glaub ich) Muss mir nachher mal den Befehl raussuchen
Mit dieser Aussage hat Du die Aufgabe schon fast gelöst,
Du mußt Die nur überlegen wann der Register um 1 erhöht wird, und wo verglichen wird.
Die Befehle, die Florian meint erkennst Du am br.. z.B brne Springe bei ungleich breq Springe bei gleich usw.
@Florian
Ich finde die Seite Hammer !Ich finde die Seite sehr gut,
Habe Sie auch schon dem Thomas empfohlen
Gruß Sebastian
Habe ich schon gesehen! ;o)Habe Sie auch schon dem Thomas empfohlen
Ich habe ihm mit den Branch's ein wenig geholfen, da ich dachte, dass er diese nicht so schnell zuordnen können wird!
Ich hatte auch ganz zu Anfang immer mit diesen ganzen BR's Schwierigkeiten, mittlerweile kenne ich alle wichtigen auswändig! ;o)
Hallo Sebastian!
Ich denke auch, bisher macht er das sehr gut!Aber ich denke der Thomas schlägt sich gut durch, oder?![]()
Er lernt schneller als ich bei meinen Anfängen, aber mir hat's ja auch keiner erklärt! ;o)
Ja, das denke ich auch, ich finde es aber sehr mutig von ihm, dass er das wagt! ;o)Es ist sicher nicht so einfach für einen Einsteiger Assembler zu lernen...
Ich finde Assembler auch sehr schön und es macht mir Spass!
Und was man dabei alles über den µC lernt ist auch nicht ganz unbedeutend!
Stimmt, gute Idee! -> siehe PN!Wenn Du magst kannst Du mir eine PN schicken, damit wir Diesen Thread nicht unnötig damit belasten ?
Viele Grüße
Florian
So,
nun blinkt es zwar, aber nicht im Sekundentakt. Hier mal der Code:
Hab auch schon versucht, diese Zeile hier "cpi zaehler, 0b01000010" durch "cpi zaehler, 0b11111111" das hier zu ersetzen. Aber blinkt immer noch so schnell.Code:.include "m8def.inc" .equ time = 255 -254 ;Damit wird der Timer vorgeladen .equ sperre = 7 .equ LED = PB2 ;LED an B.2 .def tmp = r16 ;Mein Universallregister .def status = r17 ;Mein Statusregister, ob LED an oder aus ist .def zaehler = r18 ;Mein Zählregister .org 0x000 rjmp reset ;Interruptvektor "reset:" .org OVF0addr rjmp pruefZaehler ;Interruptvektor für Timer0 Überlauf, hier springt ;das Programm hin, wenn der Timer überläuft reset: ;Stack einrichten ldi tmp, HIGH(RAMEND) ;HIGH-Byte der obersten RAM-Adresse out SPH, tmp ldi tmp, LOW(RAMEND) ;LOW-Byte der obersten RAM-Adresse out SPL, tmp sbi DDRB, LED ;B.2 als Ausgang cbi PORTB, LED ;B.2 auf LOW stellen -> LED aus am Anfang cbr status, (1<<sperre) ;Statusregister r17.7 = 0 setzen (LED aus) ;Timer Register werden belegt, hier Timer 0 ldi tmp, (1<<CS02) | (1<<CS00) ;prescaler ist 1024 out TCCR0, tmp ;Register TCCR0 ist für den Prescaller zuständig ldi tmp, (1<<TOIE0) ;Hier werden Interrupts nach Timer0 Überlauf eingeschaltet out TIMSK, tmp ;Register TIMSK ist dafür zuständig ldi tmp, time ;Hier wird der Timmer vorgelaen und zwar mit 255-254 out TCNT0, tmp ;Er läuft 254 mal durch, bevor ein Interrupt auftritt sei ;Interrupts zulassen loop: rjmp loop ;Immer wieder selbst aufrufen -> Endlosschleife pruefZaehler: inc zaehler ;Zählregister um 1 erhöhen cpi zaehler, 0b01000010 ;Wenn Zählregister = 65 ist breq zeitum ;spring zu "zeitum:" wenn zaehler = 65 zeitum: clr zaehler ;Zählregister auf 0 setzen push tmp ;Rette Universallregister in tmp, SREG ;Rette Statusregister push tmp sbrs status, sperre ;überspringe, wenn r17.7 = 1 ist (LED an?) rjmp zeitum0 ;zu "zeitum0:" springen sbrc status, sperre ;überspringe, wenn r17.7 = 0 ist (LED aus?) rjmp zeitum1 ;zu "zeitum1:" springen zeitum0: sbr status, (1<<sperre) ;r17.7 = 1 setzen (LED an) sbi PORTB, LED ;B.2 = 1 setzen -> LED an rjmp zeitum2 zeitum1: cbr status, (1<<sperre) ;r17.7 = 0 setzen (LED aus) cbi PORTB, LED ;B.2 auf 0 setzen -> LED aus rjmp zeitum2 zeitum2: pop tmp ;stelle SREG wieder her out SREG, tmp pop tmp ;stelle Universalregister wieder her reti ;die Interrupt-Routine wird verlassen ;und es wird weiter im Hauptprogramm gearbeitet
Aber eigentlich müsste 65x richtig sein. Denn
4MHz / 1024 / 254 = 65 Hz = ca. 15,4ms
Und bei 1 Sekunde muss ich 65 mal die 15,4ms ablaufen lassen.
Hab eben noch versucht, nach "breq zeitum" ein "reti" einzufügen. Nun blinkt er sehr viel langsamer, aber langsamer als 1 Sekunde. Wenn ich nun anstelle von "cpi zaehler, 0b01000010" das hier eintrage: "cpi zaehler, 0b00010000", dann isses knapp ne Sekunde, die er dann immer blinkt. Aber ist ja bestimmt nicht eine Sekunde, sondern auf gut Glück eben, aber es muss ja auch rechnerisch gehen.
Bin denk ich schonmal aufm sehr guten Wege. Nur der letzte "Feinschliff" fehlt eben noch
Gruß
Thomas
Hallo Thomas!
Das sind die ersten Sachen, die mir auffiehlen!
Du musst unter das "breq zeitum" in "pruefZaehler" noch ein reti einsetzen, um zum "loop" zurückzukehren und den Interruptflag wieder zu aktivieren!
Wäre das nicht, dann spränge das Programm immer locker entweder über "breq" zu "zeitum", wenn das gleich 65 ist, oder er geht gleich weiter zu "zeitum", da er ja nicht zurückgeschickt wird!
Außerdem hast Du noch einen logischen Fehler im Programm, dazu komme ich aber später! ;o)
Lesezeichen