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 ' Activa interrupciones generales.
INTE = 1 ' Activa la interrupción externa RB0/INT.
INTEDG = 1 ' Disparar la Interrupción con flanco de subida.
Dim X As DWord ' Variable de Posición actual (32bits).
Dim P As DWord ' Variable de Posición final (32bits).
TRISA = %100011
TRISB = %11111111
TRISC = %11111111
PORTA.2 = 0 ' Motor parado.
PORTA.3 = 0
PORTA.4 = 0 ' LED apagado.
X=0 ' Variables a cero.
P=0
'---------- Programa Principal ------------
Bucle:
If X = P Then
PORTA.4 = 0 ' Apaga el LED.
PORTA.2 = 0 ' Motor Parado.
PORTA.3 = 0
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.
GoTo Bucle
EndIf
PORTA.4 = 1 ' Enciende el LED.
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
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.
Cuando programaba en Proton IDE no se podía utilizar números negativos, al menos con el compilador que tenía. Por esta razón hago un truco. Hoy en día ya no lo uso, y el programa tiene muchos años, es recopilado de aquella época cuando controlaba motores con este lenguaje de programación.
El orden de las comparaciones para controlar el motor es jerárquico. Si alteras ese orden podría no funcionar correctamente, especialmente cuando le pides al PIC que el motor vaya a la posición cero. La primera comparación ha de ser siempre la de -igual-: "If X = P Then...". La comparación -menor de cero-: "If X > 70000 Then..." ha de estar antes de -mayor que- "If X > P Then..." y de -menor que- "If X < P Then...". Esto es importante.