list p=16f628A #include __CONFIG _PWRTE_ON & _WDT_OFF & _INTOSC_OSC_NOCLKOUT & _LVP_OFF ; Variablennamen vergeben ; steps1 equ 0x26 ; niedrige Bits der Stepvariable steps2 equ 0x27 ; hohe Bits der Stepvariable hilf equ 0x28 ; cha equ 0x29 ; Bits: 0:alt 1=neu 2=changed up 3:changed down 4: no change 5: weder a noch b geändert chb equ 0x30 ; Bits: 0:alt 1=neu 2=changed up 3:changed down 4: no change steps3 equ 0x31 ; höhere Bits der Stepvariable steps4 equ 0x32 ; noch höhere Bits der Stepvariable channela_in equ 0 channelb_in equ 1 ;************************************************************** ; Port B auf Ausgabe stellen Init bsf STATUS, RP0 ; auf Bank 1 umschalten movlw B'00000000' ; PortB alle output movwf TRISB bcf STATUS, RP0 ; auf Bank 0 zurückschalten clrf PORTB ; alle LEDs ausschalten bcf STATUS,C ; Carry-Flag löschen (hatte probleme damit dass es offenbar gesetzt war) CLRF PORTA ; Initialize PORTA by setting output data latches MOVLW 0x07 ; Turn comparators off and MOVWF CMCON ; enable pins for I/O functions BCF STATUS, RP1 BSF STATUS, RP0 ; Select Bank1 MOVLW 0x1F ; Value used to initialize data direction MOVWF TRISA ; Set RA<4:0> as inputs TRISA<5> always read as ‘1’. ; TRISA<7:6> depend on oscillator mode bcf STATUS, RP0 ; auf Bank 0 zurückschalten clrf steps1 clrf steps2 clrf steps3 clrf steps4 clrf cha clrf chb main call detect_changes call count_step call status2leds goto main ;;;;;;;;;;;;;;;;;;;; detect_changes ;status a bsf cha,1 btfss PORTA,channela_in bcf cha,1 ;status b bsf chb,1 btfss PORTA,channelb_in bcf chb,1 ;channel a btfsc cha,0 goto cha_is_set cha_not_set btfss cha,1 goto cha_nochange goto cha_upchanged cha_is_set btfss cha,1 goto cha_downchanged goto cha_nochange cha_upchanged bsf cha,2 bcf cha,3 goto end_cha cha_downchanged bsf cha,3 bcf cha,2 goto end_cha cha_nochange bcf cha,2 bcf cha,3 bsf cha,4 end_cha ;channel b btfsc chb,0 goto chb_is_set chb_not_set btfss chb,1 goto chb_nochange goto chb_upchanged chb_is_set btfss chb,1 goto chb_downchanged goto chb_nochange chb_upchanged bsf chb,2 bcf chb,3 goto end_chb chb_downchanged bsf chb,3 bcf chb,2 goto end_chb chb_nochange bcf chb,2 bcf chb,3 bsf chb,4 ;prüfen ob sich überhaupt etwas geändert hat: bcf cha,5 btfsc cha,4 bsf cha,5 end_chb return ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;Algorithmus: ;- Abbrechen wenn keine Veränderung ;- positiv zählen wenn: ; a ist und b kommt ; a geht und b ist ; a nicht und b geht ; a kommt und b ist nicht ;- ansonsten negativ zählen count_step ;analysiert ob rauf oder runter gezählt werden muss ; verlassen, wenn keine änderung: btfsc cha,5 return ;wenn_a_ist_und_b_wird; (+) btfss cha,0 goto a_nicht ; a ist btfss chb,2 goto count_step_next1 goto one_step_up count_step_next1 ;wenn_a_geht_und_b_ist; (+) btfss cha,3 goto one_step_down ; a geht btfss chb,0 goto one_step_down goto one_step_up a_nicht btfss chb,3 ;wenn a nicht und b geht (+) goto count_steps_next2 goto one_step_up count_steps_next2 ;wenn_a_kommt_und_b_nicht; (+) btfss cha,2 goto one_step_down btfsc chb,0 goto one_step_down goto one_step_up ;;; one_step_up ; führt das raufzählen aus incf steps1,1 btfss STATUS,Z return incf steps2,1 btfss STATUS,Z return incf steps3,1 btfss STATUS,Z return incf steps4,1 return ;;; one_step_down; führt das runterzählen aus movlw D'1' subwf steps1,1 btfsc STATUS,C return subwf steps2,1 btfsc STATUS,C return subwf steps3,1 btfsc STATUS,C return subwf steps4,1 return ;;; status2leds movfw steps1 movwf PORTB return ;----- ;********************************************************** ; Warteschleife w*100[ms] = w*18[ds] waitwds movwf i0 lwaitwds call Waitds decfsz i0 goto lwaitwds retlw 0 ;********************************************************** ; Warteschleife 250 ms Waitds movlw D'100' ; 100 ms Pause movwf i1 Waitms movlw .110 ; Zeitkonstante für 1ms movwf i2 Wait nop ; nop nop nop nop nop decfsz i2 ; 1 ms vorbei? goto Wait ; nein, noch nicht decfsz i1 ; 250 ms vorbei? goto Waitms ; nein, noch nicht retlw 0 ; das Warten hat ein Ende ;*********************************************************** end