-         
Seite 1 von 2 12 LetzteLetzte
Ergebnis 1 bis 10 von 18

Thema: Kann das so funktionieren? ( Lauflicht )

  1. #1
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    06.10.2008
    Alter
    26
    Beiträge
    110

    Kann das so funktionieren? ( Lauflicht )

    Anzeige

    Hallo Leute


    Ich bin hier dabei ein Lauflicht gerade zu Programmieren und ich habe
    erstmal dazu diverse Fragen.

    1.Kann das vom Code so funktionieren?

    2.Wie realiesiert man Warteschleifen?
    Ich hab dazu gegoogelt bis zum geht nicht mehr
    und wenn ich mir die Codebeispiele durchlese
    scheine ich es zu verstehen aber irgendwie bin ich nicht
    fähig diese zu verändern bzw. habe ich den Eindruck das ich
    doch nicht alles verstanden habe.
    Zum Beispiel:
    Code:
        LDI ZH,HIGH(65535)
        LDI ZL,LOW(65535)
    Zaehl:
        SBIW ZL,1
        BRNE Zaehl
    ZH,ZHL sind 2 Register z.B. R18/R19 , welche die Zahl 65535 ( 256*256 )
    bilden.
    Die Erklärung zu SBIC
    "This instruction tests a single bit in an I/O register and skips the next instruction if the bit is cleared"
    Heißt doch so viel das wenn das Register 'leer' ist das der nächste Befehl übersprungen wird.

    BRNE versteh ich nicht ganz.
    Wenn ich das nun in meinen Programmablauf einbinden möchte muss
    ich das ganze nur noch Warten nennen und es noch mit ret erweitern?

    Wer wäre so nett und könnte mir den Rest erklären? ....

    Und alle guten Dinge sind ja Drei.
    3.Wie kann man einfach das Lauflicht erweitern?
    Zum Beispiel das es sich auf Tastendruck in die andere Richtung bewegt
    oder oder alles Inventiert ist?
    Wobei das mit den Inventieren ja noch geht da man ja ein
    neues Register brauch den Inhalt darein kopiert und den Inhalt
    inventiert.Aber wie sieht es mit den rest aus?


    Hier der Code:
    Das rcall Warten ist noch leer da ich noch nicht richtig verstanden
    habe wie Warteschleifen funktionieren.
    Ich wollte das aber schonmal stehen haben damit ich *wenn es richtig ist*
    auch das rcall an der richtigen Stelle sitzt.


    Liebe Grüße
    Namenlos

    Code:
    .include	"m8def.inc"
    
    .DEF	Lauf = r16
    
    ldi	Lauf,0b11111111
    out	DDRB,Lauf			
    ;Alle Pins am Port B durch Ausgabe 0b11111111 ins
    ;Richtungsregister DDRB als Ausgang konfigurieren
    
    
    Schleife:
    
    	ldi	Lauf,0b00000000		
    ;Alle Bits Low
    	out	PortB,Lauf			
    ;Ausgabe in PortB
    
    
    	rcall	Warten
    
    
    	ldi	Lauf,0b00000001		
    ;Erster Port High
    	out	PortB,Lauf			
    ;Ausgabe in PortB
    
    
    	rcall	Warten
    
    
    	ldi	Lauf,0b00000010		
    ;Zweiter Port High
    	out	PortB,Lauf			
    ;Ausgabe in PortB
    
    
    	rcall	Warten
    
    
    	ldi	Lauf,0b00000100		
    ;Dritter Port High
    	out	PortB,Lauf			
    ;Ausgabe in PortB
    
    
    	rcall	Warten
    
    
    	ldi	Lauf,0b00001000		
    ;Vierter Port High
    	out	PortB,Lauf			
    ;Ausgabe in PortB
    
    
    	rcall	Warten
    
    
    	ldi	Lauf,0b00010000		
    ;Fünfter Port High
    	out	PortB,Lauf			
    ;Ausgabe in PortB
    
    
    	rcall	Warten
    
    
    	ldi	Lauf,0b00100000		
    ;Sechster Port High
    	out	PortB,Lauf		
    ;Ausgabe in PortB
    
    
    	rjmp	Schleife
    
    
    Warten:
    Code-Tags eingefügt (PicNick)

  2. #2
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Erst mal zur Warteschleife:
    ZH/ZL sind die Register 30 und 31 (weiss grade nicht in welcher reihenfolge). Das ist aber wohl das kleinste Problem. Der Befehl SBIW ist nicht bei allen AVR Controllern implementiert. Das ist ein spezieller Befehl für eine 16 Bit subtraktion: von der 16 Bit Zahl in ZH/ZL wird das in dem Beispiel jeweils 1 abgezogen.
    Das BRNE ist ein normaler bedingter Sprung: Springe wenn Z-Flag nicht gesetz ist, also das Ergebnis der LEtzten Rechnung nicht 0 war.

    Der Code ist umständlich könnte aber sonst fast funktionieren. Es fehlt noch die Initialliserung des Stackpointers.

    Ein Erweitern des Probgramms ist sicher möglich. Man müßte da irgendwo die Tasten abfragen und dann ggf. in einen anderen Programmteil springen.

  3. #3
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    25.11.2003
    Beiträge
    1.111
    Ja, und:
    SBIW (nicht SBIC) setzt das Z-Flag, wenn das Ergebnis der Subtraktion 0 ist. Dann ist "Equal" erfüllt und der Sprung findet nicht mehr statt, dh das Programm läuft einfach weiter, nachdem 65534 Mal gebranched wurde.
    Wenn Du ein Unterprog aufrufen willst musst Du innerhalb dessen noch die verwendeten Register retten, sofern Du sie woanders verwenden willst. Dazu sollte man dann lieber ein Buch oä lesen, damit man weiß, was man tut.
    Tasten müssen entprellt werden.
    Besser wäre es natäurlich den Timer zu benutzen, aber dazu muss man IRQs auswerten.
    Anstatt jedes Bitmuster zu speichern, kannst Du auch einfach ein Bit durch den Port "schieben" -> logical ship left oder right (LSL...)bzw, rotate left/right (ror...).
    Gruß

  4. #4
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    06.10.2008
    Alter
    26
    Beiträge
    110
    Danke für eue Antworten!

    Ich persönlich stelle mir nun einige Fragen.
    1)Gibt es den Befehl SBIW auch bei einen Mega8 ?

    2)Was für ein Stackpointer?
    Bzw wie Initialiesiert man den?

    3)Das mit den 'Bit durch den Port schieben' muss ich mir mal
    genauer anschauen bis ich mal wieder richtig Zeit dafür finde.
    Sind ja zum Glück bald Ferien

    Ich hoffe die Fragen sind nicht zu blöd!

    Liebe Grüße
    Namenlos

  5. #5
    Erfahrener Benutzer Robotik Visionär Avatar von oberallgeier
    Registriert seit
    01.09.2007
    Ort
    Oberallgäu
    Beiträge
    7.675
    Zitat Zitat von Namenlos
    ... Gibt es den Befehl ... auch bei einen Mega8 ...
    Solche Fragen stellen sich Dir öfters, Anwort gibts dafür im Datenblatt:
    http://www.atmel.com/dyn/products/da...ily_id=607#760
    ... nimm Dir die Langfassung, die Summary nutzt nix. In der Langfassung stehen alle (Assembler-) Befehle für den entsprechenden Controller.

    Zitat Zitat von Namenlos
    ... 'Bit durch den Port schieben' ...
    Schau mal hier, da gibts etliche Tutorials; da stehen eigentlich immer die Bitoperationen beschrieben.

    Zum Stackpointer solltest Du aber selbst mal die Suchfunktion bemühen. Fast alle Fragen gabs ja schon mal - und dazu auch Antworten.
    Ciao sagt der JoeamBerg

  6. #6
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    06.10.2008
    Alter
    26
    Beiträge
    110
    Huhu

    Einmal nur ganz kurz.
    Habe leider gerade keine Zeit weil ich meiner Schwester beim Umzug
    helfe.
    Ich wollte aufjedenfall erstmal Danke für eure Beiträge sagen
    Oft reicht *hoffentlich * ein kleiner Gedankenanstoß um
    weiterzukommen.... *g* und wenn ich wieder auf Granistoße
    dann werd ich mich wieder melden

    Liebe Grüße
    Namenlos

  7. #7
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    06.10.2008
    Alter
    26
    Beiträge
    110
    /Doppelpost

    Danke für eure Beiträge ich hab mich mal jetzt wieder daran
    gesetzt und es funktioniert sogar
    Jetzt versuche ich das zu vereinfachen indem ich
    das Bit einfach durch den Port schiebe

    Und ich hab mit vorgenommen mit Displays und
    AD-Wandlern was zu machen.... das kann
    ja noch dauern

    Liebe Grüße
    Namenlos

  8. #8
    Erfahrener Benutzer Fleißiges Mitglied
    Registriert seit
    06.10.2008
    Alter
    26
    Beiträge
    110
    Tripplepost....

    Hallo Leute,

    mir ist nicht ganz klar ob es angebracht ist hier weiter zu schreiben
    aber vor kurzen habe ich wieder Zeit um mich mit µC zu beschäftigen und
    ich habe mein Lauflicht inzwischen so verkleinert das ich nun
    einen 16Bit Timer benutze und ich bei jeden Überlauf einen
    Interrupt auslöse indem ich dann an den Port das Bit einfach schiebe.

    Meine Frage ist nun:
    Wie könnte man das ganze nun erweitern damit es bei Tasterdruck 1 ( Beispiel) schneller wird und bei einen anderen Tasterdruck wieder
    Langsamer wird?

    Jetzt habe ich den Timer so gewählt das er etwa alle 2 Sekunden
    auslöst.

    Um das oben genannte zu realiesieren könnte müsste man
    den Timer verkleinern oder bei Tastendruck gewisse
    Startwerte vorladen.
    So das es bei einen 16 Bit Timer nicht 65536 Takte dauert bist
    dieser überläuft sondern nur zum Beispiel die hälfte dieser Takte.
    Und wie verknüfpt man dies noch mit Tastern damit
    diese Aktion bis zum nächsten Tastendruck erhalten bleibt?

    Könnte mir da jemand auf die Sprünge helfen bzw. diverse
    Gedankenstupser geben? = )

    Liebe Grüße
    Namenlos

    Der jetzige Code
    .include "m8def.inc"

    Code:
    .def	Arbeit = r16
    .def	Licht  = r17
    
    
    .org 0x0000					; Hauptprogramm
        rjmp    Hauptprogramm    
    .org OVF1addr               ;Timer 1 Interrupt Vector Addresse
    	rjmp Timer1
    
    Hauptprogramm:
    
    		 ldi Arbeit, LOW(RAMEND)             ; LOW-Byte der obersten RAM-Adresse
             out SPL, Arbeit
             ldi Arbeit, HIGH(RAMEND)            ; HIGH-Byte der obersten RAM-Adresse
             out SPH, Arbeit
     
    
    		ldi	Arbeit,0b11111111
    		out	DDRC, Arbeit		;Alle Pins am Port C durch Ausgabe 0b11111111 ins
    								;Richtungsregister DDRC als Ausgang konfigurieren
    
    		
    
    		ldi r16,0b000000100		;Vorteiler 256 an Timer 1
    		out TCCR1B,r16			;Setze Bit
    
    		ldi r16, 0b00000100		;Interrupt Overflow aktivieren
         	out TIMSK, r16			;Setze Bit
    			
    	
    		sei						;Interrupt Aktivieren
    
    		ldi Licht,0b00000001	; =1
    		out PortC, Licht		;Erste LED an PortC an
    	
    	
    Schleife:	
    		
    		rjmp Schleife
    
    
    Timer1:
    	
    	rol Licht					;Bits 'schieben'
    	out PortC, Licht			;Gebe 'Licht' an PortC aus
    
    	reti						;Springe zurück

  9. #9
    Erfahrener Benutzer Robotik Visionär
    Registriert seit
    26.11.2005
    Ort
    bei Uelzen (Niedersachsen)
    Beiträge
    7.942
    Für eine variable Frequenz haben die 16 Bit timer den CTC Mode. Da wirkt dann eines der output-compare Register-paare als obere Grenze für den Timer. Der kann dann z.B. nur bis 10000 Zählen.

    Bei der Tastenabfrage wird man eine entprellen nutzen müssen, sonst wird eine Taste leicht mehrmals gezählt.

  10. #10
    Erfahrener Benutzer Roboter Genie
    Registriert seit
    25.11.2003
    Beiträge
    1.111
    Genau.
    Die Entprellung kannst Du zB dadurch erreichen, dass Du die Taste alle zB 50ms abfragst. Auf diese Zeit stellst Du Deinen Timer ein. Als Blinkfrequenz kannst Du Vielfache davon wählen, wenn Du einen Zähler in die ISR einfügst, der das Bit zB nur jedes 40ste Mal auslöst (40*50ms=2s).
    Gruß

Seite 1 von 2 12 LetzteLetzte

Berechtigungen

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