Rotery Encoder
Beispiele für Software-Entprellen
Mechanische Rotery-Encoder sind zwar billig, haben aber ein grundsätzliches Problem: Die Kontakte prellen. Um dies zu verhindern gibt es spezielle Entrell-Schaltungen, kostengünstiger und platzsparender ist jedoch eine "Software"-Entprellung.

Das ganze funktioniert so:
Die Funktion read_encoder wertet den Encoder in einer Schleife solange aus (aber maximal 256 mal, Variable warte), bis hintereinander 8 gleiche Werte gelesen wurden. Sind 8 gleiche Werte gelesen wurden, wird das Ergebnis in PrlfrLi bzw. PrlfrRe abgelegt.
list p=16f84
errorlevel 0,-302,-305 INCLUDE "c:\progra~1\mplab\projekte\drehimpu\p16f84.inc" ;********************************************************** ;* Pinbelegung ;* ---------------------------------- ;* PORTA: 0 LED ;* 1 LED ;* 2 LED ;* 3 LED ;* 4 LED ;* PORTB: 0 ;* 1 > rotary encoder ;* 2 ;* 3 ;* 4 ;* 5 ;* 6 < rotary encoder - B Pin4 ;* 7 < rotary encoder - A Pin5 ;* ;********************************************************** ; ; (c) Michael Kellner 01/2007 ; ; Rotary-Encoder mit LED Zeile ; Prozessor 16C/F84 @ 4 MHz ; ;********************************************************** __CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC ; '__CONFIG' directive is used to embed configuration data within .asm file. ; The lables following the directive are located in the respective .inc file. ; See respective data sheet for additional information on configuration word. #define encoder PORTB #define LED PORTA #define li 0 ; Linksdrehung kündigt sich an #define re 1 ; Rechsdrehung kündigt sich an #define PrlfrLi 2 ; Prellfrei Links #define PrlfrRe 3 ; Prellfrei Rechts #define Chaos 4 ; DrehEncoder defekt #define Ausgeben 5 ; Counter hat sich geändert ; ;***** VARIABLE DEFINITIONS ; flags EQU 0x0C ; Bit flags. tmp1 equ 0x10 ; Arbeitsregister tmp2 equ 0x11 counter equ 0x12 ; Zählstand links equ 0x13 ; bit 0 - 3 für 4 Abfragen links rechts equ 0x14 ; bit 0 - 3 für 4 Abfragen rechts warte equ 0x15 ;***** Konstanten Ini_opt equ B'0000010' ;********************************************************************** ORG 0x000 ; processor reset vector init bsf STATUS, RP0 ; Bank 1 movlw Ini_opt movwf OPTION_REG MOVLW B'11000000' ; PortB: 6,7 Eingang MOVWF TRISB movlw B'00000000' ; PortA alle outputs movwf TRISA bcf STATUS, RP0 ; Bank 0 bcf PORTB, 1 ; Ansteuerung Schalter clrf PORTA ; LEDs aus clrf INTCON ; Interupt disable clrf counter ;Hauptprogrammschleife main call read_encoder ; Rotary Encoder abfragen call enc_auswerten btfsc flags,Ausgeben call ausgeben goto main ausgeben movfw counter ; Zählerstand anzeigen movwf LED bcf flags,Ausgeben return enc_auswerten movfw flags andlw B'00001100' ; nur Bits für "prellfrei" stehen lassen bz loesch sublw B'00001100' bz setzen_li btfsc flags,PrlfrLi bsf flags,li btfsc flags,PrlfrRe bsf flags,re goto auswert_ende setzen_li btfss flags,li goto setzen_re incf counter bcf flags,li bsf flags,Ausgeben goto auswert_ende setzen_re btfss flags,re goto auswert_ende decf counter bcf flags,re bsf flags,Ausgeben goto auswert_ende loesch bcf flags,li bcf flags,re auswert_ende return read_encoder clrf warte Lb1 movfw PORTB movwf tmp1 ; aktuelle encoder-Stellung nach temp bcf STATUS,C btfsc tmp1,6 bsf STATUS,C rlf links,f bcf STATUS,C btfsc tmp1,7 bsf STATUS,C rlf rechts,f ;Lb_links bsf flags,PrlfrLi movf links,w ; ist links = 0x00? -> btfsc STATUS,Z goto Lb_rechts incf links,w ; ist links = 0xFF? -> btfss STATUS,Z goto Lb_warte bcf flags,PrlfrLi Lb_rechts bsf flags,PrlfrRe movf rechts,w ; ist rechts = 0x00? -> btfsc STATUS,Z goto Lb_ende incf rechts,w ; ist rechts = 0xFF? -> btfss STATUS,Z goto Lb_warte bcf flags,PrlfrRe goto Lb_ende Lb_warte incf warte,f bnz Lb1 bsf flags,Chaos Lb_ende return END ; directive 'end of program' |