Forum: Mikrocontroller und Digitale Elektronik Rotary Encoder


von Max B. (maxberg)


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

von Jan (Gast)


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?

von Gast (Gast)


Lesenswert?

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

von Max B. (maxberg)


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...

von Max B. (maxberg)


Lesenswert?

@Gast

Nein die Pullups sind nicht aktiv und ich habe:

clrf TRISB
clrf TRISE

also beide output...

von Max B. (maxberg)


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 =)

von Max B. (maxberg)


Lesenswert?

Jap mit ANSELH gehts =) hab ich vergessen zusetzten!

Aber danke an alles Antworter =)

Schönen Abend noch...

von norticum (Gast)


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

von Peter D. (peda)


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

von norticum (Gast)


Lesenswert?

Ich freu mich immer wieder über solche antworten!

von Peter D. (peda)


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.

von norticum (Gast)


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

von Peter D. (peda)


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

von norticum (Gast)


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

von Peter D. (peda)


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

von norticum (Gast)


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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.