mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Rotary Encoder


Autor: Max Berg (maxberg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich versuche gerade einen Drehgeber mit einem PIC16F887 auszuwerten...
Das Problem ist, wenn ich an PORTE hänge gehts.. an PORTB nicht...

Habe bei der initaliesierung keinen unterschied der beiden...
beide normal als output gesetzt...

Vorschläge?

Danke!!

Liebe Grüße Max

Autor: Jan (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wieso denn Ausgang?

Mit Pic kenne ich mich nicht aus, aber evtl. ist bei dem Port eine 
alternative Funktion aktiv, sodass du ihn nicht als General Purpose IO 
verwenden kannst?

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> beide normal als output gesetzt...
Vielleicht doch als Eingang und beim PortB sind die Pullups
aktiv? Der PortE hat keine Pullups.

Autor: Max Berg (maxberg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey danke!

Ja sowas hab ich mir auch schon gedacht... Nur weis ich eben nicht was 
genau =)
Laut Datenblatt kann man die Ports noch anderswertig verwenden aber dazu 
müsste man irgendwelche Bit setzen...
Das heißt Standartmäßig sollte es eigentlich richtig gesetzt sein...

An PORTE 0 und 1 gehts... an PORTB 0 und 1 nicht....
Habe bei beiden keine extra initialiesierungen vorgenommen...

Autor: Max Berg (maxberg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Gast

Nein die Pullups sind nicht aktiv und ich habe:

clrf TRISB
clrf TRISE

also beide output...

Autor: Max Berg (maxberg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ah...
Jetzt hab ich mal:

movlw b'00000000'
movwf ANSELH

jetzt gehts..

Nur springt mein Drehgeber immer hin und her..
mal schaun das wird noch =)

Autor: Max Berg (maxberg)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jap mit ANSELH gehts =) hab ich vergessen zusetzten!

Aber danke an alles Antworter =)

Schönen Abend noch...

Autor: norticum (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo!

Ich arbeite auch gerade an sowas. Prozessor ist Freescale HCS08. 14 Mhz 
Busclock. Ich versuche auf eine Led Bandanzeige auszugeben. Ich hänge 
aber irgendwie in der "rotstatushandler_sub" fest und weiß nicht genau 
wie weiter. Vielleicht hat jemand eine Idee?

_Startup:
            LDHX   #RAMEnd+1        ; initialize the stack pointer
            TXS
            CLI                     ; enable interrupts
            lda #%00000000
            sta SOPT
            mov #%11111000,ICGC1
            mov #%01110000,ICGC2     ;External 4Mhz Crystal 
source,~14Mhz internal Bus Clock
            ;mov #%11111111,ICGTRM    ;~8Mhz internal Bus Clock
            mov #$FF,PTFDD           ;datadirection output
            lda #$FF
            sta PTAPE
            bclr 6,PTADD             ;datadirection input
            bclr 2,PTADD             ;datadirection input
            clr RAM1
            clr RAM2
            clr left
            clr right
            clr rotstatus

mainLoop:



            jsr rotencoder_sub

            BRA    mainLoop

rotencoder_sub:

            brclr 2,PTAD,rotleft_sub
            brclr 6,PTAD,rotright_sub
            bra rotencoder_sub

rotleft_sub:
            ;brset 2,PTAD,*
            brset 0,rotstatus,rotleft_sub1
            brset 1,rotstatus,rotleft_sub1
            brset 2,rotstatus,rotleft_sub1
            brset 3,rotstatus,rotleft_sub1
            brset 4,rotstatus,rotleft_sub1
            brset 5,rotstatus,rotleft_sub1
            brset 6,rotstatus,rotleft_sub1
            brset 7,rotstatus,rotleft_sub1
            lda #%10000000
            sta left
rotleft_sub1:
            brclr 2,PTAD,*
            jsr delay
            brset 6,PTAD,*
            jsr delay
            brclr 6,PTAD,*
            jsr rotstatushandler_sub
            lda rotstatus
            sta PTFD
            rts

rotright_sub:
            ;brset 6,PTAD,*
            brset 0,rotstatus,rotright_sub1
            brset 1,rotstatus,rotright_sub1
            brset 2,rotstatus,rotright_sub1
            brset 3,rotstatus,rotright_sub1
            brset 4,rotstatus,rotright_sub1
            brset 5,rotstatus,rotright_sub1
            brset 6,rotstatus,rotright_sub1
            brset 7,rotstatus,rotright_sub1
            lda #%00000001
            sta right

rotright_sub1:
            brclr 6,PTAD,*
            jsr delay
            brset 2,PTAD,*
            jsr delay
            brclr 2,PTAD,*
            lda right
            jsr rotstatushandler_sub
            lda rotstatus
            sta PTFD
            rts

rotstatushandler_sub:

            lda left
            cmp #%10000000
            bne shiftleft_sub
            lda right
            cmp #%00000000
            bhs shiftright_sub
            bra rotstatushandler_sub


shiftleft_sub:
            lda left
            rol left
            sta rotstatus
            rts

shiftright_sub:
            lda right
            ror right
            sta rotstatus
            rts


delay:
            mov #$10,RAM1
del3:
            mov #$10,RAM2
del4:
            dec RAM2
            bne del4
            dec RAM1
            bne del3
            rts
;**************************************************************
;* spurious - Spurious Interrupt Service Routine.             *
;*             (unwanted interrupt)                           *
;**************************************************************
spurious:                           ; placed here so that security value
            NOP                     ; does not change all the time.
            RTI
;**************************************************************
;*                 Interrupt Vectors                          *
;**************************************************************

            ORG   Vrti       ; Start of interrupt vectors for device

            DC.W  spurious   ; 25  RTI
            DC.W  spurious   ; 24  IIC1
            DC.W  spurious   ; 23  ADC1
            DC.W  spurious   ; 22  KEYBOARD1
            DC.W  spurious   ; 21  SCI2TX
            DC.W  spurious   ; 20  SCI2RX
            DC.W  spurious   ; 19  SCI2ERR
            DC.W  spurious   ; 18  SCI1TX
            DC.W  spurious   ; 17  SCI1RX
            DC.W  spurious   ; 16  SCI1ERR
            DC.W  spurious   ; 15  SPI1
            DC.W  spurious   ; 14  TPM2OVF
            DC.W  spurious   ; 13  TPM2CH1
            DC.W  spurious   ; 12  TPM2CH0
            DC.W  spurious   ; 11  TPM1OVF
            DC.W  spurious   ; 10  TPM1CH5
            DC.W  spurious   ; 9   TPM1CH4
            DC.W  spurious   ; 8   TPM1CH3
            DC.W  spurious   ; 7   TPM1CH2
            DC.W  spurious   ; 6   TPM1CH1
            DC.W  spurious   ; 5   TPM1CH0
            DC.W  spurious   ; 4   ICG
            DC.W  spurious   ; 3   LVD
            DC.W  spurious   ; 2   IRQ
            DC.W  spurious   ; 1   SWI
            DC.W  _Startup   ; 0   RESET


END

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@norticum (Gast)

wirklich sehr schön, wie ausführlich Du Deinen Code kommentiert hast.

Ich habe leider keine Lust, extra noch Freescale-Assembler zu lernen.
Eine CPU, die sich Spurious Interrupts leisten kann, sollte genug Power 
unter der Haube haben, um in C programmiert zu werden.
Kommentare sollten aber trotzdem nicht fehlen.


Peter

Autor: norticum (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich freu mich immer wieder über solche antworten!

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
norticum wrote:
> Ich freu mich immer wieder über solche antworten!

Aha, deshalb hast Du also so sparsam kommentiert, damit sie kommen 
mußte.
Dann freut es mich, daß ich Dir eine Freude bereiten konnte.


Der Begriff "Spurious Interrupt" ist bei Dir unglücklich vormuliert. Er 
ist nämlich schon mit einer anderen Bedeutung belegt:

Bei größeren CPUs (ARM) kann er auftreten, obwohl keine Programmfehler 
vorliegen. Die Ursache liegt in einem schlechten Design des 
Interruptkontrollers. Durch Laufzeiteffekte kann er vergessen, wer ihm 
den Interrupt gemeldet hat und schaut dann blöd aus der Wäsche.

Daher meine Annahme, es handelt sich beim Freescale um einen Boliden.


Beim AVR-GCC wird Deine Art "Spurious Interrupt" BADISR_vect genannt:
This is a vector which is aliased to __vector_default, the vector
executed when an ISR fires with no accompanying ISR handler.


Peter


P.S.:
Also wenn brclr ein Sprung ist, dann schaut die CPU beim rts ziemlich 
blöd aus der Wäsche.

Autor: norticum (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Peter!

spurious ist im Codewarrior eine Art Standart routine. Wenn ich ein 
neues Projekt in Codewarrior öffne sieht die Vectortabelle ziemlich 
mager aus. Spurious macht in Codewarrior rein gar nix. Das ist nur gegen 
nicht gewollte interrupts. Bsp.:

;**************************************************************
;* spurious - Spurious Interrupt Service Routine.             *
;*             (unwanted interrupt)                           *
;**************************************************************
spurious:                           ; placed here so that security value
            NOP                     ; does not change all the time.
            RTI

;**************************************************************
;*                 Interrupt Vectors                          *
;**************************************************************
            ORG   $FFFA

            DC.W  spurious          ;
            DC.W  spurious          ; SWI
            DC.W  _Startup          ; Reset


RTS ist Return from Subroutine
RTI ist Return from Interrupt
brclr ist ein Branchbefehl bedeutet "branch if clear" oder "branch if 
bit x in x clear" (Wenn Taste gedrückt springe nach Subroutine x)

Momentan hab ich es mit meinem Code das soweit hinbekommen, dass sich 
die Balkenanzeige in eine Richtung bewegt. Leider unabhängig von der 
drehrichtung meines encoders. Hast du vielleicht ein AVR Assembler 
Beispiel das ich mir ansehen kann? Sprut hat auch so etwas gemacht. Ich 
versteh jedoch die mnemonic von Microchip nicht.

norticum

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
norticum wrote:
> RTS ist Return from Subroutine
> brclr ist ein Branchbefehl ...

... und pusht keine Returnadresse.

Deshalb kannst Du nicht mit RTS zurück.
RTS geht nur nach einem Call.


Peter

Autor: norticum (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
vergiss den mainloop nicht.....

mit "jsr rotencoder_sub" springe ich nach "rotencoder_sub". Mit RTS 
gehts wieder raus in den mainloop. Das selbe gilt auch für die 
"rotright_sub" bzw. "rotleft_sub".

norticum

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
norticum wrote:
> mit "jsr rotencoder_sub" springe ich nach "rotencoder_sub".

Daß JSR Call heißen soll, habe ich nicht gewußt.
Ich werd wohl besser still sein, die Syntax ist doch zu sehr 
unterschiedlich zu 8051/AVR.

Dürfte trotzdem keine so blöde Idee sein, mal zu kommentieren, wie die 
Dekodierung gedacht ist und dann als Anhang senden für die 
Frescale-Kenner.


Wenn Du mal sehen willst, wie andere Encoder einlesen:

Beitrag "Drehgeber/Encoder 1-, 2- oder 4-schrittig"


Peter

Autor: norticum (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Peter!

Werd ich nachholen (kommentieren). Ich hab von C keine Ahnung. Hab aber 
viel Geld für zwei Kurse ausgegeben um C zu lernen. Die fangen ende März 
an. Vielleicht kann ich mir unter den routinen in dem Beitrag in den du 
verweist, mehr vorstellen. Ich hab mir vor zweieinhalb Jahren das mit 
den Mikrocontrollern angefangen. Zwischenzeitlich hab ich versucht mir 
auch über AVR´s und Pic´s etwas anzueignen. Irgendwie bin ich aber immer 
wieder auf Freescale hängen geblieben. Preis Leistung stimmt einfach. 
Man bekommt einfach "Viel controller für wenig Geld". Auch viele 
unterschiedliche Demoboards sind erhältlich für kleines Geld. Die HCS08 
Serie lässt sich wirklich sehr komfortabel bearbeiten und wär für den 
Anfang in der 8 bit Reihe wohl am besten geeignet. Der saure 
Beigeschmack besteht jedoch darin, dass fast niemand damit arbeitet. Das 
soll bedeuten, man findet im gegensatz zur AVR Fraktion wenige die einem 
weiterhelfen können. Je weiter man nach oben kommt um so dünner wird die 
Luft. Hat ein Freund mal zu mir gesagt.

norticum

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.