;******************************* Descripcion del Programa ******************************** ; Entradas: ; PORTA0: Seleccion de modo de operacion ; PORTA(0)=0 => medicion del periodo de la señal (T2) ; PORTA(0)=1 => medicion del ciclo util (T1) ; PORTA1: Calibracion de la Salida a 0° ; PORTA(1)=0 => Medicion de periodos y ciclos utiles (No Calibracion) ; PORTA(1)=1 => Calibración de medición a 0° ; PORTB7: Señal de entrada proveniente del sensor ; PORTB0: Señal habilitadora de impresion en displays ; ; Salidas: ; PORTB(3:1)+PORTA(4): Numero en BCD de las unidades de grados de inclinacion ; PORTA(2)+PORTB(6:4): Numero en BCD de los decimos de grados de inclinacion ; PORTA(3): Indicador de angulo negativo ; ;********************************* Inicializacion del PIC ********************************* list p=16f84A include p16f84A.inc ;************************* Declaracion de Constantes y Variables ************************* #define BANK0 bcf STATUS,RP0 #define BANK1 bsf STATUS,RP0 #define SHOW INTCON,1 #define SIGCHG INTCON,0 #define REBTIMER INTCON,2 #define SEÑAL PORTB,7 #define SELECCION PORTA,0 #define CALIBRACION PORTA,1 PuertoA equ b'00000011' ; PORTA0: Seleccion, PORTA1: Calibracion PuertoB equ b'10000001' ; PORTB7: Señal, PORTB0: Habilitacion de Impresion cblock h'C' estado ; Estado de ocupacion en medicion de tiempos (0:libre, 1:contando) ciclout ; Salir del ciclo de espera de interrupciones msbTMR0 ; Bits mas significativos (MSB) del TMR0 msbT1 ; Bits mas significativos (MSB) del ciclo util lsbT1 ; Bits menos significativos (LSB) del ciclo util msbT2 ; Bits mas significativos (MSB) del periodo lsbT2 ; Bits menos significativos (LSB) del periodo msbT1Cal ; Bits mas significativos del ciclo util de calibracion lsbT1Cal ; Bits menos significativos del periodo de calibracion msbT2Cal ; Bits mas significativos del periodo de calibracion lsbT2Cal ; Bits menos significativos del ciclo util de calibracion Op1Hi ; MSB Operando 1 de las operaciones aritmeticas SUMA, RESTA Y MULTIPLICACION Op1Lo ; LSB Operando 1 de las operaciones aritmeticas SUMA, RESTA Y MULTIPLICACION Op2Hi ; MSB Operando 2 de las operaciones aritmeticas SUMA, RESTA Y MULTIPLICACION Op2Lo ; LSB Operando 2 de las operaciones aritmeticas SUMA, RESTA Y MULTIPLICACION Prod3 ; Byte 3 del producto de la MULTIPLICACION y el operando 1 de la DIVISION Prod2 ; Byte 2 del producto de la MULTIPLICACION y el operando 1 de la DIVISION Prod1 ; Byte 1 del producto de la MULTIPLICACION y el operando 1 de la DIVISION Prod0 ; Byte 0 del producto de la MULTIPLICACION y el operando 1 de la DIVISION Temp0 ; Variable Temporal usada en la subrutina Mul16x16 Temp1 ; Variable Temporal usada en la subrutina Mul16x16 Temp2 ; Variable Temporal usada en la subrutina Mul16x16 Temp3 ; Variable Temporal usada en la subrutina Mul16x16 Div1 ; MSB del Operando 2 de la Division Div0 ; LSB del Operando 2 de la Division Ans1 ; MSB del resultado de la Division Ans0 ; LSB del resultado de la Division DivCnt ; Contador de la Division ZactualHi ; MSB de Zactual ZactualLo ; LSB de Zactual Angulo ; Angulo de Inclinacion NumH ; Entrada de la rutina bin2bcd NumL ; Entrada de la rutina bin2bcd Hund ; Cientos de Grados de Inclinacion (debe ser cero) Tens_Ones ; Grados de inclinacion en BCD Toshow ; Habilitador de Impresion endc ;********************* Inicializacion del Vector de Interrupciones *********************** org h'00' goto inicio org h'04' goto interrupcion ;**************************** Inicializacion de Puertos ********************************** inicio BANK1 movlw PuertoA movwf TRISA movlw PuertoB movwf TRISB BANK0 ;******************************** Programa Principal ************************************* BANK1 movlw b'01000000' ; Configuramos el control de interrupciones en flanco a movwf OPTION_REG ; ascendente y la division del TMRO (2*Fosc_int) BANK0 clrf PORTA ; Ponemos en cero las salidas en PORTA(1:4) clrf PORTB ; Ponemos en cero las salidas en PORTB(0:6) clrf ciclout ; Ciclout=0 para asegurar que espere el final de la lectura del tiempo clrf estado ; Estado=0 para asegurar que cuente el periodo de la señal clrf msbTMR0 ; Limpiamos los bits mas significativos (msb) del contador TMR0 clrf msbT1 ; Limpiamos los bits mas significativos (msb) del ciclo util clrf lsbT1 ; Limpiamos los bits menos significativos (lsb) del ciclo util clrf msbT2 ; Limpiamos los bits mas significativos (msb) del periodo clrf lsbT2 ; Limpiamos los bits menos significativos (lsb) del periodo clrf msbT1Cal ; Limpiamos los bits mas significativos de la contante de Calibracion (T1) clrf lsbT1Cal ; Limpiamos los bits menos significativos de la contante de Calibracion (T1) clrf msbT2Cal ; Limpiamos los bits mas significativos de la contante de Calibracion (T2) clrf lsbT2Cal ; Limpiamos los bits menos significativos de la contante de Calibracion (T2) clrf Op1Hi ; Limpiamos los MSB del Operando 1 clrf Op1Lo ; Limpiamos los LSB del Operando 1 clrf Op2Hi ; Limpiamos los MSB del Operando 2 clrf Op2Lo ; Limpiamos los LSB del Operando 2 clrf Div1 ; Limpiamos los MSB del Operando 2 de la Division clrf Div0 ; Limpiamos los LSB del Operando 2 de la Division clrf ZactualHi ; Limpiamos ZactualHi clrf ZactualLo ; Limpiamos ZactualLo clrf Angulo ; Limpiamos la variable Ángulo de Inclinacion clrf NumH clrf NumL clrf Hund clrf Tens_Ones ; Limpiamos los grados de inclinacion en BCD clrf Toshow ; Limpiamos el habilitador de impresion clrf TMR0 ; Borramos el TMR0 movlw b'10111000' ; Activamos interrupciones solo por rebosamiento del TMR0, por movwf INTCON ; flanco de subida de PORTB0 y por cambio de estado en PORTB7 ciclo btfss ciclout, 0 goto ciclo goto entregar entregar ; Es necesario eliminar offset en el contador debido a los tiempos consumidos por la ejecucion de instrucciones bcf estado,0 ; El programa esta de nuevo libre para contar movf TMR0,W ; Guardamos el valor de TMR0 en W btfss SELECCION ; Dependiendo de la funcion del programa, asignamos el contador a las variables correspondientes goto casoT2 casoT1 movwf Op1Lo ; El valor de TMR0 se convierte en el Operando 1 movf msbTMR0,W movwf Op1Hi clrf Op2Hi movlw b'00000110' ; El operando 2 de la resta es el numero 6 movwf Op2Lo call Sub16x16 ; Realizamos la resta movf Op1Hi,W ; Asignamos el resultado de la resta al valor del ciclo util de la señal movwf msbT1 movf Op1Lo,W movwf lsbT1 btfss CALIBRACION ; Chequeamos si esta en modo de Calibracion goto continuar ; Si no esta, continuamos movf lsbT1,W ; Si esta en Calibracion, copiamos los valores del ciclo util en constantes movwf lsbT1Cal movf msbT1,W movwf msbT1Cal goto continuar casoT2 movwf Op1Lo ; El valor de TMR0 se convierte en el Operando 1 movf msbTMR0,W movwf Op1Hi clrf Op2Hi movlw b'00000101' ; El operando 2 de la resta es el numero 5 movwf Op2Lo call Sub16x16 ; Realizamos la resta movf Op1Hi,W ; Asignamos el resultado de la resta al valor del periodo de la señal movwf msbT2 movf Op1Lo,W movwf lsbT2 btfss CALIBRACION ; Chequeamos si esta en modo de Calibracion goto continuar ; Si no esta, continuamos movf lsbT2,W ; Si esta en Calibracion, copiamos los valores del ciclo util en constantes movwf lsbT2Cal movf msbT2,W movwf msbT2Cal goto continuar continuar ; Ya tenemos los valores reales del periodo y del ciclo util btfsc CALIBRACION ; Si estamos en modo Calibracion, no realizamos ningun cálculo goto imprimir btfss SELECCION ; De acuerdo al modo de trabajo en el que estemos funcionando, realizamos cálculos goto FindZ FindX call FindXtilt ; Si estamos en modo T1, calculamos el angulo de inclinacion goto imprimir ; Imprimimos FindZ call FindZactual ; Si estamos en modo T2, calculamos la constante Zactual clrf ciclout ; Borramos el habilitador de salida del ciclo goto ciclo ; Volvemos a esperar interrupciones, pues no nos interesa imprimir el periodo de la señal imprimir btfss Toshow,0 ; Vemos si el habilitador de impresion esta en alto goto final ; Si no, no imprimimos y volvemos a esperar interrupciones bcf Toshow,0 ; Deshabilitamos nuevas impresiones btfss CALIBRACION ; Chequeamos si esta en modo de calibracion goto impang ; Si no esta, imprimimos el valor del angulo movlw b'10101011' ; Si esta, imprimimos un caracter extraño en los displays movwf PORTB bsf PORTA,2 bsf PORTA,4 goto final impang movf Tens_Ones,W ; Imprimimos el valor del angulo en los dos displays movwf PORTB ; PORTB tiene como entrada el bit 7, por lo que es necesario btfss Tens_Ones,7 ; utilizar el bit 2 del PORTA como salida goto ziro1 bsf PORTA,2 checkLsb btfss Tens_Ones,0 ; utilizar el bit 4 del PORTA como salida goto ziro2 bsf PORTA,4 goto final ziro1 bcf PORTA,2 goto checkLsb ziro2 bcf PORTA,4 final clrf ciclout ; Borramos el habilitador de salida del ciclo goto ciclo ; Volvemos a esperar interrupciones ;******************************** Subrutinas ********************************************* ;************************************************************************* ;** FindZactual ** ;** Esta subrutina realiza la siguiente operacion: ** ;** Zactual=(Zcal*T2actual)/T2cal ** ;** donde Zcal: Valor de T1 durante la calibración ** ;** T2actual: Valor de T2 medido ** ;** T2cal: Valor de T durante la calibración ** ;** Zactual: Variable que tiene en cuenta errores debidos a ** ;** desviaciones de T2 en el tiempo ** ;************************************************************************* FindZactual movf msbT1Cal,W movwf Op1Hi movf lsbT1Cal,W movwf Op1Lo movf msbT2,W movwf Op2Hi movf lsbT2,W movwf Op2Lo call Mul16x16 movf msbT2Cal,W movwf Div1 movf lsbT2Cal,W movwf Div0 call Div32x16 movf Ans1,W movwf ZactualHi movf Ans0,W movwf ZactualLo return ;************************************************************************* ;** FindXtilt ** ;** Esta subrutina realiza la siguiente operacion: ** ;** Xtilt=(K*(T1-Zactual))/T2actual ** ;** donde K: Cte de linealizacion de la funcion arcsin ** ;** T1: Valor de T1 medido ** ;** T2actual: Valor de T2 medido ** ;** Zactual: Variable que tiene en cuenta errores debidos a ** ;** desviaciones de T2 en el tiempo ** ;** Xtilt: Valor en grados de la inclinacion ** ;************************************************************************* FindXtilt movf ZactualHi,W ; Vamos a evaluar si T1 > Zactual subwf msbT1,W ; restando los dos y observando el Carry btfss STATUS,C ; Si C=1, msbT1 >= ZactualHi goto angneg ; Si C=0, T1 < Zactual, la inclinacion es negativa btfss STATUS,Z ; Vamos a evaluar si msbT1 = ZactualHi goto angpos ; Si Z=0, T1 > Zactual, la inclinacion es positiva movf ZactualLo,W ; Si Z=1, analizamos la parte baja de la misma forma subwf lsbT1,W btfss STATUS,C ; Si C=1, lsbT1 > ZactualLo, la inclinacion es positiva goto angneg ; Si C=0, lsbT1 < ZactualLo, la inclinacion es negativa angpos bcf PORTA,3 ; Borramos el indicador de angulo negativo movf msbT1,W ; Pasamos los parametros para realizar la resta movwf Op1Hi movf lsbT1,W movwf Op1Lo movf ZactualHi,W movwf Op2Hi movf ZactualLo,W movwf Op2Lo call Sub16x16 ; Restamos T1 - Zactual, el resultado queda en Op1 movlw b'00000001' ; Establecemos el valor de K y lo guardamos en Op2 movwf Op2Hi ; K = d'492' = b'0000000111101100' movlw b'11101100' movwf Op2Lo call Mul16x16 ; Multiplicamos K*(T1-Zactual), el resultado queda en Prod(3:0) movf msbT2,W ; Pasamos los parametros para realizar la division movwf Div1 movf lsbT2,W movwf Div0 call Div32x16 ; Dividimos (K*(T1-Zactual))/T2, el resultado queda en Ans(1:0) movf Ans0,W movwf Angulo ; Guardamos los ultimos 8 bits del resultado en la variable Angulo movwf NumL movf Ans1,W movwf NumH call Bin2dec ; Convertimos ese valor a BCD return angneg bsf PORTA,3 ; Ponemos en alto el indicador de angulo negativo movf ZactualHi,W ; Pasamos los parametros para realizar la resta movwf Op1Hi movf ZactualLo,W movwf Op1Lo movf msbT1,W movwf Op2Hi movf lsbT1,W movwf Op2Lo call Sub16x16 ; Restamos Zactual - T1, el resultado queda en Op1 movlw b'00000001' ; Establecemos el valor de K y lo guardamos en Op2 movwf Op2Hi ; K = d'492' = b'0000000111101100' movlw b'11101100' movwf Op2Lo call Mul16x16 ; Multiplicamos K*(Zactual-T1), el resultado queda en Prod(3:0) movf msbT2,W ; Pasamos los parametros para realizar la division movwf Div1 movf lsbT2,W movwf Div0 call Div32x16 ; Dividimos (K*(Zactual-T1))/T2, el resultado queda en Ans(1:0) movf Ans0,w movwf Angulo ; Guardamos los ultimos 8 bits del resultado en la variable Angulo movwf NumL movf Ans1,W movwf NumH call Bin2dec ; Convertimos ese valor a BCD return return ;************************************************************************* ;** Sub16x16 ** ;** Esta subrutina realiza la resta de dos operandos de 16 bits ** ;** Entradas: Op1Hi:Op1Lo ** ;** Op2Hi:Op2Lo ** ;** Salidas: Op1Hi:Op1Lo ** ;************************************************************************* Sub16x16 comf Op2Lo,F ; Complemento a dos del Operando 2 (LSB) btfsc STATUS,2 ; Caso especial de cero decf Op2Hi,F ; Restamos 1 al Operando 2 (MSB) comf Op2Hi,F ; Complemento a dos del Operando 2 (MSB) movf Op2Lo,W addwf Op1Lo,F ; Op1Lo + (Op2Lo)' btfsc STATUS,0 ; Caso especial de existencia de Carry incf Op1Hi,F ; Sumamos el carry movf Op2Hi,W addwf Op1Hi,F ; Op1Hi + (Op2Hi)' return ;************************************************************************* ;** Add16x16 ** ;** Esta subrutina realiza la suma de dos operandos de 16 bits ** ;** Entradas: Op1Hi:Op1Lo ** ;** Op2Hi:Op2Lo ** ;** Salidas: Op1Hi:Op1Lo ** ;************************************************************************* Add16x16 movf Op2Lo,W addwf Op1Lo,F btfsc STATUS,C incf Op1Hi,F movf Op2Hi,W addwf Op1Hi,F return ;************************************************************************* ;** Mul16x16 ** ;** Esta subrutina realiza la multiplicacion de dos operandos de ** ;** 16 bits y la guarda en una variable de 32 bits ** ;** Entradas: Op1Hi:Op1Lo ** ;** Op2Hi:Op2Lo ** ;** Salidas: Prod3:Prod2:Prod1:Prod0 ** ;************************************************************************* Mul16x16 clrf Temp0 ; Limpiamos las variables temporales usadas en esta subrutina clrf Temp1 clrf Temp2 clrf Temp3 clrf Prod3 ; Limpiamos el resultado de esta subrutina clrf Prod2 clrf Prod1 clrf Prod0 movf Op1Lo,W ; Copiamos Op1Hi:Op1Lo a Temp1:Temp0 movwf Temp0 movf Op1Hi,W movwf Temp1 checkOp1 movf Op1Hi,F ; Chequeamos si Op1Hi es nulo btfss STATUS,Z ; observando el flag Zero goto checkOp2 ; Si Op1Hi no es cero, chequeamos Op2 movf Op1Lo,F ; Op1Hi=0 btfsc STATUS,Z ; Chequeamos Op1Lo goto igual0 ; Si Op1 es cero, el resultado de la multiplicacion es cero checkOp2 movf Op2Hi,F ; Chequeamos si Op2Hi es nulo btfss STATUS,Z ; observando el flag Zero goto multiplicar ; Si Op2Hi no es cero, ejecutar la multiplicacion movf Op2Lo,F ; Op2Hi=0 btfsc STATUS,Z ; Chequeamos Op2Lo goto igual0 ; Si Op2Lo es cero, el resultado de la multiplicacion es cero multiplicar movf Op2Hi,F ; Chequeamos si Op2Hi ha sido reducido a cero btfss STATUS,Z goto testLSB ; Si no, seguimos con el algoritmo movf Op2Lo,F ; Chequeamos si Op2Lo ha sido reducido a cero btfsc STATUS,Z return ; Si ha sido reducido a cero, la multiplicacion ha concluido testLSB bcf STATUS,C ; Rotamos Op2 hacia la derecha rrf Op2Hi,F rrf Op2Lo,F btfss STATUS,C ; ¿es el LSB de Op2 = 1? goto rotar ; Si LSB=0, rotar a la izquierda los Temp movf Temp0,W ; Si LSB=1, Prod(3:0)=Prod(3:0)+Temp(3:0) addwf Prod0,F ; teniendo en cuenta todos los carry que se puedan btfss STATUS,C ; generar en esa suma goto add2 movlw h'01' addwf Prod1,F btfss STATUS,C goto add2 movlw h'01' addwf Prod2,F btfss STATUS,C goto add2 incf Prod3,F add2 movf Temp1,W ; Continuamos con la suma addwf Prod1,F btfss STATUS,C goto add3 movlw h'01' addwf Prod2,F btfss STATUS,C goto add3 incf Prod3,F add3 movf Temp2,W ; Continuamos con la suma addwf Prod2,F btfss STATUS,C goto add4 incf Prod3,F add4 movf Temp3,W ; Continuamos con la suma addwf Prod3,F rotar bcf STATUS,C ; Realizamos la rotacio de las variables temporales rlf Temp0,F rlf Temp1,F rlf Temp2,F rlf Temp3,F goto multiplicar ; Continuamos con el ciclo de multiplicacion igual0 clrf Prod0 ; Prod(3:0)=0 clrf Prod1 clrf Prod2 clrf Prod3 return ;************************************************************************* ;** Div32x16 ** ;** Esta subrutina realiza la multiplicacion de dos operandos de ** ;** 16 bits y la guarda en una variable de 32 bits ** ;** Entradas: Prod3:Prod2:Prod1:Prod0 ** ;** Div1:Div0 ** ;** Salidas: Ans1:Ans0 ** ;************************************************************************* Div32x16 clrf Ans1 clrf Ans0 movlw h'11' movwf DivCnt ; El contador de la division es inicializado en 17 da1 movf Div1,W subwf Prod3,W ; ¿Es Div1 > Prod3? btfss STATUS,C goto noSubs ; Salte si Div1 > Prod3 btfss STATUS,Z ; ¿Es Div1=Prod3? goto doSubs ; Salte si Div1 < Prod3 movf Div0,W subwf Prod2,W ; ¿Es Div0 > Prod2? btfsc STATUS,C goto doSubs ; Salte si Div0 < Prod2 noSubs bcf STATUS,C ; Limpiamos el Carry rlf Ans0,F ; Rotamos Ans(1:0) hacia la izquierda rlf Ans1,F bcf STATUS,C ; Limpiamos el Carry rlf Prod0,F ; Rotamos Prod(3:0) hacia la izquierda rlf Prod1,F rlf Prod2,F rlf Prod3,F goto chkCounter ; Chequeamos el contador doSubs movf Prod3,W movwf Op1Hi movf Prod2,W movwf Op1Lo movf Div1,W movwf Op2Hi movf Div0,W movwf Op2Lo call Sub16x16 ; Prod(3:2)=Prod(3:2)-Div(1:0) movf Op1Hi,W movwf Prod3 movf Op1Lo,W movwf Prod2 bsf STATUS,C rlf Ans0,F ; Rotamos Ans(1:0) hacia la izquierda poniendo un 1 en el LSB rlf Ans1,F bcf STATUS,C rlf Prod0,F ; Rotamos Prod(3:0) hacia la izquierda rlf Prod1,F rlf Prod2,F rlf Prod3,F chkCounter decfsz DivCnt,F goto da1 return ;------------------------------------------- ;Fast binary to decimal conversion (0..999) ; ;Input: NumH:NumL ;Output Hund:Tens_Ones (packed BCD) ; ; ; ;Size: 56 instructions ;Execution time (with return): 57 ; ;8-July-2000 by Nikolai Golovchenko ;23-Aug-2001 ;Based on 8bit BIN2BCD of Scott Dattalo ;------------------------------------------- Bin2dec swapf NumL, w ; Add the upper and lower nibbles addwf NumL, w ; to get the one's digit andlw 0x0F skpndc ; Go through a binary to bcd addlw 0x16 ; conversion for just the one's skpndc ; digit addlw 0x06 addlw 0x06 skpdc addlw -0x06 btfsc NumL, 4 ; bit 4 is a special case addlw 0x16 - 1 + 0x6 skpdc addlw -0x06 ; now adjust the ten's digit btfsc NumL,5 ; 2^5 = 32, so add 3 to the ten's addlw 0x30 ; digit if bit 5 is set btfsc NumL,6 ; 2^6 = 64, so add 6 addlw 0x60 ; if bit 6 is set btfsc NumL,7 ; 2^7 = 128, so add 2 (the ten's addlw 0x20 ; digit) if bit 7 is set addlw 0x60 ;convert the ten's digit to bcd clrf Hund rlf Hund,F ;if there's a carry, then the input btfss Hund,F ;was greater than 99. addlw -0x60 movwf Tens_Ones movlw 0x66 ; 2^8 = 256, so add 0x56 to Tens_Ones btfsc NumH,0 movlw 0x56 + 0x66 ; add 0x66 for decimal adjust addwf Tens_Ones,F skpnc incf Hund,F clrw skpc iorlw 0x60 skpdc iorlw 0x06 subwf Tens_Ones, f movlw 0x66 ; 2^9 = 512, so add 0x12 to Tens_Ones btfsc NumH,1 movlw 0x12 + 0x66 addwf Tens_Ones, f skpnc incf Hund, f clrw skpc iorlw 0x60 skpdc iorlw 0x06 subwf Tens_Ones, f rlf NumL, w ; copy bit 7 to carry rlf NumH, w ; load w with bits 9 to 7 btfsc NumH, 1 ; add b[9] addlw 1 addwf Hund, f ; add it to hundreds return ;****************************** Interrupciones ******************************************* interrupcion ; Entrada a la rutina de introducciones btfss SIGCHG ; Establecemos si hay cambio de estado en la señal goto nosenal ; La interrupcion no es debida al cambio en la señal signal ; Interrupcion por cambio de estado btfss SEÑAL ; Establecemos si la señal esta en 1 goto cero ; Si no, esta en 0 uno ; La señal cambio de 0 a 1 btfss SELECCION ; Establecemos el modo de funcionamiento del programa goto T2a contar clrf TMR0 ; Comenzamos a contar clrf msbTMR0 ; Borramos el contenido de todo el TMR0 bsf estado,0 ; El programa esta ocupado contando borrar bcf SIGCHG ; Borramos por software el flag de cambio de estado en PORTB(7) retfie T2a ; Estamos midiendo el periodo btfss estado,0 ; Si esta disponible para medir (es decir, no esta contando) goto contar ; comenzamos a contar salir bsf ciclout,0 ; Salimos del ciclo en el programa principal bcf SIGCHG ; Borramos por software el flag de cambio de estado en PORTB(7) retfie cero ; La señal cambio de 1 a 0 btfss SELECCION ; Establecemos el modo de funcionamiento del programa goto borrar ; Si estamos midiendo el periodo, no hacemos nada goto salir ; Si estamos midiendo el ciclo util, salimos del ciclo en el programa principal nosenal btfss SHOW ; Establecemos si la interrupcion es producida por un flanco en RB0 goto timer ; Si no, es claroq que se trata de un rebosamiento de TMR0 intimp bsf Toshow,0 ; Ponemos en uno el habilitador de impresion bcf SHOW ; Borramos por software el flag de interrupcion por flanco retfie timer ; La interrupcion es debida al rebosamiento de TMR0 incf msbTMR0,F ; Incrementamos en 1 los 8 msb del TMR0 bcf REBTIMER ; Borramos por software el flag de rebosamiento de TMR0 retfie end