- Akku Tests und Balkonkraftwerk Speicher         
Seite 48 von 53 ErsteErste ... 384647484950 ... LetzteLetzte
Ergebnis 471 bis 480 von 524

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

  1. #471
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    29.07.2005
    Ort
    Berlin
    Alter
    40
    Beiträge
    289
    Anzeige

    LiFePo4 Akku selber bauen - Video
    Ich schäme mich diese Frage zu stellen, aber wie bekomme ich ein 16 Bit Register definiert? Hier erstmal der Code, vlt. verstehst du es dann besser:
    Code:
    ;Dieses Programm produziert ein Lauflicht. Jede halbe Sekunde geht die
    ;nächste LED an.
    ;Das Programm läuft in einer Endlosschleife durch.
    .include "m8def.inc"
    
    .equ time1 = 65536-1			;Damit wird der Timer1 vorgeladen, für die halbe Sekunde
    
    .def tmp = r16					;Mein Universallregister
    .def statusAmpel = r17			;Hier wird gespeichert, welche Lampen grad leuchten
    .def zeitwert = r18				;Hier wird der Wert gespeichert, mit dem der Timer1 vorgeladen wird
    .def lpm_reg = r0				;Mein lpm-Register
    
    .org 0x000
    	rjmp reset					;Interruptvektor "reset:"
    
    .org OVF0addr
    	rjmp zeitum					;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
    
    	ldi tmp, 0b11111111
    	out DDRB, tmp					;PortB als Ausgang
    	ldi statusAmpel, 0b00000010
    	out PORTB, statusAmpel			;Am Anfang LEDrot an
    
    	;Timer Register für halbe Sekunde werden belegt, hier Timer1
    	ldi tmp, (1<<CS12) | (1<<CS10)	;Prescaler ist 1024
    	out TCCR1B, tmp
    	ldi tmp, HIGH(time1)			;Für den Timer1 (16Bit) benötigen
    	out	TCNT1H, tmp					;wir 2 Register, in denen wir den Wert
    	ldi tmp, LOW(time1)				;für die 1/2 speichern ->
    	out TCNT1L, tmp					;"TCNT1H" und TCNT2L"
    	ldi tmp, (1<<TOIE1)				;Hier werden Interrupts nach Timer1 Überlauf eingeschaltet
    	out TIMSK, tmp					;Register TIMSK ist dafür zuständig
    
    	;Z-Register mit DB "timerwerte" füllen
       	ldi ZH, HIGH(timerwerte * 2)
       	ldi ZL, LOW(timerwerte * 2)
    
    	sei								;Interrupts zulassen
    
    main:
    
    	rjmp main						;Immer wieder die main durchlaufen
    
    zeitum:
    	push tmp						;tmp auf Stack sichern
    	in tmp, SREG
    	push tmp						;SREG auf Stack sichern
    		cpi statusAmpel, 0b00000010	;Ist rot an?
    		breq rotgelban				;JA -> gelb dazuschalten
    		cpi statusAmpel, 0b00000110	;Ist rot UND gelb an?
    		breq gruenan				;JA -> grün anmachen
    		cpi statusAmpel, 0b00001000	;Ist grün an?
    		breq gelban					;JA -> gelb anmachen
    
    ;Wenn alle drei Rechnungen != 0 ergeben, dann ist gelb an
    rotan:
    	sbiw ZL, 1						;nimm den vorherigen Wert aus der db (lange Zeit)
    	ldi statusAmpel, 0b00000010		;rot an
    	rjmp ende
    
    rotgelban:
    	adiw ZL, 1						;nimm den nächsten Wert aus der db (kurze Zeit)
    	ldi statusAmpel, 0b00000110		;rot und gelb an
    	rjmp ende
    
    gruenan:
    	sbiw ZL, 1						;nimm den vorherigen Wert aus der db (lange Zeit)
    	ldi statusAmpel, 0b00001000		;grün an
    	rjmp ende
    
    gelban:
    	adiw ZL, 1						;nimm den nächsten Wert aus der db (kurze Zeit)
    	ldi statusAmpel, 0b00000100		;gelb an
    		
    ende:
    	lpm								;Wert aus der db in r0 schreiben
    	mov zeitwert, lpm_reg			;den aktuellen Zeitwert aus r0 lesen
    	;TIMER1 wird neu geladen
    	ldi tmp, HIGH(time1)			;Für den Timer1 (16Bit) benötigen
    	out	TCNT1H, tmp					;wir 2 Register, in denen wir den Wert
    	ldi tmp, LOW(time1)				;für die 1 Sekunde speichern ->
    	out TCNT1L, tmp					;"TCNT1H" und TCNT2L"
    
    	out PORTB, statusAmpel			;Ampel richtig umschalten
    	pop tmp							;SREG vom Stack holen
    	out SREG, tmp
    	pop tmp							;tmp vom Stack holen
    	reti							;spring dahin zurück, wo du hergekommen bist
    
    timerwerte:
    	.db 65536-7200, 65536-1800
    Diese beide Zeilen:
    ldi tmp, HIGH(time1)
    ldi tmp, LOW(time1)
    muss ich noch ändern. Anstelle von time1 muss zeitwert rein, aber da zeitwert kein 16Bit Register ist, gibts Probleme.

    Bitte nicht hauen *gg*
    Ich weiß ja, dass ich für ein 16 Bit Register 2 8 Bit Register brauche, weiß aber leider nicht, wie ich die miteinander verbinde und vor allem, wie ich dann dort eine 16 Bit Zahl einlese. Geht sicher nicht so einfach wie mit dem Timer1, oder?

    Gruß
    Thomas

  2. #472
    Erfahrener Benutzer Roboter Experte
    Registriert seit
    30.09.2004
    Ort
    In der Nähe von Esslingen am Neckar
    Beiträge
    706
    Hi Leute,
    bin bald auf dem aktuellen Stand *freu* wisst ihr dass dieser Thread bei der Statistik auf Platz 1 ist!!
    [schild=11 fontcolor=000000 shadowcolor=C0C0C0 shieldshadow=1]Glückwunsch[/schild]
    bis jetzt hab ich alles verstanden!! *freu*
    Gruß Michi

  3. #473
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    53
    Beiträge
    2.236
    Hallo Thomas,
    ich weiß daß es schwer ist Tutorials zu lesen, aber Du hast Dir den Tutorial von
    www.avr-asm-tutorial.net nicht angetan!

    Lese Dir Aufmerksam Kapitel Register/Pointerregister durch.
    Und gib acht was dort zu .db und .dw steht.

    Gruß Sebastian

    Edit:
    @Michi, Ich freue mich, daß Du auch gut vorankommst!
    Wenn ich eben fragen darf, welches Board benutzt Du ?

  4. #474
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    29.07.2005
    Ort
    Berlin
    Alter
    40
    Beiträge
    289
    Ich krieg das nicht hin
    Ich muss doch die Register r24 und r25 benutzen, oder?
    Anwendbar sind die beiden Befehle auf die Registerpaare X, Y und Z sowie auf das Doppelregister R24/R25, das keinen eigenen Namen hat und auch keinen Zugriff auf RAM- oder sonstige Speicher ermöglicht. Es kann als 16-Bit-Wert optimal verwendet werden.
    Aber ich weiß nicht, wie ich das verwenden soll.
    Code:
    .def zeitwertL = r24
    .def zeitwertH = r25
    [....]
    lpm								;Wert aus der db in r0 schreiben
    	mov zeitwertL, lpm_reg			;den aktuellen Zeitwert aus r0 lesen
    	mov zeitwertH, lpm_reg
    	;TIMER1 wird neu geladen
    	ldi tmp, HIGH(zeitwertH)			;Für den Timer1 (16Bit) benötigen
    	out	TCNT1H, tmp					;wir 2 Register, in denen wir den Wert
    	ldi tmp, LOW(zeitwertL)				;für die 1 Sekunde speichern ->
    	out TCNT1L, tmp
    Das funktioniert ja nicht.

    Es ist doch richtig, dass lpm_reg, also r0, ein 16 Bit Register ist, oder? Also das in r0 eine 16 Bit-Zahl gespeichert ist. Mit meinen zwei "mov"-Befehlen bewirke ich da relativ wenig befürchte ich. Das kann doch nicht so schwer sein

  5. #475
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    53
    Beiträge
    2.236
    Thomas

    Ich muss doch die Register r24 und r25 benutzen, oder?
    Doppelregister R24/R25, das keinen eigenen Namen hat und auch keinen Zugriff auf RAM- oder sonstige Speicher ermöglicht.
    Muß ich noch was dazusagen ?

    Es ist doch richtig, dass lpm_reg, also r0, ein 16 Bit Register ist, oder


    Lese Tutorial Register/was?

    Also das in r0 eine 16 Bit-Zahl gespeichert ist


    Wer hat Dir das gesagt ?

    Das kann doch nicht so schwer sein
    ich habe es gehofft, aber scheinbar ist es so.

  6. #476
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    29.07.2005
    Ort
    Berlin
    Alter
    40
    Beiträge
    289
    Also das in r0 eine 16 Bit-Zahl gespeichert ist

    Wer hat Dir das gesagt ?
    Ich dachte, weil in r0 immer der aktuelle Wert aus der db steht, und da stehen ja nun 16 Bit Werte drinne.

    Das heißt, ich brauche einen zweiten Pointer-Register? Aber denn kann ich ja dann auch nicht mit r0 füllen, wenn in r0 anscheinend schon das falsche steht

  7. #477
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    53
    Beiträge
    2.236
    und da stehen ja nun 16 Bit Werte drinne.
    Und wer hat Dir das gesagt ?

    Das heißt, ich brauche einen zweiten Pointer-Register?
    Wozu einen Zweiten Pointerregister ?

    zu Deinem Vorhaben, ich habe Dir schon gesagt, Schaue im tutorial nach .db und .dw
    vergess den Quatsch mit R24 u. R25 und zweitem Pointerregister,
    Ich helfe Dir diesmal nicht, da kommst Du selber drauf, sonst lernst Du das nie...

    Das Tutorial beinhaltet Antworten auf alle Deine Fragen.

    Gruß Sebastian

  8. #478
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    29.07.2005
    Ort
    Berlin
    Alter
    40
    Beiträge
    289
    Ich schaffs leider wirklich nicht.
    Nehmen wir mal das hier:
    Code:
    lpm						
    mov zeitwert, lpm_reg
    In zeitwert steht dann 227, obwohl da eigentlich 61936 (65536-3600) stehen müsste.
    Code:
    timerwerte:
    	.dw 65536-7200, 65536-3600
    Hab jetzt rausgefunden, dass ich anstelle von db dw nehmen muss. Denn nur mit dw kann man Werte über 8Bit speichern (stimmt das denn wenigstens?)
    Aber wie ich diese eben auslesen kann, wird aus dem Tutorial nicht wirklich klar.
    Ich kann anstelle von dem hier:
    Code:
    ldi tmp, HIGH(HIGH (timerwerte * 2))
    	out	TCNT1H, tmp
    	ldi tmp, LOW(LOW (timerwerte * 2))
    	out TCNT1L, tmp
    hinschreiben, was ich will, nichts geht.
    Ich weiß, dass ich "HIGH(timerwerte * 2))" in beiden Zeilen durch etwas ersetzen muss. Eigentlich durch einen 16 Bit Register, oder? Aber ich hab ja keinen außer dem Z-Register.
    Und das hier geht ja nicht:
    Code:
    ldi tmp, HIGH(ZH)
    Mir wäre es doch auch lieber, wenn du mir dabei nicht hilfst, aber ich weiß nimmer, was ich da noch ändern soll.

    Gruß
    Thomas

  9. #479
    Erfahrener Benutzer Robotik Einstein
    Registriert seit
    08.05.2005
    Ort
    Issum
    Alter
    53
    Beiträge
    2.236
    Thomas, Du tust mir wirlich leid, ich weiß nicht, wie ich dir das sonst erklären kann

    Schade, daß Du soweit wohnst sonst würde ich Dich einladen und wir könnten das in ruhe durchgehen

    Schau mal hier
    In zeitwert steht dann 227, obwohl da eigentlich 61936 (65536-3600) stehen müsste.
    Es kann in einem Register nicht 61936 stehen!, das habe ich Dir doch gestern gesagt, ALLE
    Register beinhalten 8 Bits

    16 Bit stehen ja in zwei Registern!

    wenn Du Deine 61936 auslesen willst mußt Du dein ZPointer auf die erste adresse einstellen also z.B.
    daten:
    .dw 61936

    ldi ZH,HIGH(daten *2)
    ldi ZL,LOW(daten *2)
    jetzt kommt ein lpm

    und was steht im Tutorial ?

    .DW 12345,6789 ; zwei Worte
    ......
    Beim Lesen per LPM erscheint übrigens das niedrigere Byte der 16-Bit-Zahl zuerst!
    und was steht im R0 ?
    das niedrigere Byte der 16-Bit-Zahl

    also das low Byte von daten (hier von 61936 weil der ZPointer auf sie zeigt)
    wenn Du sie jetzt verschiebst nach z.B. zahlLOW(von mir unbenanter Register)
    hast Du die hälfte schon drin.
    jetzt adiw ZL,1
    hiermit gehen wir im .dw ein Byte weiter... jetzt zeigt der Zpointer auf die andere hälfte der Zahl
    und was steht dann im R0 nach einem lpm ? das HighByte von daten also von 61936

    das kannst Du auch von mir aus nach zahlHIGH schieben und dann hast Du Deine 16Bit Zahl aus dem Speicher ausgelesen.... sollte im .dw noch ein Komma stehen und eine zweite Zahl wirst Du wohl nach einem erneutem adiw ZL,1 wohl bei dieser Zahl landen und der Vorgang widerholt sich , genau so bei einer dritten fünften... 1000 Zahl .

    Du mußt Dir in klarem sein, daß es keine 16 Bit Register gibt!! auch der ZPointer ist kein 16 Bit Register, es ist ein Registergespann ZL und ZH also 2 Register.

    Edit:
    WICHTIG !

    Auszug aus dem Dattenblatt Seite 77:


    To do a 16-bit write, the High Byte must be written before the Low Byte.
    For a 16-bit read, the Low Byte must be read before the High Byte
    Muß man unbedingt beachten, sonst kommt dabei nur mißt raus!

    Ich hoffe, daß es jetzt verstanden wurde
    Spiel das im sim durch, gucke, wo der Zeiger hinzeigt, was er ausliest, und soweiter,
    es wird schwer sein die 16 Bits zu zerschlagen, mach das genauso wie ich dir das gestern gesagt habe, wandle eine 16Bit zahl (die Du im .dw stehen hast)in binär um mache schnitt damit Du 2x 8 Bit hast rechne aus was das für dezimale werte sind,
    und beobachte, was er Dir mit lpm in den R0 lädt, aber bedenke Low zuerst!

    Gute Nacht[/quote]

  10. #480
    Erfahrener Benutzer Roboter-Spezialist
    Registriert seit
    29.07.2005
    Ort
    Berlin
    Alter
    40
    Beiträge
    289
    Schade, daß Du soweit wohnst sonst würde ich Dich einladen und wir könnten das in ruhe durchgehen
    Das wär natürlich das Highlight
    Aber ich denk, nun hab ich das verstanden. Mit ein wenig Routine noch bekomm ich das schon auf die Reihe *zuversichtlich sei*
    Nun liest er die Werte wenigstens schonmal aus (glaub ich zumindest).
    Aber die Zeitabstände stimmen noch nicht so ganz, muss ich dann nochml am Tage schauen, ich werd nu auch erstmal ins Bett gehen.

    Danke schonmal
    Hätts sonst wirklich nicht hinbekommen

    Gruß und Gute Nacht
    Thomas

Seite 48 von 53 ErsteErste ... 384647484950 ... LetzteLetzte

Berechtigungen

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

Solar Speicher und Akkus Tests