- MultiPlus Wechselrichter Insel und Nulleinspeisung Conrad         
Seite 11 von 53 ErsteErste ... 91011121321 ... LetzteLetzte
Ergebnis 101 bis 110 von 524

Thema: Tutorial für alle Assembler-Anfänger _

  1. #101
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    Anzeige

    Powerstation Test
    Da der Interrupt ausgelöst wird, wenn der Zähler auf 0 springt, muss es doch heissen.

    .equ timer = 256 - 90
    Gut das Du das ansprichst, sorry, es muß wirklich so heißen,
    somit haben wir ein Takt mehr, also wieder ein paar µs gewonnen

    Gruß Sebastian

  2. #102
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    29.07.2005
    Ort
    Berlin
    Alter
    39
    Beiträge
    289
    Hmm...die Aufgabe ist schon ziemlich schwer. Also die Interruptroutine ist doch eigentlich indirekt auch zeitum, zeitum1 und zeitum2, oder? Denn dort springt er ja in preufZaehler hin. Oder brauch ich zeitum, zeitum1 und zeitum2 gar nicht anrühren und nur pruefZaehler und die loop ändern?

    Gruß
    Thomas

  3. #103
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    52
    Beiträge
    2.236
    alles was zwischen preufZaehler und reti steht, wird in dem interrupt abgearbeitet ja, nachdem Du Fertig bist soll dazwischen nur inc zahler und Timer neuladen stehen der rest im Hauptprogramm, komm das schafst Du.

    Ich geh jetzt schlafen, wie gesagt lass Dir ruhig zeit damit,
    Du weiß genug um das zu lösen.

    Gruß Sebastian

  4. #104
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    29.07.2005
    Ort
    Berlin
    Alter
    39
    Beiträge
    289
    Ok, dann hab ich ja richtig gedacht, also dann bis morgen, werd mal schaun, ob ichs heut noch hinbekomm.

    Gruß
    Thomas

  5. #105
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    29.07.2005
    Ort
    Berlin
    Alter
    39
    Beiträge
    289
    Ging schneller, als ich gedacht hab
    Zu deinen Fragen:
    1. Hmm...weil die Datei nun um 0,06kb kleiner geworden ist? *g* Ich weiß es nicht, hab auch deine Posts weiter oben gelesen, aber nichts brauchbares gefunden
    Vielleicht dient das auch der Geschwindigkeit des Programms. Denn wenn er schneller auf ein "reti" trifft, wird das Interrupt auch schneller wieder freigegeben. Ist aber nur reine Vermutung. Kann mir das leider nicht wirklich vorstellen. Hoffe, dassde nun nicht enttäuscht von mir bist, weil ich eine so leichte Frage nicht beantworten kann
    2.
    Code:
    .include "m8def.inc"
    
    .equ time = 256-90			;Damit wird der Timer vorgeladen
    .equ LED = PB2				;LED an B.2
    .def tmp = r16				;Mein Universallregister
    .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
    
    	;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-90
    	out TCNT0, tmp					;Er läuft 90 mal durch, bevor ein Interrupt auftritt
    	sei								;Interrupts zulassen
    
    loop:
    	cpi zaehler, 0b00101000		;Wenn Zählregister = 14 ist
    	breq zeitum					;dann spring zu "zeitum:"
    
    	rjmp loop					;Immer wieder selbst aufrufen -> Endlosschleife
    
    zeitum:
    	clr zaehler					;Zählregister auf 0 setzen
    	sbic PINB, LED				;überspringe, wenn B.2 = 0 ist (LED aus?)
    	rjmp zeitum1				;wenn B.2 = 1, dann spring zu "zeitum1:"
    
    zeitum0:
    	sbi PORTB, LED				;B.2 = 1 setzen -> LED an
    	rjmp loop					;wieder zur loop springen
    
    zeitum1:
    	cbi PORTB, LED				;B.2 auf 0 setzen -> LED aus
    	rjmp loop					;wieder zur loop springen
    
    pruefZaehler:
    	inc zaehler					;Zählregister um 1 erhöhen
    	ldi tmp, time				;Hier wird der Timer vorgelaen und zwar mit 255-90
    	out TCNT0, tmp				;Er läuft 90 mal durch, bevor ein Interrupt auftritt
    	reti						;wieder zurück, wo du hergekommen bist
    Wenigstens hab ich die programmiertechnische Aufgabe gelöst, ich hoffe doch richtig

    Gruß
    Thomas

    Achja, stimmt der Kommentar bei dieser Zeile?
    out TCNT0, tmp ;Er läuft 90 mal durch, bevor ein Interrupt auftritt

  6. #106
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    Eine teufliche Fußangel hast du noch drin.

    Da ist zunächst deine Hauptschleife:
    Code:
    loop:
       cpi zaehler, 0b00101000      ;Wenn Zählregister = 14 ist
       breq zeitum               ;dann spring zu "zeitum:"
    
       rjmp loop               ;Immer wieder selbst aufrufen -> Endlosschleife
    Das sieht ganz unschuldig aus.
    Jetzt stell dir vor, nach dem cpi gibt es einen IRQ (Interrupt ReQuest), daß also eine Interrupt Anforderung vorliegt.

    Mit cpi hast du das SREG (Status Register) verändert.
    Es hat verschiedene Flags, die das Ergebnis des Vergleiches darstellen wie 'größer als', 'gleich', etc.

    Danach testest du mit breq das Z-Flag (Zero). Es ist gesetzt, wenn zahler-0b00101000 gleich 0 ist. In diesem Falle springst du nach zeitum.

    Aber erst kommt deine Interrupt Service Routine (ISR) zum Zug:
    Code:
    pruefZaehler:
       inc zaehler               ;Zählregister um 1 erhöhen
       ldi tmp, time            ;Hier wird der Timer vorgelaen und zwar mit 255-90
       out TCNT0, tmp            ;Er läuft 90 mal durch, bevor ein Interrupt auftritt
       reti                  ;wieder zurück, wo du hergekommen bist
    Das inc erhöht zaehler um 1 und setzt u.a. das Z-Flag:
    Z=1, falls das Ergebnis=0 ist; Z=0 sonst.
    Die darauf folgenden Befehle tasten das Z nicht mehr an, und nach dem reti landest du beim breq von loop.

    Das breq wird also dann verzweigen, wenn
    - zaehler=0b00101000 (=0x28 = 40) ist, und es nach den cpi kein IRQ gibt oder
    - zaehler=0b11111111 ist in loop, und es nach dem cpi ein IRQ gibt.

    Auf das SREG kannst du mit in und out zugreifen, da fällt dir bestimmt was ein...

    Gruß, Georg-Johann
    Disclaimer: none. Sue me.

  7. #107
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    29.07.2005
    Ort
    Berlin
    Alter
    39
    Beiträge
    289
    Ich versteh leider nicht, was du meinst
    Ich hab doch gar kein Statusregister mehr. Das haben wir doch rausgenommen. Und funktionieren tuts ja auch, also die LED blinkt ja im 1 Sekundentakt.
    Vlt. kannste das ja nochmal kindergerecht erläutern, auch wenn mein Alter was anderes sagt *g*

    Gruß
    Thomas

  8. #108
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    Da hast du was verwechselt.

    SREG ist ein Hardware-Register, das alle AVRs haben. Wenn du zB ein sei Befehl machst, setzt du dadurch das I-Bit im SREG.
    Andere Hard-Register sind zB PORTB, SPL, SPH, ...
    Schau mal in das Kurzdatenblatt zum Mega8. SREG ist das erste Register im IO-Bereich ("Register Summary").
    Welche Flags im SREG durch einen Maschinenbefehl verändert werden, steht in der Tabelle zu "Instruction Set Summary" in der Spalte "Flags".
    Disclaimer: none. Sue me.

  9. #109
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    29.07.2005
    Ort
    Berlin
    Alter
    39
    Beiträge
    289
    Axo, hab nu auch deinen Post verstanden. Also du meinst, direkt nach dem Befehl cpi, wenn dort die Interrupt-Routine aufgerufen wird? Nun hab ich das dann so geändert, bin mir aber nicht sicher, ob das so richtig ist. Die LED blinkt aber immer noch im 1 Sekundentakt.
    Code:
    .include "m8def.inc"
    
    .equ time = 256-90			;Damit wird der Timer vorgeladen
    .equ LED = PB2				;LED an B.2
    .def tmp = r16				;Mein Universallregister
    .def statusreg = r17      ;Mein Statusregister
    .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
    
    	;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-90
    	out TCNT0, tmp					;Er läuft 90 mal durch, bevor ein Interrupt auftritt
    	sei								;Interrupts zulassen
    
    loop:
                    in statusreg, SREG      ;SREG sichern
    	cpi zaehler, 0b00101000		;Wenn Zählregister = 14 ist
    	breq zeitum					;dann spring zu "zeitum:"
    
    	rjmp loop					;Immer wieder selbst aufrufen -> Endlosschleife
    
    zeitum:
    	clr zaehler					;Zählregister auf 0 setzen
    	sbic PINB, LED				;überspringe, wenn B.2 = 0 ist (LED aus?)
    	rjmp zeitum1				;wenn B.2 = 1, dann spring zu "zeitum1:"
    
    zeitum0:
    	sbi PORTB, LED				;B.2 = 1 setzen -> LED an
    	rjmp loop					;wieder zur loop springen
    
    zeitum1:
    	cbi PORTB, LED				;B.2 auf 0 setzen -> LED aus
    	rjmp loop					;wieder zur loop springen
    
    pruefZaehler:
                   	inc zaehler					;Zählregister um 1 erhöhen
    	ldi tmp, time				;Hier wird der Timer vorgelaen und zwar mit 255-90
    	out TCNT0, tmp				;Er läuft 90 mal durch, bevor ein Interrupt auftritt
                    out SREG, statusreg      SREG wiederholen
    	reti						;wieder zurück, wo du hergekommen bist
    Gruß
    Thomas

  10. #110
    Erfahrener Benutzer Robotik Einstein Avatar von SprinterSB
    Registriert seit
    09.06.2005
    Ort
    An der Saar
    Beiträge
    2.802
    Zitat Zitat von toeoe
    Und funktionieren tuts ja auch, also die LED blinkt ja im 1 Sekundentakt
    [-X Daß die LED im Sekundentakt blinkt, bedeutet nicht, daß das Programm korrekt ist! Du weisst nur, daß das Programm nicht korrekt ist, wenn die LED nicht blinkt wie sie soll...

    In deinem Prog tauchen Interrupts nicht allzu oft auf. Timer0 muss überlaufen (90 Takte) und hat einen Prescaler von 1024.
    Nen Timer0 IRQ gibt's also nur alle 92160 Takte. Und falls er nicht nach dem cpi ausgelöst wird, stört er auch nicht.

    Das fiese an Fehlern in der Interrupt-Programmierung ist, daß diese Fehler oft nur sporadisch zuschlagen.
    Es ist auch denkbar, daß die Ausführungszeit deines Hauptprogramms eine gerade Anzahl von Takten braucht und dadurch nie ein IRQ direkt nach dem cpi entsteht.
    Wenn du aber irgendwo in deinem Prog eine Kleinigkeit änderst, geht es womöglich nicht mehr, weil sich dadurch die Laufzeit minimal verschiebt und dann die IRQ eben doch nach dem cpi ausgelöst wird.

    Dann wirst du dir nen Wolf suchen, weil dein Programm vorher ja "korrekt" war und du denkst, der Fehler liegt an deiner kleinen Änderung.
    Disclaimer: none. Sue me.

Seite 11 von 53 ErsteErste ... 91011121321 ... LetzteLetzte

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Solar Speicher und Akkus Tests