Willkommen in unserer Community

Werde Teil unserer Community und registriere dich jetzt kostenlos ...

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies. Weitere Informationen

Decoderschaltung für Drehimpulsgeber

Dieses Thema im Forum "AVR-Projekte" wurde erstellt von Pirx, 15. August 2010.

  1. Pirx

    Pirx Mitglied

    Registriert seit:
    15. August 2009
    Beiträge:
    245
    Zustimmungen:
    3
    Ort:
    Möckern
    Sprachen:
    Assembler
    Map
    Das Folgende ist ein Nebenprodukt aus einem größeren Projekt. Die Abfrage des Drehimpulsgebers durch den "Hauptprozessor" (ATMega8) wollte allem sportlichen Ehrgeiz zum Trotz einfach nicht zuverlässig klappen und so habe ich das "Problem" irgendwann einfach ausgelagert.

    Heraus gekommen ist eine kleine Schaltung mit einem ATtiny13. Die kann man als eigenständiges Modul in beliebige Projekte einbinden und ich denke, dass das deshalb für den einen oder anderen interessant sein dürfte.


    Die Schaltung gibt pro vollständigem Drehschritt einen Impuls aus (unvollständige werden ignoriert). Über PB2/Pin7 kann man das Format der Ausgabe bestimmen :
    PB2 offen - Richtung / Clock
    PB2 auf Masse - Up / Down

    Ist PB2 offen, so kommt auf PB1 ein L-Impuls während zeitgleich der Pegel an PB0 die Drehrichtung angibt. Liegt PB2 an Masse, so kommt abhängig von der Dehrichtung ein Impuls an PB0 oder PB1 (Details siehe Tabelle in der Schaltung).

    Die Funktionsweise kann man optisch verfolgen, wenn man das Hex-File "mit Delay zum Test" programmiert. Bei diesem Hex-File ist die Dauer der Impulse soweit verlängert, dass man sie auf an PB0 und PB1 angeschlossenen LEDs sehen kann.


    Verwendet habe ich den Drehimpulsgeber C11B13 von ALPS. Andere Typen mit identischem Schaltschema sind ebenfalls verwendbar - ggf. muss man die RC-Kombinationen zur Entprellung anpassen.

    Der Aufbau ist unkritisch. Neben dem ATtiny13 und seinen obligatorischen Bauelementen braucht es nur noch zwei RC-Kombinationen zur Entprellung. Der Schalter S1 muss nicht sein, man kann den Pin7 natürlich auch hart verdrahten. Der ATtiny13 wird mit dem beiliegenden Hex-File programmiert und auf 9,6 MHz internen Takt eingestellt.


    Für die Assembler-Freaks :
    Die vielleicht etwas merkwürdig wirkenden Kürzel und Kommentare werden schnell klar, wenn man sich diese Quad-Decoder Schaltung ansieht :
    http://www.mikrocontroller.net/articles/Datei:Schaltplan_quad_decoder.png

    Das Programm simuliert einfach die Funktion dieser Logik-Schaltung. Ein- und Ausgänge des D-FlipFlop und der EOR-Gatter sind durch Register abgebildet und die elektrischen und logischen Verknüpfungen bewerkstelligt das Programm. Die Signalaufbereitung am Schluß reduziert auf einen Impuls pro Drehschritt (der Quad-Decoder würde vier herausgeben) und bewerkstelligt die Ausgabe im gewünschten Format.
     

    Anhänge:

  2. Cassio

    Cassio Moderator

    Registriert seit:
    29. Oktober 2008
    Beiträge:
    4.023
    Zustimmungen:
    15
    Ort:
    Region Hannover
    Sprachen:
    BascomAVR
    Map
    Hallo Pirx !

    Ich bin ja nun bekannterweise kein ASM-Freak.... ;)

    Das ist wohl auch der Grund, warum ich das nun nicht ganz verstehe? :hmmmm:

    Warum nimmst du einen separaten Tiny13 um einen Drehencoder auszuwerten? :hmmmm:
    Ich kann mir gar nicht vorstellen, dass dies in ASM nicht nebenbei erledigt werden kann?
    Das geht ja sogar in BASCOM und der AVR hat später damit keine "Probleme" oder "Aussetzer". ;)


    Erkläre doch daher einen Hochsprachenprogrammierer vom Lande bitte mal, was nun das Besondere an deiner Weise ist. :eek:

    Ich blick das einfach nicht.... :confused:

    Danke und Gruß,
    Cassio
     
  3. Pirx

    Pirx Mitglied

    Registriert seit:
    15. August 2009
    Beiträge:
    245
    Zustimmungen:
    3
    Ort:
    Möckern
    Sprachen:
    Assembler
    Map
    Hi Cassio,

    in meinem Fall war der Hauptprozessor ein ATMega8. Der war allerdings schon mit anderen Aufgaben gut beschäftigt und auch etliche Prozessorbaugruppen waren schon anderweitig in Benutzung. Den Drehencoder wirklich zuverlässig zu decodieren habe ich nicht mehr hinbekommen.

    Letztlich wollte ich auch nicht noch ewig weiter dran rumdoktern und habe deshalb die Flucht nach vorn angetreten. Der kleine Baustein löst über Clock einen Interrupt aus und die Interruptroutine speichert erstmal nur den Zustand der Richtungs-Leitung ab. Alles weitere passiert später, wenn der Hauptprozessor Zeit dafür hat.

    Mit dem Drehencoder direkt hätte ich vier Impulse pro Drehschritt und müßte noch die Richtung auswerten. So habe ich nur einen Impuls und brauche keine Zeit zur Auswertung. Und den Impuls gibt es auch nur, wenn es wirklich einen kompletten Drehschritt gab. Und falls der Drehencoder mal Zicken macht, wird der Hauptprozessor nicht sinnlos mit Impulsen beschäftigt.

    Die Schaltung läßt sich natürlich auch im Zusammenhang mit beliebiger Hardware verwenden, um z.B. an einem Gerät die Up/Down-Tasten durch einen Drehencoder zu ersetzen.

    Gruß
    Pirx
     
  4. Cassio

    Cassio Moderator

    Registriert seit:
    29. Oktober 2008
    Beiträge:
    4.023
    Zustimmungen:
    15
    Ort:
    Region Hannover
    Sprachen:
    BascomAVR
    Map
    Hallo Pirx!

    Danke schön, für die ausführlichere Erklärung und dass du dir die Zeit genommen hast, einem Hochsprachen-Flachlandprogrammierer zu beschreiben! :adore: ;)

    Ist ja vielleicht mal eine gute Alternative, wenn im "Haupt-µC" mal kein Platz mehr ist, oder......
    Möglichkeiten gibt es da wohl mehrere.

    Gruß,
    Cassio
     
  5. umsteiger

    umsteiger Neues Mitglied

    Registriert seit:
    25. Januar 2010
    Beiträge:
    90
    Zustimmungen:
    0
    Ort:
    Haiterbach
    -- Nur ein Grundsatz --

    Wenn ein Drehimpulsgeber zusammen mit einem Mikrocontroller -sicher- funktionieren soll, muss der Hard und Softwareentwickler die Interruptprogrammierung des entsprechenden Prozessors perfect beherschen...

    Wofgang
     
  6. Dirk

    Dirk Administrator Mitarbeiter

    Registriert seit:
    28. Januar 2007
    Beiträge:
    4.070
    Zustimmungen:
    100
    Ort:
    Mittelhessen, Giessen
    Sprachen:
    C, Assembler, Pascal, C++, PHP, Java
    Map
    Hallo Wolfgang,

    hierfür benötigt man eigentlich nur zwei IO-Pins als INPUT konfiguriert, und einen externen Interrupt (flankengetriggert mit fallender oder steigender Flanke). Wenn man via Software nicht entprellen muss, wird die Interruptserviceroutine sehr einfach. Bei mechanischen Encodern prellt es eher als bei optischen Encodern, dann benötigt man noch ein Zeitsignal, also einen Timer. Mit dem Zeitsignal läßt sich dann zum Beispiel eine Deadtime (Zeitpause) erzeugen, zum Entprellen gibts es unterschiedliche Vorgehensweisen.

    Grüße,
    Dirk
     
  7. Pirx

    Pirx Mitglied

    Registriert seit:
    15. August 2009
    Beiträge:
    245
    Zustimmungen:
    3
    Ort:
    Möckern
    Sprachen:
    Assembler
    Map
    @Wolfgang
    Encoder rein über Interrupte abzufragen, kann dazu führen, dass der Prozessor sehr stark mit Interrupten belastet wird. Prellen ist da nur ein Problem. Wenn du mehr wissen möchtest, hier ist es ausführlich beschrieben :
    http://www.mikrocontroller.net/articles/Drehgeber

    Die Nutzung eines Timers vermeidet diese Probleme. Die Timer waren nur in meinem Fall alle schon in Gebrauch und so brauchte ich halt eine andere Lösung ...

    Gruß
    Pirx
     
  8. july69

    july69 Neues Mitglied

    Registriert seit:
    24. Mai 2016
    Beiträge:
    7
    Zustimmungen:
    0
    Hallo lieber Pirx,
    deine "Schaltung" und dein Programm sind genau das was ich gesucht habe.
    Habe es auch erfolgreich aufgebaut und "programmiert".
    Jedoch sind die Ausgangsimpulse viel zu kurz für meine nachfolgende Schaltung (Optokoppler).
    Und die Delayversion viel zu lang.
    Ich hab gerade erst mit Bascom angefangen, so dass ich mit deinem asm programm nicht soooo gut klarkomme.
    Was muss ich denn dort ändern damit die Ausgangsimpulse länger werden (vlt. so 20-50 ms)
    Achja, und wenn da aus dem Attiny Positive Impulse rauskommen sollen, was muss denn dann noch geändert werden ?
    Die Ports mit cbi an Stelle von sbi setzen und bei der Ausgabe dann die Ports auf sbi setzen und mit cbi wieder zurücksetzen?
     
    #8 july69, 19. September 2016
    Zuletzt bearbeitet: 19. September 2016
  9. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.698
    Zustimmungen:
    38
    Ort:
    Hennigsdorf
    Sprachen:
    BascomAVR, Assembler
    Map
    Richtig.
    CBI setzt das Bit auf 0, und somit das Bein auf Und.
    SBI setzt das Bit auf 1, und somit das Bein auf Vcc.
    Zwischendurch läßt Pirx den Controller drei Takte aussetzen (NOP = No Operation), der Pegel liegt also vier Takte an.
    Der Controller rennt mit 9M6Hz, ein Takt dauert also ca 104ns.
    Vier zusammen ca 420ns.
    Du(!) kannst jetzt einfach mehr NOPs nehmen - effizienter wäre natürlich 'ne Schleife.
    (P.S.: jedes Nop kostet Dich 2Byte ProgramFlash)
     
  10. july69

    july69 Neues Mitglied

    Registriert seit:
    24. Mai 2016
    Beiträge:
    7
    Zustimmungen:
    0
    Naja mit NOPs auf 20 bis 50 millisekunden zu kommen wird wohl bischen unschön.
    Wie gehts denn Elegant ?

    Übrigens, danke für die Antwort, das hilft doch schonmal beim Ausgangssignal Invertieren.
    Jetzt nur noch die Zeit......
     
    #10 july69, 19. September 2016
    Zuletzt bearbeitet: 19. September 2016
  11. dino03

    dino03 Moderator

    Registriert seit:
    27. Oktober 2008
    Beiträge:
    6.663
    Zustimmungen:
    11
    Sprachen:
    BascomAVR, Assembler
    Map
  12. july69

    july69 Neues Mitglied

    Registriert seit:
    24. Mai 2016
    Beiträge:
    7
    Zustimmungen:
    0
    Lieber Dino,
    danke für deine Antwort.
    Leider bin ich in deinem verlinkten Projekt nicht wirklich fündig geworden.
    Warhscheinlich auch deshalb weil ich mich mit Assembler gar nicht auskenne.
    Ich habe da nix gefunden das mir weiter hilft.
    Pirx hat ja ein hex File mit einem Delay, nur ist das Delay zu lang und ich würde das gerne verkürzen. Aber aus einem Hex File einen Assemblercode zurückzuinterpretieren geht ja iwie auch nicht wirklich.
    Hab mir auch schon Assembler Grundlagen angeschaut, bezüglich loop, delay usw. aber ich komm da nicht weiter....

    :help:
     
  13. dino03

    dino03 Moderator

    Registriert seit:
    27. Oktober 2008
    Beiträge:
    6.663
    Zustimmungen:
    11
    Sprachen:
    BascomAVR, Assembler
    Map
    Hi,

    im Beitrag Nr.4 ist eine Zip mit allen möglichen Dingen (hier klicken).

    Die Warteroutinen draus (alle auf 16MHz berechnet) ...



    CodeBox Assembler
    ; ##################################################################
    ; ##################################################################
    ; #### Warte-Subroutinen ###########################################
    ; ##################################################################
    ; ##################################################################
    ; 62,5ns Zykluszeit bei 16MHz
    ;
    ; ==================================================================
    ; ===== 580ns warten ===============================================
    ; ==================================================================
    ;       rcall wait580n  ; (3)     Warteschleife aufrufen
    wait580n:               ; 9 Cyclen (incl Call+Ret) => ~580ns@16MHz
            nop             ; (1)
            nop             ; (1)
            ret             ; (4)     Schleifenende, Rueckkehr
    
    
    ; ==================================================================
    ; ===== 750ns warten ===============================================
    ; ==================================================================
    ;       rcall wait750n  ; (3)     Warteschleife aufrufen
    wait750n:               ; 12 Cyclen (incl Call+Ret) => ~750ns@16MHz
            nop             ; (1)
            nop             ; (1)
            nop             ; (1)
            nop             ; (1)
            nop             ; (1)
            ret             ; (4)     Schleifenende, Rueckkehr
    
    
    ; ==================================================================
    ; ===== 10us warten ================================================
    ; ==================================================================
    ;       rcall wait10u   ; (3)     Warteschleife aufrufen
    ; ================>     ; 525 Cyclen (incl Call+Ret) => ~10us@16MHz
    wait10u: push r20       ; (2)     r20 auf Stack retten
            ldi     r20,75  ; (1)     Zaehler initialisieren 105 (14us) , 75 (10us)
                            ;                                                                                                                 
                            ;                    1__223__                                                                                     
                            ;                    |       |                                                                                     
                            ;         1 Cycle = 105*2+1+12                                                                                     
    loop10u: dec r20        ; (1)     | niedrigstes Byte -1                                                                                   
            brne loop10u    ; (1f,2t)_/ 0 erreicht? nein -> Schleife                                                                           
                                                                                                                                               
            pop r20         ; (2)     r20 zurueckholen
            ret             ; (4)     Schleifenende, Rueckkehr
    
    
    ; ==================================================================
    ; ===== 33us warten ================================================
    ; ==================================================================
    ;       rcall wait33u   ; (3)     Warteschleife aufrufen
    ; ================>     ; 525 Cyclen (incl Call+Ret) => ~33us@16MHz
    wait33u: push r20       ; (2)     r20 auf Stack retten
            clr     r20     ; (1)     Zaehler initialisieren
                            ;
                            ;                    1__513__
                            ;                    |       |
                            ;         1 Cycle = 256*2+1+12
    loop33u: dec r20        ; (1)     | niedrigstes Byte -1
            brne loop33u    ; (1f,2t)_/ 0 erreicht? nein -> Schleife
    
            pop r20         ; (2)     r20 zurueckholen
            ret             ; (4)     Schleifenende, Rueckkehr
    
    
    ; ==================================================================
    ; ===== 516us warten ===============================================
    ; ==================================================================
    ;       rcall wait516u  ; (3)     Warteschleife aufrufen
    ; ================>     ; 8241 Cyclen (incl Call+Ret) => ~516us@16MHz
    wait516u: push r20      ; (2)     r20 auf Stack retten (1tes)
            push r21        ; (2)     r21 auf Stack retten (2tes)
            clr r20         ; (1)     r20+r21 ergeben zusammen
            ldi r21,16      ; (1)     einen 2-Byte-Zaehler (8241Cycl)
                            ;
                            ;                    2_________8241___
                            ;                    |   1__513__     |
                            ;                    |   |       |    |
                            ;         12 Cycle = 16*((256*2+1)+2)+1+17
    loop516u: dec r20       ; (1)     || niedrigstes Byte -1
            brne loop516u   ; (1f,2t)_/| 0 erreicht? nein -> Schleife
            dec r21         ; (1)      | mittleres Byte -1
            brne loop516u   ; (1f,2t)__/ 0 erreicht? nein -> Schleife
    
            pop r21         ; (2)     r21 zurueckholen (2tes)
            pop r20         ; (2)     r20 zurueckholen (1tes)
            ret             ; (4)     Schleifenende, Rueckkehr
    
    
    ; ==================================================================
    ; ===== 3ms warten =================================================
    ; ==================================================================
    ;       rcall wait3m    ; (3)     Warteschleife aufrufen
    ; ================>     ; 47913 Cyclen (incl Call+Ret) => ~3ms@16MHz
    wait3m: push r20        ; (2)     r20 auf Stack retten (1tes)
            push r21        ; (2)     r21 auf Stack retten (2tes)
            clr r20         ; (1)     r20+r21 ergeben zusammen
            ldi r21,93      ; (1)     einen 2-Byte-Zaehler (47913Cycl)
                            ;
                            ;                    2_________47896__
                            ;                    |   1__513__     |
                            ;                    |   |       |    |
                            ;         12 Cycle = 93*((256*2+1)+2)+1+17
    loop3m: dec r20         ; (1)     || niedrigstes Byte -1
            brne loop3m     ; (1f,2t)_/| 0 erreicht? nein -> Schleife
            dec r21         ; (1)      | mittleres Byte -1
            brne loop3m     ; (1f,2t)__/ 0 erreicht? nein -> Schleife
    
            pop r21         ; (2)     r21 zurueckholen (2tes)
            pop r20         ; (2)     r20 zurueckholen (1tes)
            ret             ; (4)     Schleifenende, Rueckkehr
    
    
    ; ==================================================================
    ; ===== 8ms warten =================================================
    ; ==================================================================
    ;       rcall wait8m    ; (3)     Warteschleife aufrufen
    ; ================>     ; 131858 Cyclen (incl Call+Ret) => ~8,24ms@16MHz
    wait8m: push r20        ; (2)     r20 auf Stack retten (1tes)
            push r21        ; (2)     r21 auf Stack retten (2tes)
            clr r20         ; (1)     r20+r21 ergeben zusammen
            clr r21         ; (1)     einen 2-Byte-Zaehler
                            ;
                            ;                    2__________131841_
                            ;                    |    1__513__     |
                            ;                    |    |       |    |
                            ;         12 Cycle = 256*((256*2+1)+2)+1+17
    loop8m: dec r20         ; (1)     || niedrigstes Byte -1
            brne loop8m     ; (1f,2t)_/| 0 erreicht? nein -> Schleife
            dec r21         ; (1)      | mittleres Byte -1
            brne loop8m     ; (1f,2t)__/ 0 erreicht? nein -> Schleife
    
            pop r21         ; (2)     r21 zurueckholen (2tes)
            pop r20         ; (2)     r20 zurueckholen (1tes)
            ret             ; (4)     Schleifenende, Rueckkehr
    
    
    ; ==================================================================
    ; ===== r16 * 8ms warten ===========================================
    ; ==================================================================
    ;       rcall waitx8m   ; (3)     Warteschleife aufrufen - Zeit in r16
    ; ================>     ; 131843*x+18 Cyclen (incl Call+Ret) => ~x*8,24ms@16MHz
    waitx8m: push r20       ; (2)     r20 auf Stack retten (1tes)
            push r21        ; (2)     r21 auf Stack retten (2tes)
            clr r20         ; (1)     r16, r20 und r21 ergeben
            clr r21         ; (1)     zusammen einen 3-Byte-Zaehler
                            ;                     3_____________________________
                            ; r16=1 8,241ms min   |    2____________131841_     |
                            ; r16=0 2,109s  max   |    |     1__513__      |    |
                            ;                     |    |     |       |     |    |
                            ;         123 Cycle = r16*((256*((256*2+1)+2)+1)+2)+1+17
    loopx8m: dec r20        ; (1)     ||| niedrigstes Byte -1
            brne loopx8m    ; (1f,2t)_/|| 0 erreicht? nein -> Schleife
            dec r21         ; (1)      || mittleres Byte -1
            brne loopx8m    ; (1f,2t)__/| 0 erreicht? nein -> Schleife
            dec r16         ; (1)       | höchstes Byte -1
            brne loopx8m    ; (1f,2t)___/ 0 erreicht? nein -> Schleife
                            ;
            pop r21         ; (2)     r21 zurueckholen (2tes)
            pop r20         ; (2)     r20 zurueckholen (1tes)
            ret             ; (4)     Schleifenende, Rueckkehr
    
    


    die verwendeten Register werden vorher gesichert und danach wieder hergestellt (Push/Pop).
    Die Textformatierung sah etwas mistig aus. Darum habe ich alle TABs durch Leerzeichen ersetzt. Nun steht wenigstens alles soweit untereinander. Man erkennt nun etwas besser was in den Bemerkungen steht.

    Gruß
    Dino
     
    #13 dino03, 20. September 2016
    Zuletzt bearbeitet: 20. September 2016
    Janiiix3 gefällt das.
  14. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.698
    Zustimmungen:
    38
    Ort:
    Hennigsdorf
    Sprachen:
    BascomAVR, Assembler
    Map
    Wenn ich das jetzt al richtig überschlagen habe, sind 20ms 19200 Takte. Soviele NOPs würden also gar nicht in den Flash passen. Mit Schleifen geht das natürlich, aber 20ms sind 'ne ganze Menge Wartezeit.

    Wenn ich Pirx richtig verstanden habe, hatte er damals versucht das in den Hauptcontroller miteinzubauen, und es dort nicht hinbekommen, und das ganze deswegen ausgelagert.
    Im Hauptcontroller hatte er keine Hardwaremodule mehr dafür frei - deswegen alles zu Fuß in Software.

    Eigentlich hätte er den Neuansatz im seperaten Tiny auf die Hardware aufsetzen können. Der Tiny13 hat einen 8bit-Timer, einen echten externen Interruptpin, alle Beine sind PCINT-fähig.
    Man könnte also mit den externen IRQs gut den Drehgeber erfassen, und den Timer sowohl zum entprellen als auch für eine Zeitbasis für die Signalausgabe verwenden.

    Jetzt stellt sich natürlich erstmal die Frage, wo July überhaupt hinwill:
    • Bascom lernen, und das ganze selbst mit Bascom umsetzen
    • Assembler lernen, und das ganze selbst mit Assembler umsetzen/verbessern
    • Pirx's Programm durch irgendwen anpassen lassen und ohne zu lernen nutzen
    Bei den ersten beiden Varianten wirst Du hier sicher Hilfe finden, für Variante3 wäre Pirx die beste Hilfe.
    Klar kann man da einfach mehr NOPs hinknallen (bzw 'ne Schleife), aber während Du da ewig und drei Tage wartest um das Ausgangssignal zurückzusetzen, verpaßt Du womöglich Eingangsimpulse des Drehgebers...
     
  15. july69

    july69 Neues Mitglied

    Registriert seit:
    24. Mai 2016
    Beiträge:
    7
    Zustimmungen:
    0
    Hallo Leute,
    erstmal Danke für eure Bemühungen.
    Ich werde weiterhin Bascom lernen,( was für meine normalen Anwendungsfälle ausreicht)
    aber ich werde dieses Projekt hier nicht auf Bascom umsetzen wollen.
    Nein, ich will nicht Assembler lernen, das wäre mir jetzt doch too much.
    Natürlich wäre mir am liebsten ich hätte den asm Code von Pirx' Delayversion, dann könnt ich das bestimmt auf meine Delayzeit anpassen.
    Habe Pirx auch diesbezüglich angeschrieben, aber er scheint sehr beschäftigt.
    Ich warte geduldig.....

    Gruß
    July
     
  16. Dirk

    Dirk Administrator Mitarbeiter

    Registriert seit:
    28. Januar 2007
    Beiträge:
    4.070
    Zustimmungen:
    100
    Ort:
    Mittelhessen, Giessen
    Sprachen:
    C, Assembler, Pascal, C++, PHP, Java
    Map
    Hallo July,

    ich habe mal schnell in den Code geschaut. So wie ich dich verstanden habe, möchtest du die Impulslänge vergrößern.
    Ich hoffe, ich habe die richtige Stelle im Code gefunden. Du kannst es ja mal austesten.

    Ab "updown:" den Code ersetzen. Ich habe einen ATtiny13 mit 9,6MHz angenommen und eine 10ms Pause eingefügt (sollte für den Optokoppler reichen, wenn du andere Werte benötigst, kann man Werte ändern oder du rufst delay_10ms einfach mehrfach hintereinander auf).

    Wie schon mal erwähnt wurde, bei größeren Pausen kann es passieren, dass du Takte des Encoders "verlierst".

    Dirk :ciao:



    CodeBox Assembler
    updown:
           sbrs DffOut,4       ;Sprung, wenn Richtg = H (Up)
           rjmp down
    
           cbi PORTB,1           ;# Up
           nop                   ;# Impuls
           nop                   ;# senden
           nop                   ;#
           rcall delay_10ms
           sbi PORTB,1           ;#
           rjmp abfrage       ;nächster Zyklus
    
    down:
           cbi PORTB,0           ;# Down
           nop                   ;# Impuls
           nop                   ;# senden
           nop                   ;#
           rcall delay_10ms
           sbi PORTB,0           ;#
           rjmp abfrage       ;nächster Zyklus
    
    
    
    ; 9,6MHz
    ; 10ms = 9600MZ
    delay_10ms:
       push r30   ; 2MZ
       push r31   ; 2MZ
    
       ldi r30, low(2400)   ; 1MZ
       ldi r31, high(2400)   ; 1MZ
    delay_10ms_loop:   ; 9600 = 2400 x 4
       sbiw r30, 1       ; 2MZ
       brne delay_10ms_loop   ; 2MZ (1MZ)
    
       pop r31   ; 2MZ
       pop r30   ; 2MZ
    
    ret
    
     
  17. july69

    july69 Neues Mitglied

    Registriert seit:
    24. Mai 2016
    Beiträge:
    7
    Zustimmungen:
    0
    Hallo Dirk,
    danke für die konkrete Hilfe, jetzt hab ich es sogar verstanden.
    Musste aber die Zeit noch auf 20ms erhöhen, damit meine nachfolgende Schaltung gut funktioniert!
     
  18. LotadaC

    LotadaC Sehr aktives Mitglied

    Registriert seit:
    22. Januar 2009
    Beiträge:
    2.698
    Zustimmungen:
    38
    Ort:
    Hennigsdorf
    Sprachen:
    BascomAVR, Assembler
    Map
    Warum nicht?
    Beim Auswerten des Drehencoders hilft Bascom Dir weitgehend. (Encoder)
    Zum Setzen/Löschen von Bits benutzt Bascom Set/Reset
    Und für Zeitvernichtungsschleifen gibts wait/waitms/waitus
    ...
     
  19. Pirx

    Pirx Mitglied

    Registriert seit:
    15. August 2009
    Beiträge:
    245
    Zustimmungen:
    3
    Ort:
    Möckern
    Sprachen:
    Assembler
    Map
    Hallo July69,

    da hast du aber einen "alten Schinken" ausgegraben. Das Projekt war eins meiner ersten ... und beileibe nicht meiner besten.

    Inzwischen habe ich eine zuverlässigere, selbst entwickelte Routine, die das Entprellen mit erledigt und so die RC-Glieder in der Schaltung überflüssig macht.

    Da du mit ASM offenbar nicht fit bist, habe ich ein Hex_File für dich fertiggemacht. Wie gewünscht sind die Ausgabeimpulse H-aktiv und 20ms lang (@9,6 MHz).

    Achtung :
    In der Zeit der Ausgabe stattfindende Encoder-Drehschritte werden nicht registriert. Die lange Ausgabezeit begrenzt daher die mögliche Drehgeschwindigkeit auf max. 40 Schritte/s. Bei manuellem Drehen sollte das jedoch kein Problem sein.

    Im Anhang findest du die neue Schaltung (ist identisch mit der alten, nur ohne die RC-Glieder) mit dem veränderten Ausgabeschema sowie ein Hex-File mit 20ms Ausgabeimpulsen und eins mit 200ms Ausgabeimpulsen (mit dem du bei Bedarf die Funktion optisch prüfen kannst).

    Gruß
    Pirx
     

    Anhänge:

  20. july69

    july69 Neues Mitglied

    Registriert seit:
    24. Mai 2016
    Beiträge:
    7
    Zustimmungen:
    0
    Hallo Pirx,
    hab vielen Dank für deine neue Version, besser gehts nicht. Hab es zwar mit Hilfe der Forumskollegen auch so hinbekommen, aber wenn ich mir das RC Netzwerk noch sparen kann, ist das ja noch besser.
    Also nochmals vielen Dank an alle für die Hilfe.

    Gruß
    July
     

Diese Seite empfehlen

  • Über uns

    Unsere immer weiter wachsende Community beschäftigt sich mit Themenbereichen rund um Mikrocontroller- und Kleinstrechnersysteme. Neben den Themen Design von Schaltungen, Layout und Software, beschäftigen wir uns auch mit der herkömmlichen Elektrotechnik.

    Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  • Coffee Time

    Unser makerconnect-Team arbeitet hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und unser eigener makerconnekt-Server regelmäßig gewartet wird. Wir nehmen das Thema Datensicherung und Datenschutz sehr ernst und sind hier sehr aktiv, auch sorgen wir uns darum, dass alles Drumherum stimmt!

    Dir gefällt das Forum und die Arbeit unseres Teams und du möchtest es unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft, unser Team freut sich auch über eine Spende für die Kaffeekasse :-)
    Vielen Dank!
    Dein makerconnect-Team

    Spende uns! (Paypal)