NOLIST ;***************************************************************************** ; MACRO de gestion d'un codeur incremental ; d'abord appeler ReadEncodeurInit pour positionner les variables ; puis appeler ReadEncodeur pour mettre à jour les valeurs bit (dans EcodeurW) et Encodeur ; ; Cette macro a besoin de 4 octets en RAM ; EncodeurW qui contient les bits ; Value qui contient la valeur de lencodeur de 0 à MaxValue ; v1 et v2 qui contiennent le nombre d'états stables ; ; et de 2 litteraux ; MaxValue valeur maximale de l'encodeur, par exemple 0x7F pour un encodeur à 60 commuations/tour ; DebounceDelay litteral, seuil de changement de v1 ou v2, 100 par exemple ; ; ; exemple ; ; ReadEncodeurInit EncodeurW,Potar,0x3F,COUNT_v1,COUNT_v2,100 ;loop ; ReadEncodeur ; JZ loop2 ; MOVF Potar,W ; CALL SendHex ;loop2 ; ... ; GOTO loop ; ReadEncodeurInit MACRO EncodeurW,Value,MaxValue,v1,v2,DebounceDelay ; #DEFINE IO_ENCA PORTB,5 ; encodeur incremental A (leading in CW) ; #DEFINE IO_ENCB PORTB,4 ; encodeur incremental A (leading in CW) #DEFINE LAST_ENCB EncodeurW,0 #DEFINE LAST_ENCA EncodeurW,1 #DEFINE ENCB EncodeurW,2 #DEFINE ENCA EncodeurW,3 #DEFINE LAST_IO_ENCB EncodeurW,6 #DEFINE LAST_IO_ENCA EncodeurW,7 #DEFINE Encodeur Value #DEFINE MaxEncodeur MaxValue #DEFINE COUNT_ENCA v1 ; nombre d'états stables avant de modifier le bit logique #DEFINE COUNT_ENCB v2 #DEFINE COUNTMAX DebounceDelay MOVLW 0 ; initialise l'état encodeur BTFSC IO_ENCB ADDLW 1 BTFSC IO_ENCA ADDLW 2 MOVWF EncodeurW MOVLW 0 ; initialise la variable Encodeur à Zéro MOVWF Encodeur ; ici, on pourrait aller chercher dans l'E2PROM la dernière valeur connue ENDM ReadEncodeur MACRO Debounce IO_ENCA,LAST_IO_ENCA,ENCA,COUNT_ENCA,COUNTMAX Debounce IO_ENCB,LAST_IO_ENCB,ENCB,COUNT_ENCB,COUNTMAX ; les états ENCB et ENCA sont en position 2 et 3 de l'octet EncodeurW ; les états LAST_ENCB et LAST_ENCA sont en position 0 et 1 de EncodeurW MOVF EncodeurW,W CALL Encodeur_xcode XORLW 0 ; astuce pour positionner le flag Z, non positionné par un RETLW JZ ReadEncodeur_e ; ; exit avec Z=1 ; ici le codeur à changé d'état, il faut incrémenter/décrémenter la variable Encodeur XORLW 1 JZ ReadEncodeur_up MOVF Encodeur,W ; decremente Encodeur SKPZ DECF Encodeur,F GOTO ReadEncodeur_f ReadEncodeur_up CSGE Encodeur,MaxEncodeur INCF Encodeur,F ; Incremente Encodeur s'il n'est pas au maximum ReadEncodeur_f ; ici on a incrémenter ou décrémenter la valeur Encodeur ; avant de sortir (avec Z=0) on va 2 ou 3 choses MOVLW MaxEncodeur ; par sécurité, on clampe la valeur Encodeur ANDWF Encodeur,F ; ici on pourrait ranger la nouvelle valeur en E2PROM pour la garder en mémoire BTFSS ENCA ; recopie les valeurs dans LAST CLR LAST_ENCA BTFSC ENCA SETB LAST_ENCA BTFSS ENCB CLR LAST_ENCB BTFSC ENCB SETB LAST_ENCB CLRZ ; exit avec Z=0 pour indiquer que Encodeur vient de changer GOTO ReadEncodeur_e ; Subroutine de transcodage de l'état du codeur incrémental ; Le mot en entrée contient A-B (courant) et (A'-B') ancien selon le codage 0000 ABA'B' ; Le codeur a tourné CW si W=2,4,B,D sortie=+1 ; Le codeur a tourné CCW si W=1,7,8,E sortie=-1 (0xFF) ; Le codeur n'a pas bougé pour W=0,5,A,F sortie=0 ; Erreur (rebond) pour W=3,6,9,C sortie=0 Encodeur_xcode ANDLW 0x0F ADDWF PCL,F RETLW 0 ; 0000 pas bougé RETLW 0x0FF ; 0001 ccw RETLW 1 ; 0010 cw RETLW 0 ; 0011 erreur RETLW 1 ; 0100 cw RETLW 0 ; 0101 pas bougé RETLW 0 ; 0110 erreur RETLW 0x0FF ; 0111 ccw RETLW 0x0FF ; 1000 ccw RETLW 0 ; 1001 erreur RETLW 0 ; 1010 pas bougé RETLW 1 ; 1011 cw RETLW 0 ; 1100 erreur RETLW 1 ; 1101 cw RETLW 0x0FF ; 1110 ccw RETLW 0 ; 1111 pas bougé ReadEncodeur_e ENDM ;***************************************************************************** ; MACRO de traitement des rebonds ; cette macro doit être appelée à forte cadence (polling) ; elle maintient un bit en sortie sans rebond ; cette sortie est modifiée si on est sur un état stable en entrée ; caractérisé par une suite de N états identiques successifs ; ; IO,IOb bit en entrée PORTB,5 par exemple ; LAST,LASTb Mémoire bits,5 par exemple ; OUT,OUTb bit en sortie bits,7 par exemple ; COUNTMAX litteral N, seuil de changement, 100 par exemple ; Appel typique ; ; #DEFINE IO_ENCA PORTB,5 ; encodeur incremental A (leading in CW) ; #DEFINE ENCA bits,4 ; #DEFINE LAST_ENCA bits,6 ; Debounce IO_ENCA,LAST_ENCA,ENCA,COUNT_ENCA,100 ; ; ____________________________ ; contact ______________/*||| ||||]\_____________ ; _________________________________ ; sortie (OUT) _______________________| |_______ ; ; Debounce MACRO IO,IOb, LAST,LASTb, OUT,OUTb, COUNT, COUNTMAX LOCAL Debounce1,DebounceMatch0,DebounceMatch1,DebounceEnd JB IO,IOb,Debounce1 ; ici IO=0 JNB LAST,LASTb,DebounceMatch0 ; ici IO=0 et LAST=1 CLRF COUNT CLR LAST,LASTb GOTO DebounceEnd Debounce1 ; ici IO=1 JB LAST,LASTb,DebounceMatch1 ; ici IO=1 et LAST=0 CLRF COUNT SETB LAST,LASTb GOTO DebounceEnd DebounceMatch0 ; ici IO=0 et LAST=0 INCF COUNT,F CSLT COUNT,COUNTMAX CLR OUT,OUTb GOTO DebounceEnd DebounceMatch1 ; ici IO=1 et LAST=1 INCF COUNT,F CSLT COUNT,COUNTMAX SETB OUT,OUTb DebounceEnd ENDM LIST