Programa Proton IDE de un PIC Encoder con un 16F876A, 16 bits de resolución, por Interrupción, bis.

Segunda Versión:

Device=16F876A
 
REMINDERS = FALSE
     Config XT_OSC, PWRTE_ON, CPD_OFF, WDT_OFF, BODEN_OFF, LVP_OFF
REMINDERS = TRUE
ALL_DIGITAL = TRUE 
On_INTERRUPT GoTo Interrupcion
Symbol INTE   = INTCON.4         ' RB0 Habilitar interrupción externa.
Symbol INTF   = INTCON.1         ' RB0 Flag de interrupción externa.
Symbol GIE    = INTCON.7         ' Global Interrupt Enable.
Symbol INTEDG = OPTION_REG.6     ' Flag = 0 Flanco bajada. Flag = 1 Flanco subida.
GIE    = 1                       ' Activar interrupciones generales.
INTE   = 1                       ' Activar la interrupción externa RB0/INT.
INTEDG = 1                       ' Activar la interrupción por flanco de subida.
TRISA  = %100011
TRISB  = %11111111
TRISC  = %11111111
PORTA.2 = 0         ' Motor parado.
PORTA.3 = 0
PORTA.4 = 0         ' Apaga el LED.
Dim P    As  DWord  ' Declaramos el valor de P como DWord (32 bits), es la posición. 
Dim X    As  DWord  ' Declaramos el valor de X como DWord (32 bits), es el contador de pulsos.
Dim Q    As  DWord  ' Q nos servirá para saber que ha llegado a la posición y no hay nueva posición.
Dim Aux  As  Byte   ' Se almacenará el valor anterior de RA0 y RA1, hasta la siguiente comparación.
Dim Enc  As  Byte   ' Se almacenará el valor actual de RA0 y RA1, hasta la siguiente comparación.
Dim Temp As  Byte   ' Contador para temporización. 
Dim Flag As  Bit    ' Bandera que avisa de nueva posición.
Q=0                 ' Ponemos todas las variables a cero.
P=0                
X=0
Aux=0              
Enc=0
Temp=0
Flag=0     
Bucle:              ' Bucle infinito.
    PORTA.4 = Flag   ' Enciende/apaga el LED si motor está en marcha o parado.
    
    If Flag=1 Then
       Q=P                  ' Igualamos para detectar cambios después.
       
       P.BYTE0 = PORTB      ' Carga el byte bajo de los 16 bits.
       P.BYTE1 = PORTC      ' Carga el byte alto de los 16 bits.
       
       P.0     = PORTA.0    ' RA0 y RA1 pasan a ocupar los bits P0 y P1,
       P.1     = PORTA.1    ' sobre-escribiéndolos.
        
       If P<>Q Then Flag=0  ' Detectar nueva entrada de datos.
    EndIf
    
    If X = P Then
       PORTA.2 = 0          ' Motor Parado.
       PORTA.3 = 0
       Flag=1
       GoTo Bucle
    EndIf
    If Temp>8 Then Temp=0   ' PWM.
    Inc Temp
    
    If Flag=1 And Temp>3 Then
       PORTA.2 = 0          ' Motor parado (PWM).
       PORTA.3 = 0
       GoTo Bucle
    Else
       If X > 70000 Then    ' Si x<0, Motor hacia delante.
          PORTA.2 = 1
          PORTA.3 = 0
          GoTo Bucle
       EndIf
        
       If X > P Then        ' Si x>p, motor hacia atrás. 
          PORTA.2 = 0
          PORTA.3 = 1  
          GoTo Bucle
       EndIf
         
       If X < P Then        ' Si x<p, motor hacia delante.
          PORTA.2 = 1
          PORTA.3 = 0   
          GoTo Bucle
       EndIf
        
    EndIf
    
GoTo Bucle
End
   
Interrupcion:                 '-------- Decodificador de Encoder --------------
       
    Context SAVE              ' Salva en contexto de los registros antes de operar con la interrupción.
    
    If PORTB.0 = 1    Then    ' Si RB0 se ha puesto a 1 (flanco de subida),
       INTEDG  = 0            ' entonces activar la siguiente interrupción por flanco de bajada.
       If PORTB.1 = 1 Then    ' Si RB1 está a 1
          Inc X               ' entonces incrementar el contador X.
       EndIf
    Else                      ' Si RB0 se ha puesto a 0 (flanco de bajada),
       INTEDG  = 1            ' entonces activar la siguiente interrupción por flanco de subida.
       If PORTB.1 = 1 Then    ' Si RB1 está 1
          Dec X               ' entonces decrementar el contador X.
       EndIf
    EndIf
     
    INTF = 0                  ' Borra el "flag" de la interrupción RB0/INT     
                              ' para poder permitir la siguiente interrupción.
    Context Restore           ' Restablece el contexto de los registros tal como estaban antes de la
                              ' interrupción.