Device=16F876A REMINDERS = FALSE Config XT_OSC, PWRTE_ON, CPD_OFF, WDT_OFF, BODEN_OFF, LVP_OFFREMINDERS = TRUEALL_DIGITAL = TRUE On_INTERRUPT GoTo InterrupcionSymbol 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 = %100011TRISB = %11111111TRISC = %11111111PORTA.2 = 0 ' Motor parado.PORTA.3 = 0PORTA.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 EndIfGoTo BucleEnd 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.