Ejemplos de Programacion Asm

Descargar como docx, pdf o txt
Descargar como docx, pdf o txt
Está en la página 1de 415

EJEMPLOS DE PROGRAMACION ASM

;******************************** Librería "Aritmetica.INC" *****************************

; ===================================================================

; Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"

; E. Palacios, F. Remiro y L.J. López. www.pic16f84a.com

; Editorial Ra-Ma. www.ra-ma.es

; ===================================================================

; Librería de subrutinas con diversas operaciones aritméticas:

; - Arit_VisualizaBinario: Visualiza en el LCD el dato en binario que le entra por W.

; - Arit_Negar: Niega el contenido de un número binario de 16 bits.

; - Arit_Suma_16Bit: Realiza la suma con dos registros de 16 bits.

; - Arit_Resta_16Bit: Realiza la resta con dos registros de 16 bits.

; - Arit_Multiplica_8Bit: Multiplica dos registros de 8 bits.

; - Arit_Multiplica_16Bit: Multiplica dos registros de 16 bits.

; - Arit_Divide_8Bit: Divide dos registros de 8 bits.

; - Arit_Divide_16Bit: Divide un registro de 16 bits entre otro de 7 bits.

; - Arit_BCD_Bin_16Bit: Convierte un número BCD de 5 dígitos a binario natural de 16 bits.

; - Arit_Bin_BCD_16Bit: Convierte un número binario de 16 bits a BCD de 5 dígitos.

; - Arit_VisualizaBCD: Visualiza en el LCD un número decimal de varios dígitos.

CBLOCK

Arit_Operando_1L ; Byte bajo del operando 1.

Arit_Operando_1H ; Byte alto del operando 1.

Arit_Operando_2L ; Byte bajo del operando 2.

Arit_Operando_2H ; Byte alto del operando 2.

Arit_Resultado_1L ; Byte bajo del byte 1 del resultado.


Arit_Resultado_1H ; Byte alto del byte 1 del resultado.

Arit_Resultado_2L ; Byte bajo del byte 2 del resultado.

Arit_Resultado_2H ; Byte alto del byte 2 del resultado.

Arit_ContadorBits ; Para realizar diferentes contadores con bits.

Arit_Auxiliar ; Registro temporal para realizar operaciones


intermedias.

ENDC

; Subrutina "Arit_VisualizaBinario" -------------------------------------------------------

; Visualiza en binario en el visualizador LCD el dato que le entra por el registro W.

Arit_VisualizaBinario

movwf Arit_Auxiliar ; Pasa el dato a visualizar a un registro auxiliar.

movlw .8

movwf Arit_ContadorBits ; Se van a visualizar ocho bits en el LCD

Arit_VisualizaBit

rlf Arit_Auxiliar,F ; El bit a visualizar pasa al Carry .

movlw '1' ; En principio supone que es un "1".

btfss STATUS,C ; Comprueba su valor.

movlw '0' ; Ha sido cero.

call LCD_Caracter ; Lo visualiza.

decfsz Arit_ContadorBits,F ; ¿Ha terminado de visualizar los 8 bits?

goto Arit_VisualizaBit ; No, sigue visualizando otro bit.

return

; Subrutina "Arit_Negar" ----------------------------------------------------------------

; Niega el contenido de un número de 16 bits almacenado en dos registros


; (Arit_Operando_1H, Arit_Operando_1L).

; Lo hace en complemento a 2 por el método clásico, es decir, primero invierte todos los bits

; y después le suma "1".

; Se utiliza la instrucción "addwf __", en lugar de "incf ___", porque ésta no posiciona

; el flag de Carry.

; En el registro de trabajo W también aparece el resultado de la negación del byte bajo.

; Entrada: En los registros (Arit_Operando_1H, Arit_Operando_1L) el dato de

; 16 bits a negar.

; Salida: En los mismo registros (Arit_Operando_1H, Arit_Operando_1L) el dato de

; 16 bits negado. En (W) el byte más bajo negado.

Arit_Negar

comf Arit_Operando_1H,F ; Invierte los registros que contienen los operandos.

comf Arit_Operando_1L,F

movlw .1 ; Le suma 1.

addwf Arit_Operando_1L,F

btfsc STATUS,C ; Si hay acarreo tiene que llevarlo al byte


superior.

incf Arit_Operando_1H,F

movf Arit_Operando_1L,W ; En (W) el resultado del byte bajo.

return

; Subrutinas "Arit_Suma_16Bit" y "Arit_Resta_16Bit" ---------------------------------------

; Realiza la suma/resta en 16 bits (Operando 2) +/- (Operando 1) y el resultado lo guarda en


; (Operando 2). El resultado lo guarda en 16 bits. Es decir:

; (Arit_Operando_2H, Arit_Operando_2L) +/- (Arit_Operando_1H, Arit_Operando_1L) -->

; (Arit_Operando_2H, Arit_Operando_2L).

Arit_Resta_16Bit

call Arit_Negar ; Para la resta, simplemente niega el numero de


16 bits

Arit_Suma_16Bit ; (Arit_Operando_1H, Arit_Operando_1L)


y suma.

movf Arit_Operando_1L,W ; Suma el byte más bajo.

addwf Arit_Operando_2L,F ; y lo guarda en Arit_Operando_2L.

btfsc STATUS,C ; Si hay acarreo incrementa en una unidad uno


de

incf Arit_Operando_1H,F ; de los bytes altos.

movf Arit_Operando_1H,W

addwf Arit_Operando_2H,F ; Suma el byte alto.

return

; Subrutinas "Arit_Multiplica_8Bit" ------------------------------------------------------

; Realiza la multiplicación del contenido de dos registros de 8 bits. El resultado se almacena

; en 16 bits. La operación se realiza sin signo.

; El algoritmo utilizado se basa en el método empleado para efectuar una multiplicación

; manualmente con lápiz y papel. En este método, la multiplicación se lleva a cabo tomando

; un bit del multiplicador, empezando por el menos significativo:

; - Si es "1" se efectúa la suma del multiplicando y el producto parcial anterior. El producto

; parcial resultante se desplaza un bit a la derecha, introduciendo un cero por la izquierda.

; - Si es "0" la suma no es necesaria y el producto parcial resultante anterior se desplaza un

; bit a la derecha, introduciendo además un cero por la izquierda.


;

; Este proceso se repite tantas veces como bits tiene el multiplicador.

; Previo a la llamada de esta subrutinas los números a multiplicar se almacenan en los registros

; Arit_Multiplicando y Arit_Multiplicador. El resultado se almacena en 16 bits en los registros

; (Arit_Producto_H, Arit_Producto_L). Es decir:

; (Arit_Multiplicando) * (Arit_Multiplicador) --> (Arit_Producto_H, Arit_Producto_L)

; Se utilizan posiciones de memoria definidas anteriormente, a las que se les cambia el nombre

; por motivos puramente pedagógicos:

Arit_Multiplicando EQU Arit_Operando_1L

Arit_Multiplicador EQU Arit_Operando_2L

Arit_Producto_H EQU Arit_Resultado_1H

Arit_Producto_L EQU Arit_Resultado_1L

Arit_Multiplica_8Bit

clrf Arit_Producto_H ; En principio el resultado es cero.

clrf Arit_Producto_L

movlw .8 ; Carga el contador de 8 bits.

movwf Arit_ContadorBits

movf Arit_Multiplicando,W ; Carga el multiplicando.

Arit_MultiplicaBit8

rrf Arit_Multiplicador,F ; Va a comprobar el siguiente bit del multiplicador.

btfsc STATUS,C ; Si el bit del multiplicador es "1"

addwf Arit_Producto_H,F ; suma el resultado parcial anterior más el multiplicando.

rrf Arit_Producto_H,F ; Desplaza el resultado parcial un lugar hacia la

rrf Arit_Producto_L,F ; derecha, introduciendo un "0" por la izquierda.

decfsz Arit_ContadorBits,F ; ¿Ha multiplicado los 8 bits?


goto Arit_MultiplicaBit8 ; Repite la operación.

return

; Subrutinas "Arit_Multiplica_16Bit" ------------------------------------------------------

; Realiza la multiplicación del contenido de dos registros de 16 bits. El resultado se almacena

; en 32 bits. La operación se realizan sin signo.

; El algoritmo utilizado es similar al de la multiplicación de 8 bits.

; Previo a la llamada de esta subrutinas los números a multiplicar se almacenan en los registros

; (Arit_Multiplicando_H, Arit_Multiplicando_L) y (Arit_Multiplicador_H, Arit_Multiplicador_L).

; El resultado en 32 bits se proporciona en los registros

; (Arit_Producto_2H, Arit_Producto_2L, Arit_Producto_1H, Arit_Producto_1L).

; Se utilizan posiciones de memoria definidas anteriormente, a las que se les cambia el nombre

; por motivos puramente pedagógicos:

Arit_Multiplicando_H EQU Arit_Operando_1H

Arit_Multiplicando_L EQU Arit_Operando_1L

Arit_Multiplicador_H EQU Arit_Operando_2H

Arit_Multiplicador_L EQU Arit_Operando_2L

Arit_Producto_1H EQU Arit_Resultado_1H

Arit_Producto_1L EQU Arit_Resultado_1L

Arit_Producto_2H EQU Arit_Resultado_2H

Arit_Producto_2L EQU Arit_Resultado_2L

Arit_Multiplica_16Bit

clrf Arit_Producto_1H ; En principio el resultado es cero.


clrf Arit_Producto_1L

clrf Arit_Producto_2H

clrf Arit_Producto_2L

movlw .16 ; Carga el contador de 16 bits.

movwf Arit_ContadorBits

Arit_Multiplica16Bit

rrf Arit_Multiplicador_H,F ; Va a comprobar el siguiente bit del multiplicador.

rrf Arit_Multiplicador_L,F

btfss STATUS,C

goto Arit_Multiplicador_BitCero

movf Arit_Multiplicando_L,W ; Suma en 16 bits el resultado parcial y

addwf Arit_Producto_2L,F ; y el multiplicando.

btfsc STATUS,C

incf Arit_Producto_2H,F

movf Arit_Multiplicando_H,W

addwf Arit_Producto_2H,F

Arit_Multiplicador_BitCero

rrf Arit_Producto_2H,F ; Desplaza el resultado parcial un lugar hacia la

rrf Arit_Producto_2L,F ; derecha, introduciendo un "0" por la izquierda.

rrf Arit_Producto_1H,F

rrf Arit_Producto_1L,F

decfsz Arit_ContadorBits,F ; ¿Ha multiplicado los 16 bits?

goto Arit_Multiplica16Bit ; Repite la operación.

return

; Subrutinas "Arit_Divide_8Bit" ---------------------------------------------------------

; Realiza la división del contenido del dividendo de 8 bits entre un divisor de 8 bits.

;
; El algoritmo utilizado se basa en el método empleado para resolver una división de

; números binarios con lápiz y papel. En este método se van tomando los bits del dividendo

; uno a uno, comenzando por el más significativo: por cada bit del dividendo se genera un

; bit en el cociente. Los bits separados constituyen el dividendo parcial. Cada vez que se

; toma un nuevo bit del dividendo, el valor conjunto de los bits en el dividendo parcial se

; compara con el divisor. El el primero resulta ser mayor o igual al segundo, entonces al

; dividendo parcial se le resta el valor del divisor, el bit respectivo del cociente se pone

; a "1" y el resultado de la resta se convierte en el nuevo dividendo parcial, una vez que

; se le agrega el siguiente bit del dividendo. Si la comparación entre dividendo y divisor

; indica que éste último es mayor, entonces el bit del cociente se pone a "0" y al dividendo

; parcial anterior se le añade el siguiente bit del dividendo para formar el nuevo dividendo

; parcial. El proceso termina cuando se agotan los bits del dividendo; el contenido del

; dividendo parcial en ese momento constituye precisamente el resto de la operación de

; división.

; Entradas:

; - (Arit_Dividendo) que hacen de dividendo de 8 bits.

; - (Arit_Divisor) que es el divisor de 8 bits.

; Salidas:

; - (Arit_Cociente).

; - (Resto).

; - (W), en el registro de trabajo también el resto.

; La división se hará sin signo y el programa que le llame deberá detectar que el divisor no

; es cero.

; Se utilizan posiciones de memoria definidas anteriormente, a las que se les cambia el nombre

; por motivos puramente pedagógicos:


Arit_Dividendo EQU Arit_Operando_1L

Arit_Divisor EQU Arit_Operando_2L

Arit_Cociente EQU Arit_Resultado_1L

Arit_Resto EQU Arit_Resultado_2L

Arit_Divide_8Bit

clrf Arit_Cociente ; En principio el resultado es cero.

clrf Arit_Resto

movlw .8 ; Carga el contador.

movwf Arit_ContadorBits

Arit_DivideBit8

rlf Arit_Dividendo,F

rlf Arit_Resto,F ; (Arit_Resto) contiene el dividendo parcial.

movf Arit_Divisor,W

subwf Arit_Resto,W ; Compara dividendo parcial y divisor.

btfsc STATUS,C ; Si (dividendo parcial)>(divisor)

movwf Arit_Resto ; (dividendo parcial) - (divisor) --> (dividendo


parcial)

rlf Arit_Cociente,F ; Desplaza el cociente introduciendo el bit


apropiado.

decfsz Arit_ContadorBits,F

goto Arit_DivideBit8

movf Arit_Resto,W ; El resto también en (W)

return

; Subrutinas "Arit_Divide_16Bit" --------------------------------------------------------

; Realiza la división del contenido del dividendo de 16 bits entre un divisor de 7 bits.

; El máximo valor del divisor será 127.


;

; Se utiliza el mismo algoritmo explicado para la subrutina Arit_Divide_8bit.

; Entradas:

; - (Arit_Dividendo_H) y (Arit_Dividendo_L) que hacen de dividendo de 16 bits.

; - (Arit_Divisor) que es el divisor de 7 bits, (máximo b'01111111'=0x7F=d'127').

; Salidas:

; - (Arit_Cociente_H) y (Arit_Cociente_L) que hacen de cociente de 16 bits.

; - (Resto) de 8 bits.

; - (W), en el registro de trabajo también el resto.

; La división se hará sin signo y el programa que le llame deberá detectar que el divisor no

; es cero. El divisor será de 7 bits, es decir su valor máximo será:

; b'01111111'=0x7F=d'127'.

; Se utilizan posiciones de memoria definidas anteriormente, a las que se les cambia el nombre

; por motivos puramente pedagógicos:

Arit_Dividendo_H EQU Arit_Operando_1H

Arit_Dividendo_L EQU Arit_Operando_1L

Arit_Cociente_H EQU Arit_Resultado_1H

Arit_Cociente_L EQU Arit_Resultado_1L

Arit_Divide_16Bit

clrf Arit_Cociente_H ; En principio el resultado es cero.

clrf Arit_Cociente_L

clrf Arit_Resto

movlw .16 ; Carga el contador.

movwf Arit_ContadorBits
Arit_DivideBit16

rlf Arit_Dividendo_L,F

rlf Arit_Dividendo_H,F

rlf Arit_Resto,F ; (Arit_Resto) contiene el dividendo parcial.

movf Arit_Divisor,W

subwf Arit_Resto,W ; Compara dividendo parcial y divisor.

btfsc STATUS,C ; Si (dividendo parcial)>(divisor)

movwf Arit_Resto ; (dividendo parcial) - (divisor) --> (dividendo


parcial)

rlf Arit_Cociente_L,F ; Desplaza el cociente introduciendo el bit


apropiado

rlf Arit_Cociente_H,F ; "0" ó "1" según corresponda.

decfsz Arit_ContadorBits,F

goto Arit_DivideBit16

movf Arit_Resto,W ; El resto también en (W).

return

; Subrutinas "Arit_BCD_Bin_16Bit" ------------------------------------------------------

; Realiza la conversión de un número decimal de 5 digitos a binario natural de 16 bits.

; El máximo número a convertir será pues el b'1111111111111111'=0xFFFF=d'65535'

; El metodo usado para la conversión de un número BCD a binario natural, se basa en que

; cada dígito de un número codificado en BCD tiene un peso igual a la potencia de diez

; asociada a su posición. Para convertir el número BCD a su equivalente binario sólo es

; necesario multiplicar cada dígito BCD por su peso correspondiente y luego sumar todos

; los productos parciales obtenidos, el resultado es el número binario natural buscado.

; Es decir el valor de un número BCD de 5 dígitos se puede expresar como:

;
; 10^4 DecenasMillar + 10^3 Millares + 10^2 Centenas + 10 Decenas + Unidades =

; 10*10*10*10 DecenasMillar + 10*10*10 Millares + 10*10 Centenas + 10 Decenas + Unidades

; Finalmente la subrutina aplica el siguiente algoritmo:

; 10(10(10(10 DecenasMillar + Millares) + Centenas) + Decenas) + Unidades = Resultado

; El resultado se obtiene en 16 bits, es decir en 2 registros de 8 bits, que son:

; (Arit_Resultado_1H, Arit_Resultado_1L). Esta subrutina no tiene sistema alguno para

; detectar desbordamiento que debe preveerse en el programa que la llame.

; Previo a la llamada de esta subrutinas, cada digito del número decimal a convertir se

; almacenan en registros independientes, que son:

CBLOCK

Arit_Unidades

Arit_Decenas

Arit_Centenas

Arit_Millares

Arit_DecenasMillar

ENDC

Arit_BCD_Bin_16Bit

clrf Arit_Resultado_1H ; Realiza la carga inicial de los registros.

movf Arit_DecenasMillar,W

movwf Arit_Resultado_1L ; (Resultado Parcial) = (DecenasMillar)

movf Arit_Millares,W

call Arit_BCD_Operacion ; (10*DecenasMillar+Millares)

movf Arit_Centenas,W
call Arit_BCD_Operacion ; (10(10*DecenasMillar+Millares)+Centenas)

movf Arit_Decenas,W

call Arit_BCD_Operacion ; (10(10(10*DecenasMillar+Millares)+Centenas)


+Decenas)

movf Arit_Unidades,W

call Arit_BCD_Operacion ; Resultado final.

return

Arit_BCD_Operacion ; Realiza la operacion: (10 * Resultado Anterior


+ W)

movwf Arit_Auxiliar ; Guarda la variable de entrada.

movf Arit_Resultado_1L,W

movwf Arit_Multiplicando_L ; (Resultado Anterior) --> (Multiplicando)

movf Arit_Resultado_1H,W

movwf Arit_Multiplicando_H

clrf Arit_Multiplicador_H ; Carga el multiplicador con 10.

movlw .10

movwf Arit_Multiplicador_L

call Arit_Multiplica_16Bit ; (10 * Resultado Anterior)

movf Arit_Auxiliar,W

addwf Arit_Resultado_1L,F

btfsc STATUS,C

incf Arit_Resultado_1H,F ; (10 * Resultado Anterior + W)

return

; Subrutinas "Arit_Bin_BCD_16Bit" --------------------------------------------------------

; Convierte un número binario de 16 bits almacenado en los registros

; (Arit_Binario_H, Arit_Binario_L) a BCD.


; La conversión de binario a BCD se puede realizar a través de la división sucesiva del número

; binario entre diez (0x0A). El resto generado después de la primera división proporciona el

; dígito BCD correspondiente a la unidades y cada división subsecuente proporciona el dígito

; siguiente, es decir, decenas, centenas, etc. A continuación se explica un ejemplo expresado

; en decimal:

; 58634 : 10 = 5863 Resto = 4 (Unidades)

; 5863 : 10 = 586 Resto = 3 (Decenas)

; 586 : 10 = 58 Resto = 6 (Centenas)

; 58 : 10 = 5 Resto = 8 (Millares)

; 5 : 10 = 0 Resto = 5 (Decenas de Millar)

; El mismo ejemplo expresado en hexadecimal:

; 0xE50A : 0x0A = 0x16E7 Resto = 0x04 (Unidades)

; 0x16E7 : 0x0A = 0x024A Resto = 0x03 (Decenas)

; 0x024A : 0x0A = 0x003A Resto = 0x06 (Centenas)

; 0x003A : 0x0A = 0x0005 Resto = 0x08 (Millares)

; 0x0005 : 0x0A = 0x0000Resto = 0x05 (Decenas de Millar)

; Entrada: Número binario de 16 bits en los registros (Arit_Binario_H, Arit_Binario_L)

; Salida: Número decimal de 5 digitos en los registros:

; (Arit_DecenasMillar, Arit_Millares, Arit_Centenas, Arit_Decenas, Arit_Unidades).

CBLOCK

Arit_ContadorDigitos

Arit_Binario_H

Arit_Binario_L

ENDC
Arit_Bin_BCD_16Bit

movf Arit_Binario_H,W ; Carga el número de entrada como primer dividendo

movwf Arit_Dividendo_H ; parcial para realizar las sucesivas divisiones

movf Arit_Binario_L,W ; entre 10.

movwf Arit_Dividendo_L

movlw .5 ; El número decimal tendrá 5 digitos.

movwf Arit_ContadorDigitos

movlw Arit_Unidades ; Se va a utilizar direccionamiento indirecto.

movwf FSR ; Apunta al primer digito BCD, las


unidades.

Arit_DigitoBCD

movlw .10 ; Carga 10 en el divisor.

movwf Arit_Divisor

call Arit_Divide_16Bit ; Divide el cociente anterior entre 10.

movwf INDF ; El resto producido en la división es el digito


BCD.

incf FSR,F ; Apunta a siguiente posición de registros de


salida.

movf Arit_Cociente_H,W ; El cociente anterior será el dividendo de la

movwf Arit_Dividendo_H ; próxima division de 16 bits.

movf Arit_Cociente_L,W

movwf Arit_Dividendo_L

decfsz Arit_ContadorDigitos,F

goto Arit_DigitoBCD

return

; Subrutinas "Arit_VisualizaBCD" --------------------------------------------------------

; Visualiza en el LCD un número decimal de varios dígitos de manera tal que no se representan

; los ceros no significativos de la izquierda. El número decimal de entrada se almacena en los


; registros:(Arit_DecenasMillar, Arit_Millares, Arit_Centenas, Arit_Decenas, Arit_Unidades).

CBLOCK ; Si (Arit_FlagVisual)=0x00 No escribe el


siguiente

Arit_FlagVisual ; nibble si es "0".

ENDC ; Si (Arit_FlagVisual)=b'00000001' SI
escribe el

; siguiente nibble aunque sea


"0".

Arit_NumeroDigitos EQU .5

Arit_VisualizaBCD

clrf Arit_FlagVisual ; En principio no escribe si el dígito es cero.

movlw Arit_NumeroDigitos-1 ; El último dígito de unidades se visualizará siempre

movwf Arit_ContadorDigitos ; por tanto son n-1 digitos a comprobar.

movlw Arit_DecenasMillar ; Se va a utilizar direccionamiento indirecto.

movwf FSR ; Apunta al dígito BCD más a la izquierda.

Arit_VisualizaDigitoBCD

movf INDF,W ; Carga el dígito a visualizar.

btfsc Arit_FlagVisual,0 ; Si el dígito anterior fue visualizado también

goto Arit_VisualizaDigito ; visualiza el actual.

btfsc STATUS,Z ; Comprueba si el digito actual es cero

goto Arit_PasaAlSiguiente ; No visualiza y pasa al siguiente dígito.

Arit_VisualizaDigito

call LCD_Nibble ; Visualiza en digito

bsf Arit_FlagVisual,0 ; Señala que ha visualizado el dígito actual.

Arit_PasaAlSiguiente

decf FSR,F ; Apunta a la siguiente posición de los registros

decfsz Arit_ContadorDigitos,F ; de entrada.

goto Arit_VisualizaDigitoBCD
movf Arit_Unidades,W ; Las unidades siempre se visualizan, aunque
sean

call LCD_Nibble ; cero.

return

; ===================================================================

; Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"

; E. Palacios, F. Remiro y L. López. www.pic16f84a.com

; Editorial Ra-Ma. www.ra-ma.es

; ===================================================================

;******************************** Librería "BIN_BCD.INC" ********************************

; ===================================================================

; Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"

; E. Palacios, F. Remiro y L. López. www.pic16f84a.com

; Editorial Ra-Ma. www.ra-ma.es

; ===================================================================

; Un número binario natural de 8 bits es convertido a BCD. El resultado se guarda en tres

; posiciones de memorias llamadas: BCD_Centenas, BCD_Decenas y BCD_Unidades.

; El procedimiento utilizado es mediante restas de 10, tal como se explicó en el capítulo 9.

; Entrada: En el registro W el número binario natural a convertir.

; Salidas: En (BCD_Centenas), (BCD_Decenas) y (BCD_Unidades).

; En el registro W también las decenas (nibble alto) y unidades (nibble bajo).

; Subrutina "BIN_a_BCD" -----------------------------------------------------------------


CBLOCK ; En las subrutinas no se debe fijar la dirección

BCD_Centenas ; de la RAM de usuario. Se toma a continuación de

BCD_Decenas ; la última asignada.

BCD_Unidades

ENDC

BIN_a_BCD

clrf BCD_Centenas ; Carga los registros con el resultado inicial.

clrf BCD_Decenas ; En principio las centenas y decenas a cero.

movwf BCD_Unidades ; Se carga el número binario a convertir.

BCD_Resta10

movlw .10 ; A las unidades se les va restando 10 en cada

subwf BCD_Unidades,W ; pasada. (W)=(BCD_Unidades) -10.

btfss STATUS,C ; ¿C = 1?, ¿(W) positivo?, ¿(BCD_Unidades)>=10?

goto BIN_BCD_Fin ; No, es menor de 10. Se acabó.

BCD_IncrementaDecenas

movwf BCD_Unidades ; Recupera lo que queda por restar.

incf BCD_Decenas,F ; Incrementa las decenas y comprueba si ha llegado

movlw .10 ; a 10. Lo hace mediante una resta.

subwf BCD_Decenas,W ; (W)=(BCD_Decenas)-10).

btfss STATUS,C ; ¿C = 1?, ¿(W) positivo?, ¿(BCD_Decenas)>=10?

goto BCD_Resta10 ; No. Vuelve a dar otra pasada, restándole 10 a

BCD_IncrementaCentenas ; las unidades.

clrf BCD_Decenas ; Pone a cero las decenas

incf BCD_Centenas,F ; e incrementa las centenas.

goto BCD_Resta10 ; Otra pasada: Resta 10 al número a convertir.

BIN_BCD_Fin

swapf BCD_Decenas,W ; En el nibble alto de (W) también las decenas.


addwf BCD_Unidades,W ; En el nibble bajo de (W) las unidades.

return ; Vuelve al programa principal.

; La directiva "END" se debe poner en el programa principal no aquí.

; ===================================================================

; Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"

; E. Palacios, F. Remiro y L. López. www.pic16f84a.com

; Editorial Ra-Ma. www.ra-ma.es

; ===================================================================

;**************************** Librería "BUS_I2C.INC" ************************************

; ===================================================================

; Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"

; E. Palacios, F. Remiro y L. López. www.pic16f84a.com

; Editorial Ra-Ma. www.ra-ma.es

; ===================================================================

; Estas subrutinas permiten realizar las tareas básicas de control del bus serie I2C,

; por parte de un solo microcontrolador maestro.

; ZONA DE DATOS **********************************************************************

CBLOCK

I2C_ContadorBits ; Cuenta los bits a transmitir o a recibir.

I2C_Dato ; Dato a transmitir o recibido.

I2C_Flags ; Guarda la información del estado del


bus I2C.

ENDC
#DEFINE I2C_UltimoByteLeer I2C_Flags,0

; - (I2C_UltimoByteLeer)=0, NO es el último byte a leer por el maestro.

; - (I2C_UltimoByteLeer)=1, SÍ es el último byte a leer por el maestro.

; La definición de las líneas SCL y SDA del bus I2C se puede cambiar según las

; necesidades del hardware.

#DEFINE SCL PORTA,3 ; Línea SCL del bus I2C.

#DEFINE SDA PORTA,4 ; Línea SDA del bus I2C.

; Subrutina "SDA_Bajo" ------------------------------------------------------------------

SDA_Bajo

bsf STATUS,RP0 ; Configura la línea SDA como salida.

bcf SDA

bcf STATUS,RP0

bcf SDA ; SDA en bajo.

return

; Subrutina "SDA_AltaImpedancia" --------------------------------------------------------

SDA_AltaImpedancia

bsf STATUS,RP0 ; Configura la línea SDA entrada.

bsf SDA ; Lo pone en alta impedancia y,


gracias a la

bcf STATUS,RP0 ; Rp de esta línea, se mantiene a nivel


alto.

return
;

; Subrutina "SCL_Bajo" ------------------------------------------------------------------

SCL_Bajo

bsf STATUS,RP0

bcf SCL ; Configura la línea SCL como


salida.

bcf STATUS,RP0

bcf SCL ; La línea de reloj SCL en bajo.

return

; Subrutina "SCL_AltaImpedancia" --------------------------------------------------------

SCL_AltaImpedancia

bsf STATUS,RP0 ; Configura la línea SCL entrada.

bsf SCL ; Lo pone en alta impedancia y,


gracias a la Rp

bcf STATUS,RP0 ; de esta línea, se mantiene a nivel alto.

SCL_EsperaNivelAlto

btfss SCL ; Si algún esclavo mantiene esta línea en


bajo

goto SCL_EsperaNivelAlto ; hay que esperar.

return

; Subrutina "I2C_EnviaStart" ------------------------------------------------------------

; Esta subrutina envía una condición de Start o inicio.

I2C_EnviaStart

call SDA_AltaImpedancia ; Línea SDA en alto.


call SCL_AltaImpedancia ; Línea SCL en alto.

call Retardo_4micros ; Tiempo tBUF del protocolo.

call SDA_Bajo ; Flanco de bajada de SDA mientras SCL está alto.

call Retardo_4micros ; Tiempo tHD;STA del protocolo.

call SCL_Bajo ; Flanco de bajada del reloj SCL.

call Retardo_4micros

return

; Subrutina "I2C_EnviaStop" -------------------------------------------------------------

; Esta subrutina envía un condición de Stop o parada.

I2C_EnviaStop

call SDA_Bajo

call SCL_AltaImpedancia ; Flanco de subida de SCL.

call Retardo_4micros ; Tiempo tSU;STO del protocolo.

call SDA_AltaImpedancia ; Flanco de subida de SDA.

call Retardo_4micros ; Tiempo tBUF del protocolo.

return

; Subrutina "I2C_EnviaByte" -------------------------------------------------------------

; El microcontrolador maestro transmite un byte por el bus I2C, comenzando por el bit

; MSB. El byte a transmitir debe estar cargado previamente en el registro de trabajo W.

; De la subrutina ejecutada anteriormente I2C_EnviaStart o esta misma I2C_EnviaByte,

; la línea SCL se debe encontrar a nivel bajo al menos durante 5 µs.

I2C_EnviaByte

movwf I2C_Dato ; Almacena el byte a transmitir.


movlw 0x08 ; A transmitir 8 bits.

movwf I2C_ContadorBits

I2C_EnviaBit

rlf I2C_Dato,F ; Chequea el bit, llevándolo previamente


al Carry.

btfsc STATUS,C

goto I2C_EnviaUno

I2C_EnviaCero

call SDA_Bajo ; Si es "0" envía un nivel bajo.

goto I2C_FlancoSCL

I2C_EnviaUno

call SDA_AltaImpedancia ; Si es "1" lo activará a alto.

I2C_FlancoSCL

call SCL_AltaImpedancia ; Flanco de subida del SCL.

call Retardo_4micros ; Tiempo tHIGH del protocolo.

call SCL_Bajo ; Termina el semiperiodo positivo del reloj.

call Retardo_4micros ; Tiempo tHD;DAT del protocolo.

decfsz I2C_ContadorBits,F ; Lazo para los ocho bits.

goto I2C_EnviaBit

call SDA_AltaImpedancia ; Libera la línea de datos.

call SCL_AltaImpedancia ; Pulso en alto de reloj para que el esclavo

call Retardo_4micros ; pueda enviar el bit ACK.

call SCL_Bajo

call Retardo_4micros

return

; Subrutina "I2C_LeeByte" ---------------------------------------------------------------

;
; El microcontrolador maestro lee un byte desde el esclavo conectado al bus I2C. El dato

; recibido se carga en el registro I2C_Dato y lo envía a la subrutina superior a través

; del registro W. Se empieza a leer por el bit de mayor peso MSB.

; De alguna de las subrutinas ejecutadas anteriormente I2C_EnviaStart, I2C_EnviaByte

; o esta misma I2C_LeeByte, la línea SCL lleva en bajo al menos 5 µs.

I2C_LeeByte

movlw 0x08 ; A recibir 8 bits.

movwf I2C_ContadorBits

call SDA_AltaImpedancia ; Deja libre la línea de datos.

I2C_LeeBit

call SCL_AltaImpedancia ; Flanco de subida del reloj.

bcf STATUS,C ; En principio supone que es "0".

btfsc SDA ; Lee el bit

bsf STATUS,C ; Si es "1" carga 1 en el Carry.

rlf I2C_Dato,F ; Lo introduce en el registro.

call SCL_Bajo ; Termina el semiperiodo positivo del reloj.

call Retardo_4micros ; Tiempo tHD;DAT del protocolo.

decfsz I2C_ContadorBits,F ; Lazo para los 8 bits.

goto I2C_LeeBit

; Chequea si este es el último byte a leer para enviar o no el bit de reconocimiento

; ACK en consecuencia.

btfss I2C_UltimoByteLeer ; Si es el último, no debe enviar

; el bit de reconocimiento ACK.

call SDA_Bajo ; Envía el bit de reconocimiento ACK

; porque todavía no es el último


byte a leer.
call SCL_AltaImpedancia ; Pulso en alto del SCL para transmitir el

call Retardo_4micros ; bit ACK de reconocimiento. Este es tHIGH.

call SCL_Bajo ; Pulso de bajada del SCL.

call Retardo_4micros

movf I2C_Dato,W ; El resultado se manda en el registro de

return ; de trabajo W.

; ===================================================================

; Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"

; E. Palacios, F. Remiro y L. López. www.pic16f84a.com

; Editorial Ra-Ma. www.ra-ma.es

; ===================================================================

;**************************** Librería "LCD_MENS.INC" ********************************

; ===================================================================

; Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"

; E. Palacios, F. Remiro y L. López. www.pic16f84a.com

; Editorial Ra-Ma. www.ra-ma.es

; ===================================================================

; Librería de subrutinas para el manejo de mensajes a visualizar en un visualizador LCD.

CBLOCK

LCD_ApuntaCaracter ; Indica la posición del carácter a visualizar

; respecto del comienzo de todos


los mensajes,

; (posición de la etiqueta
"Mensajes").
LCD_ValorCaracter ; Código ASCII del carácter a

ENDC ; visualizar.

; Los mensajes tienen que estar situados dentro de las 256 primeras posiciones de la

; memoria de programa, es decir, no pueden superar la dirección 0FFh.

; Subrutina "LCD_Mensaje" ---------------------------------------------------------------

; Visualiza por pantalla el mensaje apuntado por el registro W.

; Los mensajes deben localizarse dentro de una zona encabezada por la etiqueta "Mensajes" y que

; tenga la siguiente estructura:

; Mensajes ; ¡Etiqueta obligatoria!

; addwf PCL,F

; Mensaje0 ; Posición inicial del mensaje.

; DT ".. ..", 0x00 ; Mensaje terminado en 0x00.

; Mensaje1

; ...

; ...

; FinMensajes

; La llamada a esta subrutina se realizará siguiendo este ejemplo:

; movlw Mensaje0 ; Carga la posición del mensaje.

; call LCD_Mensaje ; Visualiza el mensaje.

LCD_Mensaje

movwf LCD_ApuntaCaracter ; Posición del primer carácter del mensaje.


movlw Mensajes ; Halla la posición relativa del primer carácter

subwf LCD_ApuntaCaracter,F ; del mensaje respecto de etiqueta "Mensajes".

decf LCD_ApuntaCaracter,F ; Compensa la posición que ocupa "addwf PCL,F".

LCD_VisualizaOtroCaracter

movf LCD_ApuntaCaracter,W

call Mensajes ; Obtiene el código ASCII del carácter apuntado.

movwf LCD_ValorCaracter ; Guarda el valor de carácter.

movf LCD_ValorCaracter,F ; Lo único que hace es posicionar flag Z. En caso

btfsc STATUS,Z ; que sea "0x00", que es código indicador final

goto LCD_FinMensaje ; de mensaje, sale fuera.

LCD_NoUltimoCaracter

call LCD_Caracter ; Visualiza el carácter ASCII leído.

incf LCD_ApuntaCaracter,F ; Apunta a la posición del siguiente carácter

goto LCD_VisualizaOtroCaracter ; dentro del mensaje.

LCD_FinMensaje

return ; Vuelve al programa principal.

; Subrutina "LCD_MensajeMovimiento" -----------------------------------------------------

; Visualiza un mensaje de mayor longitud que los 16 caracteres que pueden representarse

; en una línea, por tanto se desplaza a través de la pantalla.

; En el mensaje debe dejarse 16 espacios en blanco, al principio y al final para

; conseguir que el desplazamiento del mensaje sea lo más legible posible.

CBLOCK

LCD_CursorPosicion ; Contabiliza la posición del cursor dentro de la

ENDC ; pantalla LCD


LCD_MensajeMovimiento

movwf LCD_ApuntaCaracter ; Posición del primer carácter del mensaje.

movlw Mensajes ; Halla la posición relativa del primer carácter

subwf LCD_ApuntaCaracter,F ; del mensaje respecto de la etiqueta "Mensajes".

decf LCD_ApuntaCaracter,F ; Compensa la posición que ocupa "addwf PCL,F".

LCD_PrimeraPosicion

clrf LCD_CursorPosicion ; El cursor en la posición 0 de la línea.

call LCD_Borra ; Se sitúa en la primera posición de la línea 1 y

LCD_VisualizaCaracter ; borra la pantalla.

movlw LCD_CaracteresPorLinea ; ¿Ha llegado a final de línea?

subwf LCD_CursorPosicion,W

btfss STATUS,Z

goto LCD_NoEsFinalLinea

LCD_EsFinalLinea

call Retardo_200ms ; Lo mantiene visualizado durante este tiempo.

call Retardo_200ms

movlw LCD_CaracteresPorLinea-1; Apunta a la posición del segundo carácter visualizado

subwf LCD_ApuntaCaracter,F ; en pantalla, que será el primero en la siguiente

goto LCD_PrimeraPosicion ; visualización de línea, para producir el efecto

LCD_NoEsFinalLinea ; de desplazamiento hacia la izquierda.

movf LCD_ApuntaCaracter,W

call Mensajes ; Obtiene el ASCII del carácter apuntado.

movwf LCD_ValorCaracter ; Guarda el valor de carácter.

movf LCD_ValorCaracter,F ; Lo único que hace es posicionar flag Z. En caso

btfsc STATUS,Z ; que sea "0x00", que es código indicador final

goto LCD_FinMovimiento ; de mensaje, sale fuera.

LCD_NoUltimoCaracter2

call LCD_Caracter ; Visualiza el carácter ASCII leído.

incf LCD_CursorPosicion,F ; Contabiliza el incremento de posición del


; cursor en la pantalla.

incf LCD_ApuntaCaracter,F ; Apunta a la siguiente posición por visualizar.

goto LCD_VisualizaCaracter ; Vuelve a visualizar el siguiente carácter

LCD_FinMovimiento ; de la línea.

return ; Vuelve al programa principal.

; ===================================================================

; Del libro "MICROCONTROLADOR PIC16F84. DESARROLLO DE PROYECTOS"

; E. Palacios, F. Remiro y L. López. www.pic16f84a.com

; Editorial Ra-Ma. www.ra-ma.es

; ===================================================================

; ML_CHIP_V1_1

; partimos del ML_CHIP1_0

;
(Salvamos en ML1_1_bk1.asm)

; Corrijo el bug de que AI7 solo esta la configuracion de 5 entradas analogicas.

; (el bug es que tambien aparecia cuando eran 3)

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++++

List p=PIC16F876A ;Tipo de procesador

include "P16F876A.INC" ;Definiciones de registros


internos

;Defines que le faltan al anterior include

ADCS2 EQU .6 ;Bit en registro ADCON1


PSPIF EQU .7 ;Bit en registro PIR1

PSPIE EQU .7 ;Bit en registro PIE1

;CONSTANTES

#define ByteAltoBeginFD HIGH Pg2_FLASH_DATA_Inicio

#define ByteBajoBeginFD LOW Pg2_FLASH_DATA_Inicio

#define ByteAltoBeginLADDER HIGH Pg3_ProgramaLadder

#define ByteBajoBeginLADDER LOW Pg3_ProgramaLadder

MSB EQU .7 ;Bit mas


significativo (RUTINAS MATEMATICAS)

LSB EQU .0 ;Bit menos


significativo (RUTINAS MATEMATICAS)

NAN EQU .4 ;bit4 = not-a-


number exception flag (RUTINAS MATEMATICAS)

;DIRECCIONES DE RAM

;BANCO_0_BANCO_0_BANCO_0_BANCO_0_BANCO_0_BANCO_0_BANCO_0_BANCO_0_BANCO
_0_BANCO_0_

TIMER_1S_L EQU 0x20 ;Byte bajo para conseguir


temporizaciones

;de 1 segundo
(10 milisegundos)

TIMER_1S_H EQU 0x21 ;Byte alto para conseguir


temporizaciones

;de 1 segundo
(100*10 mseg=1seg)

#define B0_PendienteSCL 0X22,4 ;a 1: Positiva, a 0: Negativa

RX_232_BYTESenTRAMA EQU 0x24 ;En rutina de RX-USART bytes en


trama
RX_232_DIRH EQU 0x25 ;En rutina de RX-USART. DirH del
PIC

RX_232_DIRL EQU 0x26 ;En rutina de RX-USART. DirL del


PIC

BUFFER_TX_NEXT EQU 0x28 ;Posicion del siguiente byte a tx


por USART

BUFFER_TX_LAST EQU 0x29 ;Posicion del ultimo byte a tx por


USART

BUFFER_RX_MENOS_1 EQU 0x29 ;Posicion en memoria antes del buffer de


Rx

BUFFER_RX_0 EQU 0x2A ;Primera posicion del buffer de


tx/rx del

;puerto serie.
Aqui se almacena dirH de la

;direccion de la
trama.

BUFFER_RX_1 EQU 0x2B ;Segunda posicion del buffer de


tx/rx del

;puerto serie.
Aqui se almacena dirL de la

;direccion de la
trama.

BUFFER_RX_2 EQU 0x2C ;Tercera posicion del buffer de


tx/rx del

;puerto serie.
Aqui se almacena el comando

;de la trama.

BUFFER_RX_3 EQU 0x2D ;Cuarta posicion del buffer de


tx/rx del

;puerto serie.
Aqui se almacena el tamaño
;de datos utiles
de la trama.

;;.ACK EQU 0x6F ;Flag de enviar o no NACK (Para


las rutinas de I2C)

LOCAL_0 EQU 0x62 ;Locales para parametros


en subrutinas.

LOCAL_1 EQU 0x63

LOCAL_2 EQU 0x64

LOCAL_3 EQU 0x65

LOCAL_4 EQU 0x66

LOCAL_5 EQU 0x67

LOCAL_6 EQU 0x68

LOCAL_7 EQU 0x69

AI_YaRealizada1Vez EQU 0x6A ;Bit0: 1AI: a 1 ya se ha realizado un AD

;Bit1: 2AI: a 1 ya
se ha realizado un AD

;Bit2: 3AI: a 1 ya
se ha realizado un AD

;Bit3: 4AI: a 1 ya
se ha realizado un AD

;Bit4: 5AI: a 1 ya
se ha realizado un AD

;Bit5: 6AI: a 1 ya
se ha realizado un AD

;Bit6: 7AI: a 1 ya
se ha realizado un AD

;Bit7: 8AI: a 1 ya
se ha realizado un AD

AI_EntradaAnalogLeida EQU 0x6B ;Bit0: 1AI: a 1 ya se ha leido 1ªAI=AI2


;Bit1: 2AI: a 1 ya
se ha leido 2ªAI=AI3

;Bit2: 3AI: a 1 ya
se ha leido 3ªAI=AI4

;Bit3: 4AI: a 1 ya
se ha leido 4ªAI=AI5

;Bit4: 5AI: a 1 ya
se ha leido 5ªAI=AI7

PCaPIC_FLASH_H EQU 0x6C ;direccion flash donde vamos a


grabar el

;siguiente codigo
ladder que nos envien

;desde el PC
(BYTE ALTO)

PCaPIC_FLASH_L EQU 0x6D ;direccion flash donde vamos a


grabar el

;siguiente codigo
ladder que nos envien

;desde el PC
(BYTE BAJO)

CODIGO_LADDER EQU 0x6F ;Codigo Ladder que hemos leido


de FLASH

;BANCO_1_BANCO_1_BANCO_1_BANCO_1_BANCO_1_BANCO_1_BANCO_1_BANCO_1_BANCO
_1_BANCO_1_

#define B1_bDelayIniLCD 0X20,0

#define B1_bEnviarIniLCD 0X20,1

#define B1_bBusyLCD 0X20,2

#define B1_bErrorLCD 0X20,3

#define B1_bIniLCDOK 0X20,4

#define B1_bDatosLCDOK 0X20,5

#define B1_bEnviandoIniLCD 0X20,6


#define B1_bEnviandoDatosLCD 0X20,7

#define B1_bIniLCDPaso1 0X21,0

#define B1_bIniLCDPaso2 0X21,1

#define B1_bIniLCDPaso3 0X21,2

#define B1_bIniLCDPaso4 0X21,3

#define B1_bEnviar1LineaLCD 0X21,4

#define B1_bEnviar2LineaLCD 0X21,5

#define B1_bEsperandoBusyFlag 0X21,6

B1_cDelayIniLCD EQU 0x22

B1_cCursorLCD EQU 0x23

B1_cEsperandoBusyFlag EQU 0x24

B1_LOCAL0_LCD EQU 0x25 ;Locales para parametros en


subrutinas.

B1_LOCAL1_LCD EQU 0x26 ;Locales para parametros en


subrutinas.

B1_PunteroLCD EQU 0x5A ;Usado por las rutinas de entrada al S.O.


de

;acceso al LCD

#define B1_BT_1 0x4F ;Base de tiempos para los timers de 1


mseg

#define B1_BT_10 0x50 ;Base de tiempos para los timers de 10


mseg

#define B1_BT_100 0x51 ;Base de tiempos para los timers de 100


mseg

#define B1_BT_1000 0x52 ;Base de tiempos para los timers de 1000


mseg

#define B1_DEC_BT_1 0x53 ;variable temporal para decrementar los


Timer

#define B1_SetPoint_100mseg 0x54 ;Variable para calcular cuando llevamos 100


mseg

;de timer1
#define B1_SetPoint_500mseg 0x55 ;Variable para calcular cuando llevamos 500
mseg

;de timer1

#define B1_DEC_BT_10 0x56 ;variable temporal para decrementar los Timer

#define B1_DEC_BT_100 0x57 ;variable temporal para decrementar los


Timer

#define B1_DEC_BT_1000 0x58 ;variable temporal para decrementar los


Timer

#define B1_DEC_BT 0x59 ;variable temporal para decrementar los


Timer

B1_IniBufferLCD EQU 0x27 ;Primera posicion del buffer del


LCD

GF_CONTADOR_UP EQU 0x5B ;GRABACION EN FLASH. Para


direccionar con FSR

GF_CONTADOR_DOWN EQU 0x5C ;Para saber cuando terminamos de


formar

;las 4 palabras
para grabar en FLASH

GF_0 EQU 0x5D ;Byte alto de la 1º palabra de 14


bits

GF_1 EQU 0x5E ; bajo de la 1º palabra de 14


bits

GF_2 EQU 0x5F ;Byte alto de la 2º palabra de 14


bits

GF_3 EQU 0x60 ; bajo de la 2º palabra de 14


bits

GF_4 EQU 0x61 ;Byte alto de la 3º palabra de 14


bits

GF_5 EQU 0x62 ; bajo de la 3º palabra de 14


bits

GF_6 EQU 0x63 ;Byte alto de la 4º palabra de 14


bits
GF_7 EQU 0x64 ; bajo de la 4º palabra de 14
bits

REMB3 EQU 0x5B ;RUTINAS MATEMATICAS

REMB2 EQU 0x5C

REMB1 EQU 0x5D

REMB0 EQU 0x5E

AARGB7 EQU 0x5B

AARGB6 EQU 0x5C

AARGB5 EQU 0x5D

AARGB4 EQU 0x5E

AARGB3 EQU 0x5F

AARGB2 EQU 0x60

AARGB1 EQU 0x61

AARGB0 EQU 0x62

AEXP EQU 0x63

SIGN EQU 0x64

FPFLAGS EQU 0x65

BARGB3 EQU 0x66

BARGB2 EQU 0x67

BARGB1 EQU 0x68

BARGB0 EQU 0x69

BEXP EQU 0x6A

TEMPB3 EQU 0x6B

TEMPB2 EQU 0x6C

TEMPB1 EQU 0x6D

TEMPB0 EQU 0x6E

TEMP EQU 0x6E ;OJO: Comprobar este

LOOPCOUNT EQU 0x6F


;BANCO_2_BANCO_2_BANCO_2_BANCO_2_BANCO_2_BANCO_2_BANCO_2_BANCO_2_BANCO
_2_BANCO_2_

;Zona de RD

RD000 EQU 0x10 ;Limite inferior

RD095 EQU 0x6F ;Limite superior

;BANCO_3_BANCO_3_BANCO_3_BANCO_3_BANCO_3_BANCO_3_BANCO_3_BANCO_3_BANCO
_3_BANCO_3_

Banco3Reg0x10 EQU 0x10 ;Registro para configuracion E/S

Banco3Reg0x11 EQU 0x11 ;Registro para configuracion E/S

Banco3Reg0x12 EQU 0x12 ;Registro para configuracion E/S

Banco3Reg0x13 EQU 0x13 ;Registro para configuracion E/S

Banco3Reg0x14 EQU 0x14 ;Registro para configuracion E/S

Banco3Reg0x15 EQU 0x15 ;Registro para configuracion E/S

Banco3Reg0x16 EQU 0x16 ;Registro para configuracion E/S

#define bConfig_0_EA 0X10,0 ;A 1 tenemos configuradas 0 Analog Input

#define bConfig_1_EA 0X10,1 ;A 1 tenemos configuradas 1 Analog Input

;AI2

#define bConfig_3_EA 0X10,2 ;A 1 tenemos configuradas 3 Analog Input

;AI2,AI3,AI5

#define bConfig_5_EA 0X10,3 ;A 1 tenemos configuradas 5 Analog Input

;AI2,AI3,AI4,AI5,
AI7

#define bConfigLCD 0X11,0 ;A 1 tenemos configurado el LCD

#define bConfigI2C 0X11,1 ;A 1 tenemos configurado el I2C

#define bConfigSHUT 0X11,2 ;A 1 tenemos configurado el Shutdown

#define bConfig485 0X11,3 ;A 1 tenemos configurado el 485


#define P1_DI1_DO0 0X12,0 ;A 1 tenemos configurado P1 como
Digital Input

#define P2_DI1_DO0 0X12,1 ;A 1 tenemos configurado P2 como


Digital Input

#define P3_DI1_DO0 0X12,2 ;A 1 tenemos configurado P3 como


Digital Input

#define P4_DI1_DO0 0X12,3 ;A 1 tenemos configurado P4 como


Digital Input

#define P5_DI1_DO0 0X12,4 ;A 1 tenemos configurado P5 como


Digital Input

#define P6_DI1_DO0 0X12,5 ;A 1 tenemos configurado P6 como


Digital Input

#define P7_DI1_DO0 0X12,6 ;A 1 tenemos configurado P7 como


Digital Input

#define P8_DI1_DO0 0X12,7 ;A 1 tenemos configurado P8 como


Digital Input

#define P9_DI1_DO0 0X13,0 ;A 1 tenemos configurado P9 como


Digital Input

#define P10_DI1_DO0 0X13,1 ;A 1 tenemos configurado P10 como


Digital Input

#define P11_DI1_DO0 0X13,2 ;A 1 tenemos configurado P11 como


Digital Input

#define P12_DI1_DO0 0X13,3 ;A 1 tenemos configurado P12 como


Digital Input

#define P13_DI1_DO0 0X13,4 ;A 1 tenemos configurado P13 como


Digital Input

#define P14_DI1_DO0 0X13,5 ;A 1 tenemos configurado P14 como


Digital Input

#define P15_DI1_DO0 0X13,6 ;A 1 tenemos configurado P15 como


Digital Input

#define P16_DI1_DO0 0X13,7 ;A 1 tenemos configurado P16 como


Digital Input

#define P17_DI1_DO0 0X14,0 ;A 1 tenemos configurado P17 como


Digital Input
#define P18_DI1_DO0 0X14,1 ;A 1 tenemos configurado P18 como
Digital Input

#define P19_DI1_DO0 0X14,2 ;A 1 tenemos configurado P19 como


Digital Input

#define P20_DI1_DO0 0X14,3 ;A 1 tenemos configurado P20 como


Digital Input

#define P21_DI1_DO0 0X14,4 ;A 1 tenemos configurado P21 como


Digital Input

#define P22_DI1_DO0 0X14,5 ;A 1 tenemos configurado P22 como


Digital Input

#define P23_DI1_DO0 0X14,6 ;A 1 tenemos configurado P23 como


Digital Input

#define P24_DI1_DO0 0X14,7 ;A 1 tenemos configurado P24 como


Digital Input

#define P25_DI1_DO0 0X15,0 ;A 1 tenemos configurado P25 como


Digital Input

#define P26_DI1_DO0 0X15,1 ;A 1 tenemos configurado P26 como


Digital Input

#define P27_DI1_DO0 0X15,2 ;A 1 tenemos configurado P27 como


Digital Input

#define P28_DI1_DO0 0X15,3 ;A 1 tenemos configurado P28 como


Digital Input

#define P29_DI1_DO0 0X15,4 ;A 1 tenemos configurado P29 como


Digital Input

#define P30_DI1_DO0 0X15,5 ;A 1 tenemos configurado P30 como


Digital Input

#define P31_DI1_DO0 0X15,6 ;A 1 tenemos configurado P31 como


Digital Input

#define P32_DI1_DO0 0X15,7 ;A 1 tenemos configurado P32 como


Digital Input

#define P33_DI1_DO0 0X16,0 ;A 1 tenemos configurado P33 como


Digital Input

#define P34_DI1_DO0 0X16,1 ;A 1 tenemos configurado P34 como


Digital Input
#define P35_DI1_DO0 0X16,2 ;A 1 tenemos configurado P35 como
Digital Input

#define P36_DI1_DO0 0X16,3 ;A 1 tenemos configurado P36 como


Digital Input

#define P37_DI1_DO0 0X16,4 ;A 1 tenemos configurado P37 como


Digital Input

#define P38_DI1_DO0 0X16,5 ;A 1 tenemos configurado P38 como


Digital Input

#define P39_DI1_DO0 0X16,6 ;A 1 tenemos configurado P39 como


Digital Input

#define P40_DI1_DO0 0X16,7 ;A 1 tenemos configurado P40 como


Digital Input

ByteBajo1AI EQU 0x17 ;Byte bajo de la 1-AI

ByteAlto1AI EQU 0x18 ;Byte alto de la 1-AI

ByteBajo2AI EQU 0x19 ;Byte bajo de la 1-AI

ByteAlto2AI EQU 0x1A ;Byte alto de la 1-AI

ByteBajo3AI EQU 0x1B ;Byte bajo de la 1-AI

ByteAlto3AI EQU 0x1C ;Byte alto de la 1-AI

ByteBajo4AI EQU 0x1D ;Byte bajo de la 1-AI

ByteAlto4AI EQU 0x1E ;Byte alto de la 1-AI

ByteBajo5AI EQU 0x1F ;Byte bajo de la 1-AI

ByteAlto5AI EQU 0x20 ;Byte alto de la 1-AI

ByteBajo6AI EQU 0x21 ;Byte bajo de la 1-AI

ByteAlto6AI EQU 0x22 ;Byte alto de la 1-AI

ByteBajo7AI EQU 0x23 ;Byte bajo de la 1-AI

ByteAlto7AI EQU 0x24 ;Byte alto de la 1-AI

ByteBajo8AI EQU 0x25 ;Byte bajo de la 1-AI

ByteAlto8AI EQU 0x26 ;Byte alto de la 1-AI

B3_ByteIO_P1_p8 EQU 0x27

B3_ByteIO_P9_p16 EQU 0x28


B3_ByteIO_P17_p24 EQU 0x29

B3_ByteIO_P25_p32 EQU 0x2A

B3_ByteIO_P33_p40 EQU 0x2B

#define P1_Valor 0X27,0 ;Valor del Pin

#define P2_Valor 0X27,1 ;Valor del Pin

#define P3_Valor 0X27,2 ;Valor del Pin

#define P4_Valor 0X27,3 ;Valor del Pin

#define P5_Valor 0X27,4 ;Valor del Pin

#define P6_Valor 0X27,5 ;Valor del Pin

#define P7_Valor 0X27,6 ;Valor del Pin

#define P8_Valor 0X27,7 ;Valor del Pin

#define P9_Valor 0X28,0 ;Valor del Pin

#define P10_Valor 0X28,1 ;Valor del Pin

#define P11_Valor 0X28,2 ;Valor del Pin

#define P12_Valor 0X28,3 ;Valor del Pin

#define P13_Valor 0X28,4 ;Valor del Pin

#define P14_Valor 0X28,5 ;Valor del Pin

#define P15_Valor 0X28,6 ;Valor del Pin

#define P16_Valor 0X28,7 ;Valor del Pin

#define P17_Valor 0X29,0 ;Valor del Pin

#define P18_Valor 0X29,1 ;Valor del Pin

#define P19_Valor 0X29,2 ;Valor del Pin

#define P20_Valor 0X29,3 ;Valor del Pin

#define P21_Valor 0X29,4 ;Valor del Pin

#define P22_Valor 0X29,5 ;Valor del Pin

#define P23_Valor 0X29,6 ;Valor del Pin

#define P24_Valor 0X29,7 ;Valor del Pin

#define P25_Valor 0X2A,0 ;Valor del Pin


#define P26_Valor 0X2A,1 ;Valor del Pin

#define P27_Valor 0X2A,2 ;Valor del Pin

#define P28_Valor 0X2A,3 ;Valor del Pin

#define P29_Valor 0X2A,4 ;Valor del Pin

#define P30_Valor 0X2A,5 ;Valor del Pin

#define P31_Valor 0X2A,6 ;Valor del Pin

#define P32_Valor 0X2A,7 ;Valor del Pin

#define P33_Valor 0X2B,0 ;Valor del Pin

#define P34_Valor 0X2B,1 ;Valor del Pin

#define P35_Valor 0X2B,2 ;Valor del Pin

#define P36_Valor 0X2B,3 ;Valor del Pin

#define P37_Valor 0X2B,4 ;Valor del Pin

#define P38_Valor 0X2B,5 ;Valor del Pin

#define P39_Valor 0X2B,6 ;Valor del Pin

#define P40_Valor 0X2B,7 ;Valor del Pin

B3_PunteroSigEEPROM EQU 0x39 ;Puntero al siguiente valor a escribir

;en memoria
EEPROM (0..3)

B3_PunteroUltEEPROM EQU 0x3A ;Puntero al ultimo valor a escribir en

;memoria
EEPROM (0..3)

B3_PrimerByteEEPROM EQU 0x3B ;1º Byte a escribir en memoria


EEPROM

B3_SegundoByteEEPROM EQU 0x3C ;2º Byte a escribir en memoria EEPROM

B3_DireccionEEPROM EQU 0x3D ;Direccion donde escribir el primer byte

;Esto para timers

TimControl_YaEnMarcha EQU 0
TimControl_TipoTimer_BitBajo EQU 1

TimControl_TipoTimer_BitAlto EQU 2

TimControl_BaseTiempo_BitBajo EQU 3

TimControl_BaseTiempo_BitAlto EQU 4

TimControl_SalidaTimer EQU 5

TimControl_SenalActivAnterior EQU 6

TimControl_ActivacionBT EQU 7

;BANCO COMUN

STACK_0 EQU 0x70 ;Se usa en el ciclo de


scan para llamar al SO

STACK_1 EQU 0x71 ;Se usa en el ciclo de


scan para llamar al SO

STACK_2 EQU 0x72 ;Se usa en el ciclo de


scan para llamar al SO

STACK_3 EQU 0x73 ;Se usa en el ciclo de


scan para llamar al SO

;...

COMUN_PORT_A EQU 0x70 ;Se usa fuera del ciclo de scan


para E/S

COMUN_PORT_B EQU 0x71 ;Se usa fuera del ciclo de scan


para E/S

COMUN_PORT_C EQU 0x72 ;Se usa fuera del ciclo de scan


para E/S

COMUN_PORT_D EQU 0x73 ;Se usa fuera del ciclo de scan


para E/S

PILA_LOGICA EQU 0x78 ;Pila logica para gestionar U,O,...

PILA_LOGICA_NIVEL EQU 0x79 ;Nivel de Pila logica para gestionar U,O,...

#define ESTADO_LOGICO_DE_OL 0X7A,0 ;Valor lógico del bit obtenido por U,O,...
#define ESTADO_LOGICO_PARA_OL 0X7A,1 ;Valor lógico de la pila para =,SET,...

#define Bx_EE_EnMarcha 0X7A,2 ;Hay un proceso de escritura de EEPROM


en marcha

#define Bx_BEnviarSigCARACTER 0X7A,3 ;Orden desde ISR de enviar siguiente caracter a

;LCD

SAVE_STATUS EQU 0x7B ;Salvar el contexto en las


interrupciones

SAVE_FSR EQU 0x7C ;Salvar el contexto en las


interrupciones

SAVE_PCLATH EQU 0x7D ;Salvar el contexto en las


interrupciones

SAVE_W EQU 0x7E ;Salvar el contexto en las


interrupciones

#define B0_Pre_SD_1s 0x22,1 ;Imagen de SD_1s

#define B0_Pre_SD_0_5s 0x22,2 ;Imagen de SD_0_5s

#define B0_Pre_SD_0_1s 0x22,3 ;Imagen de SD_0_1s

;#define B0_Pre_SD_EE_FREE 0x22,5 ;Imagen de SD_EE_FREE (En el banco


común)

#define B0_Pre_SD_EE_WROK 0x22,6 ;Imagen de SD_EE_WROK (En el banco común)

#define B0_Pre_SD_EE_WRER 0x22,7 ;Imagen de SD_EE_WRER (En el banco común)

#define Bx_SD_1CYCLE 0x74,0 ;SD_1CYCLE (En el banco común)

#define Bx_SD_2RUN 0x74,1 ;SD_2RUN (En el banco común)

#define Bx_SD_ON 0x74,2 ;SD_ON (En el banco


común)

#define Bx_SD_OFF 0x74,3 ;SD_OFF (En el banco común)

#define Bx_SD_1s 0x74,4 ;SD_1s (En el banco común)

#define Bx_SD_0_5s 0x74,5 ;SD_0_5s (En el banco común)

#define Bx_SD_0_1s 0x74,6 ;SD_0_1s (En el banco común)


#define Bx_SD_CF 0x74,7 ;SD_CF (En el banco común)

#define Bx_SD_EQ 0x75,0 ;SD_EQ (En el banco


común)

#define Bx_SD_NEQ 0x75,1 ;SD_NEQ (En el banco común)

#define Bx_SD_GE 0x75,2 ;SD_GE (En el banco común)

#define Bx_SD_GT 0x75,3 ;SD_GT (En el banco común)

#define Bx_SD_LE 0x75,4 ;SD_LE (En el banco común)

#define Bx_SD_LT 0x75,5 ;SD_LT (En el banco común)

#define Bx_SD_MUL_OVF 0x75,6 ;SD_MUL_OVF (En el banco común)

#define Bx_SD_DIV_BY0 0x75,7 ;SD_DIV_BY0 (En el banco común)

#define Bx_SD_EE_FREE 0x76,0 ;SD_EE_FREE (En el banco común)

#define Bx_SD_EE_WROK 0x76,1 ;SD_EE_WROK (En el banco común)

#define Bx_SD_EE_WRER 0x76,2 ;SD_EE_WRER (En el banco común)

#define Bx_SD_EE_RDOK 0x76,3 ;SD_EE_RDOK (En el banco común)

#define bTamano2B 0x77,0 ;Tamaño de la funcion es de 2 Bytes

#define bTamano4B 0x77,1 ;Tamaño de la funcion es de 4 Bytes

#define bFlancoUP 0x77,2 ;Flanco ascendente

#define bFlancoDOWN 0x77,3 ;Flanco descendente

#define bBit0Modalidad 0x77,4 ;Bit 0 de la modalidad de la primitiva

#define bBit1Modalidad 0x77,5 ;Bit 1 de la modalidad de la primitiva

#define bRunPrimitSO 0x77,7 ;a 1 debemos ejecutar proxima primitiva del SO

#define bPilaLogica 0x7A,1 ;Estado de la pila logica

#define B0_bPLConRUN0x23,5 ;CPU en RUN


;#define bTodasADLeidas 0x75,6 ;Todas las Entradas/Salidas
Analogicas han

; ;sido leidas por


primera vez

;LCD_LCD_LCD_LCD_LCD_LCD_LCD_LCD_LCD_LCD_LCD_LCD_LCD_LCD_LCD_LCD_LCD_LCD_LCD
_LCD_LCD_

#define B0_LCD_RS PORTC,1 ;LCD Register Select

#define B0_LCD_RW PORTC,2 ;Read/#Write

#define B0_LCD_E PORTC,5 ;Enable

#define B1_LCD_RS TRISC,1 ;LCD Register Select

#define B1_LCD_RW TRISC,2 ;Read/#Write

#define B1_LCD_E TRISC,5 ;Enable

;+++++++++++++++++++++++++++++++++++++++MACROS++++++++++++++++++++++++++++++++++++++
+++++++++

;++++++++++++++++++++++++++MACROS++++++++++++++++++++++++++MACROS++++++++++++++++++
++++++++++

;+++++++++++++++++++++++MACROS++++++++++MACROS+++++++++++++++++++++++++++++++++++++
++++++++++

;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++MACROS++++++++++++++
+++++++++

;++++++++++++++++++++++++++++++++++++++++++++MACROS+++++++++++++++++++++++++++++++++
+++++++++

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++MACROS+++++++++++++++++++++
+++++++++

;++++++MACROS+++++++++++++MACROS+++++++++++++++++++++++++++++++++++++MACROS+++++++
+++++++++++

pPagina0 macro

BCF PCLATH,3
BCF PCLATH,4

endm

pPagina1 macro

BSF PCLATH,3

BCF PCLATH,4

endm

pPagina2 macro

BCF PCLATH,3

BSF PCLATH,4

endm

pPagina3 macro

BSF PCLATH,3

BSF PCLATH,4

endm

sBanco0 macro

BCF STATUS,RP0

BCF STATUS,RP1

endm

sBanco1 macro

BSF STATUS,RP0

BCF STATUS,RP1

endm

sBanco2 macro
BCF STATUS,RP0

BSF STATUS,RP1

endm

sBanco3 macro

BSF STATUS,RP0

BSF STATUS,RP1

endm

salvar_W_STATUS macro

movwf SAVE_W ;En B0-B1:SAVE_W guardamos el acumulador

swapf STATUS,W ;Guardo STATUS en B0:SAVE_STATUS

clrf STATUS

movwf SAVE_STATUS

movf FSR,W ;Guardo FSR en B0:SAVE_FSR

movwf SAVE_FSR

movf PCLATH,W ;Guardo PCLATH en B0:SAVE_PCLATH

movwf SAVE_PCLATH

clrf PCLATH ;Consejo de Microchip (ver datasheet)

endm

restaurar_W_STATUS macro

clrf STATUS

movf SAVE_PCLATH,W ;Restauro PCLATH desde B0:SAVE_PCLATH

movwf PCLATH

movf SAVE_FSR,W ;Restauro FSR desde B0:SAVE_FSR

movwf FSR

swapf SAVE_STATUS,W ;Restauro STATUS desde B0:SAVE_STATUS


movwf STATUS

swapf SAVE_W,F ;Restauro W (Acumulador)

swapf SAVE_W,W

endm

org 0x00 ;Vector de Reset

clrf INTCON

clrf PCLATH

goto Inicio

org 0x04 ;Vector de interrupción

;+++++++++++++++++++++++++++++++++++++++INTERRUPCIONES+++++++++++++++++++++++++++++++
++++++++

;++++++++++++++++++++++++++INTERRUPCIONES+++++++++++INTERRUPCIONES+++++++++++++++++++
++++++++

;+++++++++++++++++++++++INTERRUPCIONES++INTERRUPCIONES+++++++++++++++++++++++++++++++
++++++++

;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++INTERRUPCIONES+++++++
++++++++

;++++++++++++++++++++++++++++++++++++++++++++INTERRUPCIONES++++++++++++++++++++++++++
++++++++

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++INTERRUPCIONES++++++++++++++
++++++++

;++++++INTERRUPCIONES+++++INTERRUPCIONES+++++++++++++++++++++++++++++INTERRUPCIONES+
+++++++++

Inter

salvar_W_STATUS

clrwdt
;******************************************************************************

;* TMR1: Primero comprobamos si ha sido la interrupcion del TMR1 la que ha saltado

;******************************************************************************

inter_TMR1_

btfsc PIR1,TMR1IF ;Bit de señalizacion para el rebose del TMR1

goto inter_TMR1

;******************************************************************************

;* USART: comprobamos si la USART esta libre para transmitir un caracter

;******************************************************************************

Inter_tx_usart_

sBanco1

btfss PIE1,4

goto Inter_rx_usart_

sBanco0

; bcf STATUS,RP0 ;Banco 0

btfsc PIR1,4

goto Inter_tx_usart

;******************************************************************************

;* USART: comprobamos si ha llegado un caracter.

;******************************************************************************

Inter_rx_usart_

sBanco0

; bcf STATUS,RP0 ;Banco 0

btfss PIR1,5

goto salir_inter
;Esto lo he cambiado de sitio el 21-12-2002

bcf PIR1,5 ;Restaura el flag de recepcion

;******************************************************************************

;* Hemos recibido un caracter por la USART.

;******************************************************************************

btfss 0x23,0 ;Chequeamos el bit "Trama de maestro recibida, no analizada"

goto m_rx_2

goto m_rx_1

m_rx_1

goto salir_inter

m_rx_2

movlw .201 ;¿Es el caracter recibido el chr(201)?

subwf RCREG,W ;Restamos a W el contenido de 0x22, y lo dejamos en W

btfss STATUS,Z ;Comprobamos si la resta es cero.

;Si la resta es 0 => Z==1

;btfss salta una instrucción si el bit es 1

goto m_rx_3

goto m_rx_4 ;Saltamos a m_rx_4 si el caracter recibido es el SOT

m_rx_3

btfss 0x23,1 ;Chequeamos el bit "Recibiendo trama de maestro"

goto m_rx_1

goto m_rx_5
m_rx_4

bsf 0x23,1 ;Ponemos a 1 el bit "Recibiendo trama de maestro"

clrf RX_232_BYTESenTRAMA

;Ponemos a 0 el byte "bytes en trama"

;****************************************************************************

;* Utilizamos un bucle con direccionamiento indirecto para poner a 0 la zona

;* del buffer de recepcion

;****************************************************************************

bcf STATUS,IRP ;Selecciona el banco en direccionamiento indirecto

movlw BUFFER_RX_0 ;Empezamos en la posición 0x2A

movwf FSR

bucle_m_rx_4

clrf INDF

incf FSR,F ;Incrementamos FSR

;Comprobamos si hemos llegado a 0x61

;movlw 0x3F

movlw 0x61

subwf FSR,W ;Le restamos FSR y lo dejamos en W

btfss STATUS,Z ;Comprobamos si es cero la resta

goto bucle_m_rx_4 ;Todavia no es 0x61

goto m_rx_1

;*****************************************************************************

;* Fin del bucle con direccionamiento indirecto

;*****************************************************************************

m_rx_5 ;¿Es el caracter recibido el chr(202)?

movlw .202 ;0xCA=202 antes 0x02 ;Metemos en W el 0x02 caracter EOT


subwf RCREG,W ;Restamos a W el contenido de 0x22, y lo dejamos en W

btfss STATUS,Z ;Comprobamos si la resta es cero.

;Si la resta es 0 => Z==1

;btfss salta una instrucción si el bit es 1

goto m_rx_6 ;Saltamos a m_rx_6 si el caracter recibido no es el EOT

goto m_rx_7 ;Saltamos a m_rx_7 si el caracter recibido es el EOT

m_rx_6 ;¿es el byte "Bytes en trama" == 54?

movlw .54 ;Metemos en W el .54

subwf RX_232_BYTESenTRAMA,W

;Restamos a W el contenido de 0x24, y lo


dejamos en W

btfss STATUS,Z ;Comprobamos si la resta es cero.

;Si la resta es 0 => Z==1

;btfss salta una instrucción si el bit es 1

goto m_rx_9 ;Saltamos a m_rx_9 si no es .54

goto m_rx_8 ;Saltamos a m_rx_8 si es .54

m_rx_7

bcf 0x23,1 ;Ponemos a 0 el bit "Recibiendo trama de maestro"

bsf 0x23,0 ;Ponemos a 1 el bit "Trama de maestro recibida, no


analizada"

bcf 0x23,2 ;Ponemos a 0 el bit "Trama comprobada"

bcf 0x23,3 ;Ponemos a 0 el bit "Trama para nosotros"

goto m_rx_1

m_rx_8

bcf 0x23,1 ;Ponemos a 0 el bit "Recibiendo trama de maestro"

clrf RX_232_BYTESenTRAMA
;Ponemos a 0 el byte "Bytes en trama"

goto m_rx_1

m_rx_9

;******************************************************************************

;* Hemos recibido un caracter interior a la trama.

;******************************************************************************

bcf STATUS,RP0

incf RX_232_BYTESenTRAMA,F

;Incrementamos el valor del byte "Bytes en


Trama"

;Tenemos que hacer un direccionamiento


indirecto para

;almacenar en el buffer.

movf RX_232_BYTESenTRAMA,W

;Cargamos en el acumulador

addlw BUFFER_RX_MENOS_1

;Es la posicion BufferRecepcion[-1]

movwf FSR ;Ya tenemos en FSR la dirección de


BufferRecepcion[ultimo]

bcf STATUS,IRP ;Seleccionamos banco 0 para direccionamiento indirecto

movf RCREG,W ;Cargamos en W el caracter recibido

movwf INDF ;Ya lo tenemos grabado.

goto m_rx_1

;******************************************************************************

;* Interrupción de disponibilidad de transmision por USART

;******************************************************************************

Inter_tx_usart
btfss 0x23,7 ;Comprobamos si tenemos algo para enviar

goto salir_inter

;******************************************************************************

;* Vamos a enviar los caracteres de la trama

;******************************************************************************

sBanco0

movf BUFFER_TX_NEXT,W

subwf BUFFER_TX_LAST,W

btfsc STATUS,Z

goto Inter_tx_usart_Fin_Envio_Trama

movf BUFFER_TX_NEXT,W

movwf FSR ;Ya tenemos en FSR la dirección del caracter a enviar.

bcf STATUS,IRP ;Seleccionamos banco 0 para direccionamiento indirecto

movf INDF,W

movwf TXREG

incf BUFFER_TX_NEXT,F

goto salir_inter

Inter_tx_usart_Fin_Envio_Trama

sBanco1

bcf PIE1,TXIE ;Inhabilitamos la interrupcion

sBanco0

bcf 0x23,7

goto salir_inter

;******************************************************************************
;* Interrupción del TMR1 cada 1 mseg.

;******************************************************************************

inter_TMR1

sBanco0

bcf PIR1,TMR1IF ;Borramos el flag del Timer1

movlw 0xFF ;Recargamos el valor del Timer1 a 4 MHZ

movwf TMR1H

movlw 0x86

movwf TMR1L

;movlw 0xFD ;Recargamos el valor del Timer1 a 20 MHZ

;movwf TMR1H

;movlw 0xA2

;movwf TMR1L

;Comprobamos que no se haya quedado bloqueada la USART por overrun, si es asi

;no recibiremos mas caracteres por la USART hasta que la reseteemos.

btfss RCSTA,OERR

goto Usart_Fin_Bloqueo ;Usart_No_Bloqueada

Usart_Si_Bloqueada

bcf RCSTA,CREN ;Reseteamos el overrun

bsf RCSTA,CREN

Usart_Fin_Bloqueo

sBanco1

incf B1_BT_1,f ;Base de tiempos para los timers de 1 mseg


;Si estamos esperando 10 mseg entre pasos de inicializacion de LCD incrementamos

btfss B1_bDelayIniLCD

goto LCD_Delay_End

incf B1_cDelayIniLCD,F

LCD_Delay_End

; ;Si estamos esperando respuesta del LCD al BusyFlag

; btfss B1_bEsperandoBusyFlag

; goto LCD_noEsperaBusyFlag

; ;Estamos esperando respuesta del busy flag, pero antes vamos a asegurarnos de que

; ;el comando esta bien pedido

; sBanco0

; btfss B0_LCD_E

; goto LCD_noEsperaBusyFlag

; btfsc B0_LCD_RS

; goto LCD_noEsperaBusyFlag

; btfss B0_LCD_RW

; goto LCD_noEsperaBusyFlag

; btfss PORTB,7

; goto LCD_EsperaBusyFlag0

; goto LCD_noEsperaBusyFlag

;LCD_EsperaBusyFlag0

; sBanco0

; bcf B0_LCD_E ;Quitamos el enable

; sBanco1

; bcf B1_bEsperandoBusyFlag
;

; ;bsf PCLATH,3

; ;Esto faltaba:

; bsf Bx_BEnviarSigCARACTER

; ;call EnviarSiguienteA_LCD

; ;bcf PCLATH,3

;LCD_noEsperaBusyFlag

sBanco0

decfsz TIMER_1S_L,F ;En la posición de RAM 0x20 tenemos 10

goto todavia_no_cero

goto ya_es_cero

todavia_no_cero

goto salir_inter_TMR1

ya_es_cero

;Hemos atendido a la interrupción 10 veces.

; bcf STATUS,RP0 ;Selecciona banco 0

;**************************************************************************

;* Esto se ejecuta cada 10 mseg

;* Si el bit 7 del 0x27 esta a 0, es que queremos que se decremente cada

;* 10 mseg.

;* Cuando llegue a 0 ponemos su bit 7 a 1

;**************************************************************************

;**************************************************************************
;* Fin de la rutina que se ejecuta cada 10 mseg

;**************************************************************************

sBanco0

;RUTINA de lo que hacemos cada 10 mseg

movlw .10

movwf TIMER_1S_L

sBanco1

incf B1_BT_10,f ;Base de tiempos para los timers de 10 mseg

HanPasado100mseg_

;sBanco1

decfsz B1_SetPoint_100mseg,F

goto HanPasado500mseg_

;RUTINA de lo que hacemos cada 100 mseg

;Recargamos el valor del set point de 100 mseg.

movlw .10

movwf B1_SetPoint_100mseg

incf B1_BT_100,f ;Base de tiempos para los timers de 10 mseg

;Esto es lo que hacemos cada 100mseg.

sBanco0

btfss B0_Pre_SD_0_1s

goto Pre_SD000_6_es_cero

goto Pre_SD000_6_es_uno
Pre_SD000_6_es_cero

bsf B0_Pre_SD_0_1s

goto Pre_SD000_6_seguir

Pre_SD000_6_es_uno

bcf B0_Pre_SD_0_1s

Pre_SD000_6_seguir

HanPasado500mseg_

sBanco1

decfsz B1_SetPoint_500mseg,F

goto HanPasado1000mseg_

;RUTINA de lo que hacemos cada 500 mseg

;Recargamos el valor del set point de 500 mseg.

movlw .50

movwf B1_SetPoint_500mseg

;Esto es lo que hacemos cada 500mseg.

sBanco0

btfss B0_Pre_SD_0_5s

goto Pre_SD000_5_es_cero

goto Pre_SD000_5_es_uno

Pre_SD000_5_es_cero

bsf B0_Pre_SD_0_5s

goto Pre_SD000_5_seguir

Pre_SD000_5_es_uno

bcf B0_Pre_SD_0_5s

Pre_SD000_5_seguir
HanPasado1000mseg_

sBanco0

decfsz TIMER_1S_H,F

goto salir_inter_TMR1

;RUTINA de lo que hacemos cada 1000 mseg

sBanco1

incf B1_BT_1000,f ;Base de tiempos para los timers de 1000 mseg

sBanco0

;Recargamos el valor del set point de 1000 mseg.

movlw .100

movwf TIMER_1S_H

;Esto es lo que hacemos cada 1000mseg.

btfss B0_Pre_SD_1s

goto Pre_SD000_4_es_cero

goto Pre_SD000_4_es_uno

Pre_SD000_4_es_cero

bsf B0_Pre_SD_1s

goto Pre_SD000_4_seguir

Pre_SD000_4_es_uno

bcf B0_Pre_SD_1s

Pre_SD000_4_seguir

salir_inter_TMR1

salir_inter

restaurar_W_STATUS

retfie
;+++++++++++++++++++++++++++++++++++++++INICIALIZACION_PIC+++++++++++++++++++++++++++++
++++++

;++++++++++++++++++++++++++INICIALIZACION_PIC+++++++INICIALIZACION_PIC+++++++++++++++++++
++++

;+++++++++++++++++++++++INICIALIZACION_PIC++INICIALIZACION_PIC+++++++++++++++++++++++++++
++++

;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++INICIALIZACION_PIC+++++
++++++

;++++++++++++++++++++++++++++++++++++++++++++INICIALIZACION_PIC++++++++++++++++++++++++
++++++

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++INICIALIZACION_PIC++++++++++++
++++++

;++++++INICIALIZACION_PIC+++INICIALIZACION_PIC+++++++++++++++++++++++INICIALIZACION_PIC+++
+++

Inicio

clrf STATUS

clrf INTCON ;Con esto inhabilitamos interrupciones globalmente

clrf PIR1

bsf B0_Pre_SD_1s

bsf B0_Pre_SD_0_5s

bsf B0_Pre_SD_0_1s

sBanco1

clrf PIE1

clrf PIE2

bsf OPTION_REG,7 ;Inhabilitamos las pull-ups del PORTB

;Registro CMCON (Comparadores) Para que funcione el PIC16F876A

bsf CMCON,CM2 ;Inhabilitamos todos los comparadores


bsf CMCON,CM1

bsf CMCON,CM0

clrf B1_BT_1 ;Base de tiempos para los timers de 1 mseg

clrf B1_BT_10 ;Base de tiempos para los timers de 10 mseg

clrf B1_BT_100 ;Base de tiempos para los timers de 100 mseg

clrf B1_BT_1000 ;Base de tiempos para los timers de 1000 mseg

;Inicialización de zona de RAM

sBanco0

movlw b'10000000' ;Configuramos el AD dejandolo inactivo

movwf ADCON0

;bcf bTodasADLeidas

clrf AI_YaRealizada1Vez

;A 0 indicamos que no hemos realizado ninguna


lectura A/D

clrf AI_EntradaAnalogLeida

;La ultima Analog Input leida es la 0 (Es decir


ninguna)

;clrf TIMER_1S_L

;clrf TIMER_1S_H

clrf 0x23

clrf 0x27 ;Aqui vamos a poner cuantas instrucciones seguidas se han

;ejecutado de U/UN compiladas para luego


poder realizar el

;salto correctamente.

bcf Bx_SD_2RUN
;bcf Bx_SD_1s

;bcf Bx_SD_0_5s

;bcf Bx_SD_0_1s

bsf Bx_SD_1s

bsf Bx_SD_0_5s

bsf Bx_SD_0_1s

bcf Bx_SD_CF

bcf Bx_SD_OFF

bsf Bx_SD_ON

bsf Bx_SD_1CYCLE

bsf Bx_SD_2RUN

bcf Bx_SD_MUL_OVF

bcf Bx_SD_EQ

bcf Bx_SD_NEQ

bcf Bx_SD_GE

bcf Bx_SD_GT

bcf Bx_SD_LE

bcf Bx_SD_LT

bcf Bx_SD_DIV_BY0

;bsf B0_Pre_SD_EE_FREE

bsf Bx_SD_EE_FREE

;bcf B0_Pre_SD_EE_WROK

bcf Bx_EE_EnMarcha
bcf Bx_SD_EE_WROK

;bcf B0_Pre_SD_EE_WRER

bcf Bx_SD_EE_WRER

bcf Bx_SD_EE_RDOK

;Posición inicial de colocación de seudo-código ladder en FLASH.

movlw ByteAltoBeginLADDER

movwf PCaPIC_FLASH_H

movlw ByteBajoBeginLADDER

movwf PCaPIC_FLASH_L

;Vamos a inicializar la zona de RAM

;***************************************************************************

;* Utilizamos un bucle con direccionamiento indirecto para borrar el

;* contenido de la zona de memoria

;***************************************************************************

bcf STATUS,IRP ;Selecciona el banco en direccionamiento indirecto

sBanco0

movlw TIMER_1S_L ;Empezamos en la posición 0x20

movwf FSR

buclecillo

clrf INDF

incf FSR,F ;Incrementamos FSR

;Comprobamos si hemos llegado a 0x47

movlw 0x47

subwf FSR,W ;Le restamos FSR y lo dejamos en W


btfss STATUS,Z ;Comprobamos si es cero la resta

goto buclecillo ;Todavia no es 0x29

; ;Vamos a limpiar la zona RAM de RD.

; bsf STATUS,IRP ;Direccionamiento indirecto Bancos 2-3

; movlw RD000

; movwf FSR

;LimpiezaZonaRD

; clrf INDF

; incf FSR,F ;Incrementamos FSR

; movlw RD095

; addlw .1

; subwf FSR,W ;Le restamos FSR y lo dejamos en W

; btfss STATUS,Z ;Comprobamos si es cero la resta

; goto LimpiezaZonaRD ;Todavia no es 0x29

; bcf STATUS,IRP

;Vamos a limpiar la zona de timers.

bsf STATUS,IRP ;Direccionamiento indirecto Bancos 2-3

movlw RD000

iorlw 0x80

movwf FSR

LimpiezaZonaTimer

clrf INDF

incf FSR,F ;Incrementamos FSR


movlw RD095

addlw .1

iorlw 0x80

subwf FSR,W ;Le restamos FSR y lo dejamos en W

btfss STATUS,Z ;Comprobamos si es cero la resta

goto LimpiezaZonaTimer

bcf STATUS,IRP

;Vamos a limpiar el Banco1.

bcf STATUS,IRP ;Direccionamiento indirecto Bancos 0-1

movlw 0x20

iorlw 0x80

movwf FSR

LimpiezaZonaBanco1

clrf INDF

incf FSR,F ;Incrementamos FSR

movlw 0x6F

addlw .1

iorlw 0x80

subwf FSR,W ;Le restamos FSR y lo dejamos en W

btfss STATUS,Z ;Comprobamos si es cero la resta

goto LimpiezaZonaBanco1

bcf STATUS,IRP

pPagina3

call Pg3_LimpiarZonaLCD

pPagina0
;****************************************************************************

;* Fin del bucle con direccionamiento indirecto

;****************************************************************************

;INICIALIZACION DEL I2C

;*Hay que configurar las patas SCL y SDA como entradas, nosotros configuramos

;todas las del puerto C como entradas aquí.

;sBanco1

;movlw b'10000000'

;movwf SSPSTAT ;Velocidad estándar con niveles I2C

;movlw .9

;movwf SSPADD ;Velocidad del bus I2C 100KHz

;sBanco0

;Módulo MSSP en el modo Master I2C

;El bit 5 habilita el I2C y el 3 activado con los 2,1,0 desactivados hace que

;la velocidad del I2C la ponga el registro SSPADD

;movlw b'00101000'

;movwf SSPCON ;Módulo MSSP en On

sBanco0

clrf SSPCON ;Módulo MSSP en Off

;FIN INICIALIZACION I2C

;Introducimos la direccion del pic

;movlw 0x0B

;movwf RX_232_DIRH

;movlw 0x0B
;movwf RX_232_DIRL

clrf RX_232_DIRH

clrf RX_232_DIRL

clrf PORTA

clrf PORTC

clrf PORTB

;Cargamos en la posicion ram 0x20 el valor 250 en decimal

movlw .10 ;0xFA ;0xFA es decimal 250

movwf TIMER_1S_L

;Cargamos en la posicion ram TIMER_1S_H el valor 4 en decimal

movlw .100 ;0x04

movwf TIMER_1S_H

sBanco1

movlw .50

movwf B1_SetPoint_500mseg

movlw .10

movwf B1_SetPoint_100mseg

movlw b'10001110'

movwf ADCON1 ;Puerta A la RA0 como analógica, resto digitales

clrf PORTB ;Puerta B salida

movlw b'00011111'

movwf TRISA ;Puerta A como entrada

movlw b'10111111'
movwf TRISC ;RC7/Rx entrada, RC6/Tx salida,todo los demas entradas

movlw b'01000000' ;Inhabilitamos las interrupciones del TMR0

movwf INTCON ;El unico que habilitamos es el PEIE

movlw b'00100100'

movwf TXSTA ;TX en On, modo asíncrono con 8 bits y alta velocidad

movlw .25 ;9600 baudios con Fosc=4MHz

;movlw .129 ;9600 baudios con Fosc=20MHz

movwf SPBRG

bsf PIE1,RCIE ;Habilita interrupción en la recepción por la USART

bcf PIE1,TXIE ;Inhabilita interrupción en la transmision por la USART

movlw 0x34

movwf 0x20

movlw 0x21

movwf 0x21

sBanco0

movlw b'10010000'

movwf RCSTA ;USART en On, recepción contínua

movlw 0xFF ;Recargamos el valor del Timer1 a 4 MHZ

movwf TMR1H

movlw 0x86

movwf TMR1L

;movlw 0xFD ;Recargamos el valor del Timer1 a 20 MHZ

;movwf TMR1H
;movlw 0xA2

;movwf TMR1L

bcf PIR1,TMR1IF ;Borramos el flag del Timer1

movlw b'00110001' ;Habilitamos el Timer 1 con preescaler 8

movwf T1CON

sBanco1

bsf PIE1,TMR1IE ;Habilitamos las interrupciones del Timer 1

bsf INTCON,GIE ;Habilitamos interrupciones globalmente.

sBanco0

bsf B0_bPLConRUN;Bit de CPU en RUN.

;Cogemos de Flash la configuración de Entradas/Salidas

call CogeConfigIO_DeFLASH_ARAM

pPagina2

call Pg2_LimpiarTimers

pPagina0

sBanco3

btfss bConfigLCD ;A 1 tenemos configurado el LCD

goto IniLCD_End

sBanco1

bsf B1_bEnviarIniLCD ;Arrancamos la inicialización

IniLCD_End
;++++++++++++++++++++++++++++++++++++++BUCLE_INFINITO+++++++++++++++++++++++++++++++++
+++

;+++++++++++++++++++++++++BUCLE_INFINITO++++++++++++++++++BUCLE_INFINITO++++++++++++++
+++

;++++++++++++++++++++++BUCLE_INFINITO+++BUCLE_INFINITO++++++++++++++++++++++++++++++++
+++

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++BUCLE_INFINITO+++++++++
+++

;+++++++++++++++++++++++++++++++++++++++++++BUCLE_INFINITO++++++++++++++++++++++++++++
+++

;+++++++++++++++++++++++++++++++++++++++++++++++++++++++BUCLE_INFINITO++++++++++++++++
+++

;+++++BUCLE_INFINITO+++++BUCLE_INFINITO+++++++++++++++++++++++++++++BUCLE_INFINITO+++++
++

m_b_0

;Por aqui pasa este en RUN o STOP siempre

call Pg0_EEPROM

call Pg0_ActualizaTimers

sBanco3

btfss bConfigLCD ;A 1 tenemos configurado el LCD

goto NoInicializa_LCD_

bsf PCLATH,3

call Inicializa_LCD_ ;El subrayado al final es pregunta

bcf PCLATH,3

;NoInicializa_LCD_

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

sBanco1

;Si estamos esperando respuesta del LCD al BusyFlag

btfss B1_bEsperandoBusyFlag

goto LCD_noEsperaBusyFlag

;Estamos esperando respuesta del busy flag, pero antes vamos a asegurarnos de que

;el comando esta bien pedido

sBanco0

btfss B0_LCD_E

goto LCD_noEsperaBusyFlag

btfsc B0_LCD_RS

goto LCD_noEsperaBusyFlag

btfss B0_LCD_RW

goto LCD_noEsperaBusyFlag

btfss PORTB,7

goto LCD_EsperaBusyFlag0

goto LCD_noEsperaBusyFlag

LCD_EsperaBusyFlag0

sBanco0

bcf B0_LCD_E ;Quitamos el enable

sBanco1

bcf B1_bEsperandoBusyFlag

bsf PCLATH,3
;bsf Bx_BEnviarSigCARACTER

call EnviarSiguienteA_LCD

bcf PCLATH,3

LCD_noEsperaBusyFlag

NoInicializa_LCD_

; btfss Bx_BEnviarSigCARACTER

; goto m_b_0_NoEnviarSigCaracterALCD

; bsf PCLATH,3

; call EnviarSiguienteA_LCD

; bcf PCLATH,3

; ;bcf Bx_BEnviarSigCARACTER

;m_b_0_NoEnviarSigCaracterALCD

sBanco0

bsf Bx_SD_0_1s

btfss B0_Pre_SD_0_1s

bcf Bx_SD_0_1s

bsf Bx_SD_0_5s

btfss B0_Pre_SD_0_5s

bcf Bx_SD_0_5s

bsf Bx_SD_1s

btfss B0_Pre_SD_1s
bcf Bx_SD_1s

;sBanco0

bsf PCLATH,3

call Pg1_EntradasSalidas

bcf PCLATH,3

sBanco0

bcf bRunPrimitSO ;Anulamos la ejecución de la proxima primitiva del S.O.

btfsc B0_bPLConRUN;Bit de CPU en RUN.

goto m_b_0_RUN

goto m_ml_9999 ;m_ml_9999: Evaluamos la trama recibida desde USART.

m_b_0_RUN

;Por aqui pasa solo cuando esta en RUN

sBanco0

pPagina3

call Pg3_ProgramaLadder

pPagina0

sBanco0

;Tenemos que evaluar el codigo devuelto por el ProgramaLadder.

;Cuando es 0x7F es la terminacion normal

;Cuando es 0x01 es la funcion END

;Cuando es 0x02 es la funcion STOP

sublw 0x02
btfss STATUS,Z

goto m_b_0_NoPonerASTOP

pPagina3

call Pg3_PonerCPUaSTOP

pPagina0

sBanco0

;;Ponemos en STOP

;sBanco3

;clrf B3_ByteIO_P1_p8

;clrf B3_ByteIO_P9_p16

;clrf B3_ByteIO_P17_p24

;clrf B3_ByteIO_P25_p32

;clrf B3_ByteIO_P33_p40

;bsf PCLATH,3

;call Pg1_EntradasSalidas

;bcf PCLATH,3

;sBanco0

;bcf B0_bPLConRUN;Bit de CPU en RUN.

m_b_0_NoPonerASTOP

bcf Bx_SD_1CYCLE ;Primer ciclo de scan

bcf Bx_SD_2RUN

bcf Bx_SD_EE_WROK

bcf Bx_SD_EE_WRER

m_ml_9999

;****************************************************************************
;* Comprobamos si la trama recibida tiene el formato y el checksum validos.

;****************************************************************************

btfss 0x23,0

goto m_b_1

goto m_b_2

m_b_1

btfss 0x23,3

goto m_b_0

goto m_b_13

m_b_2

btfss 0x23,2

goto m_b_3

goto m_b_1

m_b_3

movf RX_232_BYTESenTRAMA,W

;Comparamos si el contenido de 0x24 es mayor o


igual que 4

movwf LOCAL_0

movlw .4

movwf LOCAL_1

call byte_mayorigual_que

btfss LOCAL_1,0

goto m_b_4 ;No

goto m_b_5 ;Sí

m_b_4
bcf 0x23,0

goto m_b_11

m_b_5

;****************************************************************************

;* Hacemos la comprobacion de la longitud de datos variables recibidos.

;****************************************************************************

movlw 0x05

subwf RX_232_BYTESenTRAMA,W

;Restamos 5 a los bytes que tiene la trama


(Menos SOT y EOT)

subwf BUFFER_RX_3,W ;Le restamos el campo de la trama recibida de longitud de datos

btfss STATUS,Z ;Comprobamos si la resta es cero.

;Si la resta es 0 => Z==1

goto m_b_4 ;No

goto m_b_6 ;Sí

m_b_6

;CALCULAMOS CHECKSUM

;****************************************************************************

;* Utilizamos un bucle con direccionamiento indirecto para calcular el

;* checksum de la trama recibida, lo almacenamos en LOCAL_0

;* Usamos como variable temporal LOCAL_1

;****************************************************************************

sBanco0

movlw 0xC9 ;Le sumamos SOT (Que es el caracter 0xC9=201)

movwf LOCAL_0 ;En LOCAL_0 vamos a tener el checksum calculado

clrf LOCAL_1 ;En LOCAL_1 vamos a tener la posición del ultimo


caracter recibido
;mas 1 para poder parar el bucle de
direccionamiento indirecto

movf LOCAL_1,W

addlw BUFFER_RX_MENOS_1

;Es la dirección de BufferRecepcion[-1]

addwf RX_232_BYTESenTRAMA,W

;Le sumamos el byte "Bytes en trama"

movwf LOCAL_1

bcf STATUS,IRP ;Selecciona el banco 0 en direccionamiento indirecto

movlw BUFFER_RX_0 ;Empezamos en la posición 0x2A

movwf FSR

bucle_m_b_6

movf LOCAL_0,W ;Cargamos el total en el acumulador

addwf INDF,W

movwf LOCAL_0

incf FSR,F ;Incrementamos FSR

;Comprobamos si hemos llegado a 0x3F

movf LOCAL_1,W

subwf FSR,W ;Le restamos FSR y lo dejamos en W

btfss STATUS,Z ;Comprobamos si es cero la resta

goto bucle_m_b_6 ;Todavia no

;Ya hemos terminado de calcular el Checksum, lo


tenemos

;en LOCAL_0

;YA TENEMOS EL CHECKSUM EN LOCAL_0

;El nuevo checksum es el calculado modulo 201


movlw .200 ;0xC8 ;0xC8=200

movwf LOCAL_1

call byte_mayor_que

btfss LOCAL_1,0

goto m_b_6_No_es_mayor_que_200

goto m_b_6_Si_es_mayor_que_200

m_b_6_Si_es_mayor_que_200

movlw .201 ;0xC9

subwf LOCAL_0,F

goto m_b_6_seguir

m_b_6_No_es_mayor_que_200

movf LOCAL_0,W

m_b_6_seguir

;*****************************************************************************

;* Fin del bucle con direccionamiento indirecto

;*****************************************************************************

;Vamos a poner en LOCAL_1 la direccion de donde esta el checksum que venia con la trama

bcf STATUS,IRP ;Selecciona el banco 0 en direccionamiento indirecto

sBanco0

movlw BUFFER_RX_MENOS_1

;Empezamos en la posición 0x2A

addwf RX_232_BYTESenTRAMA,W

;Le sumamos el byte "bytes en trama"

movwf FSR

movf INDF,W
movwf LOCAL_1 ;Ya tenemos en LOCAL_1 el checksum que venia con la
trama

movf LOCAL_1,W

subwf LOCAL_0,W ;Le restamos FSR y lo dejamos en W

btfss STATUS,Z ;Comprobamos si es cero la resta

goto m_b_4 ;No coinciden los checksum

goto m_b_8

;;Los Checksum coinciden. vamos a ver si la trama iba dirigida a nosotros.

m_b_8

sBanco0

movf RX_232_DIRH,W ;Direccion dirH del PIC

subwf BUFFER_RX_0,W ;Comprobamos si dirH coinciden

btfss STATUS,Z ;Comprobamos si es cero la resta

goto m_b_4 ;No

movf RX_232_DIRL,W ;Comprobamos si dirL coinciden

subwf BUFFER_RX_1,W

btfss STATUS,Z ;Comprobamos si es cero la resta

goto m_b_4 ;No

goto m_b_10 ;Ambas coinciden

m_b_10

bsf 0x23,3

goto m_b_11

m_b_11

bsf 0x23,2
goto m_b_1

m_b_13

sBanco0

movlw 0x0A ;Esto hay que quitarlo. es la respuesta al comando 0x0A

subwf BUFFER_RX_2,W

btfss STATUS,Z

goto m_b_47

; goto m_b_16

m_b_16

bcf 0x23,3

bcf 0x23,0

goto m_b_0

;
*************************************************************************************
*****

;* Hacemos las comparaciones para saber cual es el comando recibido por USART

;
*************************************************************************************
*****

m_b_47

;movlw 0x1D ;Es el comando 0x1D: Begin Transferencia PC->PLC ??

movlw .5 ;Es el comando 5: Begin Transferencia PC->PLC ??

subwf BUFFER_RX_2,W

btfsc STATUS,Z

goto m_b_50 ;Vamos al codigo del comando


m_b_49

;movlw 0x1E ;Es el comando 0x1E: Begin Bloque ON-LINE ??

movlw .6 ;Es el comando 6: Begin Bloque ON-LINE ??

subwf BUFFER_RX_2,W

btfsc STATUS,Z

;goto m_b_51 ;Vamos a la siguiente comparacion

goto m_b_52 ;Vamos al codigo del comando

m_b_51

;movlw 0x1F ;Es el comando 0x1F: Línea en bloque ON-LINE ??

movlw .7 ;Es el comando 7: Línea en bloque ON-LINE ??

subwf BUFFER_RX_2,W

btfsc STATUS,Z

;goto m_b_53 ;Vamos a la siguiente comparacion

goto m_b_54 ;Vamos al codigo del comando

m_b_53

;movlw 0x20 ;Es el comando 0x20: End Bloque ON-LINE ??

movlw .8 ;Es el comando 8: End Bloque ON-LINE ??

subwf BUFFER_RX_2,W

btfsc STATUS,Z

;goto m_b_55 ;Vamos a la siguiente comparacion

goto m_b_56 ;Vamos al codigo del comando

m_b_55

;movlw 0x21 ;Es el comando 0x21: End Transferencia PC->PLC ??

movlw .9 ;Es el comando 9: End Transferencia PC->PLC ??

subwf BUFFER_RX_2,W

btfsc STATUS,Z
;goto m_b_57 ;Vamos a la siguiente comparacion

goto m_b_58 ;Vamos al codigo del comando

m_b_57

;movlw .34 ;Es el comando .34: Monitorización de bits??

movlw .17 ;Es el comando .17: Monitorización de bits??

subwf BUFFER_RX_2,W

btfsc STATUS,Z

;goto m_b_59 ;Vamos a la siguiente comparacion

goto m_b_60 ;Vamos al codigo del comando

;m_b_59

; movlw .35 ;Es el comando .35: Debugger 1 instrucción ??

; subwf BUFFER_RX_2,W

; btfsc STATUS,Z

; ;goto m_b_61 ;Vamos a la siguiente comparacion

; goto m_b_62 ;Vamos al codigo del comando

m_b_61

;movlw .36 ;Es el comando .36: Forzado ??

movlw .12 ;Es el comando .12: Forzado ??

subwf BUFFER_RX_2,W

btfsc STATUS,Z

;goto m_b_63 ;Vamos a la siguiente comparacion

goto m_b_64 ;Vamos al codigo del comando

m_b_63

;movlw .37 ;Es el comando .37: Poner CPU a START ??

movlw .13 ;Es el comando .13: Poner CPU a START ??


subwf BUFFER_RX_2,W

btfsc STATUS,Z

;goto m_b_65 ;Vamos a la siguiente comparacion

goto m_b_66 ;Vamos al codigo del comando

m_b_65

;movlw .38 ;Es el comando .38: poner CPU a STOP ??

movlw .14 ;Es el comando .14: poner CPU a STOP ??

subwf BUFFER_RX_2,W

btfsc STATUS,Z

;goto m_b_67

goto m_b_68 ;Vamos al codigo del comando

m_b_67

movlw .11 ;Es el comando .11: Ping-Pong

subwf BUFFER_RX_2,W

btfsc STATUS,Z

;goto m_b_69

goto m_b_70 ;Vamos al codigo del comando

;m_b_69

; movlw .12 ;Es el comando .12: Nos pide el contenido de una


posicion FLASH

; subwf BUFFER_RX_2,W

; btfss STATUS,Z

; goto m_b_71

; goto m_b_72 ;Vamos al codigo del comando

m_b_71
;movlw .39 ;Es el comando .39: Nos pide el contenido de una
posicion RAM

movlw .15 ;Es el comando .15: Nos pide el contenido de una


posicion RAM

subwf BUFFER_RX_2,W

btfsc STATUS,Z

;goto m_b_73

goto m_b_74 ;Vamos al codigo del comando

m_b_73

movlw .16 ;Es el comando .16: Monitorizacion a nivel de byte.

subwf BUFFER_RX_2,W

btfsc STATUS,Z

goto m_b_76 ;Vamos al codigo del comando

m_b_75

movlw .1 ;Es el comando .1: Lectura del programa Ladder.

subwf BUFFER_RX_2,W

btfsc STATUS,Z

goto m_b_78 ;Vamos al codigo del comando

m_b_77

movlw .2 ;Es el comando .2: Lectura de la configuración de I/O de


FLASH

subwf BUFFER_RX_2,W

btfsc STATUS,Z

goto m_b_80 ;Vamos al codigo del comando

m_b_79
movlw .3 ;Es el comando .3: Escritura de la configuración de I/O en
FLASH

subwf BUFFER_RX_2,W

btfsc STATUS,Z

goto m_b_82 ;Vamos al codigo del comando

m_b_81

movlw .4 ;Es el comando .4: Monitorizacion de todos los valores


de E/S

subwf BUFFER_RX_2,W

btfsc STATUS,Z

goto m_b_84 ;Vamos al codigo del comando

movlw .18 ;Es el comando .18:

subwf BUFFER_RX_2,W

btfsc STATUS,Z

goto WriteFD ;Vamos al codigo del comando

movlw .19 ;Es el comando .19

subwf BUFFER_RX_2,W

btfsc STATUS,Z

goto WriteED ;Vamos al codigo del comando

movlw .20 ;Es el comando .20

subwf BUFFER_RX_2,W

btfsc STATUS,Z

goto ReadED ;Vamos al codigo del comando

m_b_NO_SE_HA_RECIBIDO_NINGUN_COMANDO_VALIDO
goto m_b_16

;
*************************************************************************************
*****

;* Hemos recibido por USART el comando .5: Begin Transferencia PC->PLC

;
*************************************************************************************
*****

m_b_50

pPagina3

call Pg3_PonerCPUaSTOP

pPagina0

sBanco0

;;Ponemos en STOP

;sBanco3

;clrf B3_ByteIO_P1_p8

;clrf B3_ByteIO_P9_p16

;clrf B3_ByteIO_P17_p24

;clrf B3_ByteIO_P25_p32

;clrf B3_ByteIO_P33_p40

;bsf PCLATH,3

;call Pg1_EntradasSalidas

;bcf PCLATH,3

;sBanco0

;IMPORTANTE: Ponemos la CPU en STOP.


;bcf B0_bPLConRUN

pPagina2

call Pg2_LimpiarTimers

pPagina0

;Posición inicial de colocación de pseudo-código ladder en FLASH.

movlw ByteAltoBeginLADDER

movwf PCaPIC_FLASH_H

movlw ByteBajoBeginLADDER

movwf PCaPIC_FLASH_L

movlw .4

movwf 0x6E ;Registro para realizar la grabación en FLASH

;GRABAMOS EN FLASH

bsf STATUS,RP0 ;Banco 1

clrf GF_CONTADOR_UP

movlw .4

movwf GF_CONTADOR_DOWN

bcf STATUS,RP0 ;Banco 0

movlw 0x00

movwf LOCAL_0

movlw 0x00

movwf LOCAL_1

call Mandar14Bits_A_BufferFLASH
clrf BUFFER_RX_3 ;Tamaño de datos : 0

movlw .5 ;Cargamos el comando .5

movwf BUFFER_RX_2

call mandar_trama_a_maestro

goto m_b_16

;******************************************************************************
**

;* Hemos recibido por USART el comando .6: Begin Bloque ON-LINE

;******************************************************************************
**

m_b_52

sBanco0

;Instruccion 'movlw 0x01'

movlw 0x30

movwf LOCAL_0

movlw 0x01

movwf LOCAL_1

call Mandar14Bits_A_BufferFLASH

;Instruccion 'PILA_LOGICA'

movlw 0x00

movwf LOCAL_0

movlw 0xF8

movwf LOCAL_1

call Mandar14Bits_A_BufferFLASH

;Instruccion 'PILA_LOGICA_NIVEL'
movlw 0x00

movwf LOCAL_0

movlw 0xF9

movwf LOCAL_1

call Mandar14Bits_A_BufferFLASH

movlw .6 ;Cargamos el comando .6

movwf BUFFER_RX_2

clrf BUFFER_RX_3 ;Tamaño de datos.

call mandar_trama_a_maestro

goto m_b_16

;
*************************************************************************************
***

;* Hemos recibido por USART el comando .18: WriteFD

;
*************************************************************************************
***

WriteFD

sBanco0

movf BUFFER_RX_3,W ;Tamaño de datos

btfsc STATUS,Z ;Si es cero salimos

goto WriteFD_end

;Posición inicial de colocación de Flash Data

movlw 0x17

movwf PCaPIC_FLASH_H

movlw 0x30
addwf 0x2E,W ;En la trama nos dice a partir de que FD escribimos.

movwf PCaPIC_FLASH_L

;Inicializamos la Grabación en FLASH

bsf STATUS,RP0 ;Banco 1

clrf GF_CONTADOR_UP

movlw .4

movwf GF_CONTADOR_DOWN

;Como vamos a grabar solo 20 posiciones vamos a grabar una vacía

bcf STATUS,RP0 ;Banco 0

;movlw 0x00

;movwf LOCAL_0

;movlw 0x00

;movwf LOCAL_1

;call Mandar14Bits_A_BufferFLASH

;movlw 0x2E

movlw 0x2F

movwf FSR

bcf STATUS,IRP ;Selecciona el banco 0 en direccionamiento indirecto

movlw .20 ;Ejecutamos el bucle 20 veces.

movwf LOCAL_3

WriteFD_main

; movf INDF,W

sBanco0
movlw 0x34

movwf LOCAL_0

swapf INDF,W

movwf LOCAL_1

incf FSR,F

movf INDF,W

andlw 0x0F

iorwf LOCAL_1,F

;GRABAMOS EN FLASH

;Guardamos FSR

movf FSR,W

movwf LOCAL_2

call Mandar14Bits_A_BufferFLASH

;Restauramos FSR

movf LOCAL_2,W

movwf FSR

bcf STATUS,IRP

incf FSR,F

decfsz LOCAL_3

goto WriteFD_main

WriteFD_end

;Mandamos el ACK de Linea Bloque ON-LINE

clrf BUFFER_RX_3 ;Tamaño de datos : 0


movlw .18 ;Cargamos el comando .18

movwf BUFFER_RX_2

call mandar_trama_a_maestro

;;call CogeConfigIO_DeFLASH_ARAM

goto m_b_16

;
*************************************************************************************
***

;* Hemos recibido por USART el comando .19: WriteED

;
*************************************************************************************
***

WriteED

;??

;Primero ponemos el micro en STOP

pPagina3

call Pg3_PonerCPUaSTOP

call Pg3_WriteED

pPagina0

goto m_b_16

;
*************************************************************************************
***

;* Hemos recibido por USART el comando .20: ReadED

;
*************************************************************************************
***

ReadED

pPagina3
call Pg3_ReadED

pPagina0

goto m_b_16

;
*************************************************************************************
***

;* Hemos recibido por USART el comando .3: Escritura de la configuración de I/O en FLASH

;
*************************************************************************************
***

m_b_82

sBanco0

movf BUFFER_RX_3,W ;Tamaño de datos

btfsc STATUS,Z ;Si es cero salimos

goto m_b_82_end

; ;Posición inicial de colocación de pseudo-código ladder en FLASH.

; movlw 0x0E

; movwf PCaPIC_FLASH_H

; movlw 0xF8

; movwf PCaPIC_FLASH_L

;Posición inicial de colocación de pseudo-código ladder en FLASH.

movlw 0x17

movwf PCaPIC_FLASH_H

movlw 0xF8

movwf PCaPIC_FLASH_L

;Inicializamos la Grabación en FLASH


bsf STATUS,RP0 ;Banco 1

clrf GF_CONTADOR_UP

movlw .4

movwf GF_CONTADOR_DOWN

;Como vamos a grabar solo 7 posiciones vamos a grabar una vacía

bcf STATUS,RP0 ;Banco 0

movlw 0x00

movwf LOCAL_0

movlw 0x00

movwf LOCAL_1

call Mandar14Bits_A_BufferFLASH

movlw 0x2E

movwf FSR

bcf STATUS,IRP ;Selecciona el banco 0 en direccionamiento indirecto

movlw .7 ;Ejecutamos el bucle 7 veces.

movwf LOCAL_3

m_b_82_main

; movf INDF,W

sBanco0

movlw 0x34

movwf LOCAL_0

swapf INDF,W

movwf LOCAL_1
incf FSR,F

movf INDF,W

andlw 0x0F

iorwf LOCAL_1,F

;GRABAMOS EN FLASH

;Guardamos FSR

movf FSR,W

movwf LOCAL_2

call Mandar14Bits_A_BufferFLASH

;Restauramos FSR

movf LOCAL_2,W

movwf FSR

bcf STATUS,IRP

incf FSR,F

decfsz LOCAL_3

goto m_b_82_main

m_b_82_end

;Mandamos el ACK de Linea Bloque ON-LINE

clrf BUFFER_RX_3 ;Tamaño de datos : 0

movlw .3 ;Cargamos el comando .3

movwf BUFFER_RX_2

call mandar_trama_a_maestro

call CogeConfigIO_DeFLASH_ARAM

goto m_b_16
;
*************************************************************************************
*****

;* Hemos recibido por USART el comando .7: Línea en bloque ON-LINE

;
*************************************************************************************
*****

m_b_54

;****************************************************************************

;* Utilizamos un bucle con direccionamiento indirecto

;****************************************************************************

sBanco0

movf BUFFER_RX_3,W

btfsc STATUS,Z ;Si es cero salimos

goto m_b_54_end

movlw 0x2E

movwf FSR

bcf STATUS,IRP ;Selecciona el banco 0 en direccionamiento indirecto

;El primer byte recibido es la secuencia de las tramas tenemos que comprobar

;que es el que sigue.

incf FSR,F

decf BUFFER_RX_3,F

btfsc STATUS,Z ;Si es cero salimos

goto m_b_54_end
m_b_54_main

movf INDF,W

;****************************************************************************

;* Aqui ponemos lo que queremos hacer con los nibble que recibimos

;* El nibble recibido lo tenemos en W.

;****************************************************************************

movwf LOCAL_0

rlf LOCAL_0,F

rlf LOCAL_0,F

rlf LOCAL_0,F

rlf LOCAL_0,F

rlf LOCAL_0,F

rlf LOCAL_7,F

rlf LOCAL_6,F

rlf LOCAL_0,F

rlf LOCAL_7,F

rlf LOCAL_6,F

rlf LOCAL_0,F

rlf LOCAL_7,F

rlf LOCAL_6,F

rlf LOCAL_0,F

rlf LOCAL_7,F
rlf LOCAL_6,F

decfsz 0x6E,F

goto m_b_54_FIN_Nibbles

;****************************************************************************

;* Aqui ponemos lo que queremos hacer con el doble byte recibido

;* Lo tenemos en B0:LOCAL_6,LOCAL_7

;****************************************************************************

;GRABAMOS EN FLASH

;Guardamos FSR

movf FSR,W

movwf LOCAL_2

; bcf STATUS,RP0 ;Banco 0

sBanco0

movf LOCAL_6,W

movwf LOCAL_0

movf LOCAL_7,W

movwf LOCAL_1

call Mandar14Bits_A_BufferFLASH

;Restauramos FSR

movf LOCAL_2,W

movwf FSR

bcf STATUS,IRP
movlw .4

movwf 0x6E

;******* FIN DE LO QUE QUEREMOS HACER CON EL BYTE ***************************

m_b_54_FIN_Nibbles

incf FSR,F

decfsz BUFFER_RX_3,F

goto m_b_54_main

goto m_b_54_end

m_b_54_end

;Mandamos el ACK de Linea Bloque ON-LINE

clrf BUFFER_RX_3 ;Tamaño de datos : 0

movlw .7 ;Cargamos el comando .7

movwf BUFFER_RX_2

call mandar_trama_a_maestro

goto m_b_16

;
*************************************************************************************
*****

;* Hemos recibido por USART el comando .8: End Bloque ON-LINE

;
*************************************************************************************
*****

m_b_56 ;Mandamos el ACK de End Bloque ON-LINE

sBanco0

clrf BUFFER_RX_3 ;Tamaño de datos : 0


movlw .8 ;Cargamos el comando .8

movwf BUFFER_RX_2

call mandar_trama_a_maestro

goto m_b_16

;
*************************************************************************************
*****

;* Hemos recibido por USART el comando .9: End Transferencia PC->PLC

;
*************************************************************************************
*****

m_b_58

sBanco0

movlw 0x34

movwf LOCAL_0

movlw 0x7F

movwf LOCAL_1

call Mandar14Bits_A_BufferFLASH_Y_ForzarEscritura

clrf BUFFER_RX_3 ;Tamaño de datos : 0

movlw .9 ;Cargamos el comando .9

movwf BUFFER_RX_2

call mandar_trama_a_maestro

goto m_b_16

;
*************************************************************************************
*****
;* Hemos recibido por USART el comando .17: Monitorización de bits

;
*************************************************************************************
*****

m_b_60

sBanco0

movf 0x2E,W ;En 0x2E tenemos el numero de operandos a monitorizar

btfsc STATUS,Z

goto m_b_60_Fin

bcf STATUS,IRP ;Selecciona el banco 0-1 en direccionamiento indirecto

movlw 0x2F ;En 0x2F tenemos el primer byte.

movwf FSR

m_b_60_bucle

movf INDF,W

movwf LOCAL_2

incf FSR,F

movf INDF,W

swapf INDF,W

andlw 0xF0

movwf LOCAL_3

incf FSR,F

movf INDF,W

andlw 0x0F
iorwf LOCAL_3,F

;En LOCAL_3 Tenemos el byte del booleano, tenemos que comprobar si es RD250,RD251 para

;pasarlo a SD000,SD001

;Tambien puede ser RD252.

movlw .250

subwf LOCAL_3,W

btfsc STATUS,Z

;goto m_b_60_Sera_SD001 ;Vamos a la siguiente comparacion

goto m_b_60_Es_SD000

;m_b_60_Sera_SD001

movlw .251

subwf LOCAL_3,W

btfsc STATUS,Z

;goto m_b_60_NoEs_SD ;Por defecto es RD

;goto m_b_60_Es_SD001

goto m_b_60_Es_SD001

;m_b_60_Sera_SD002

movlw .252

subwf LOCAL_3,W

btfss STATUS,Z

goto m_b_60_NoEs_SD ;Por defecto es RD

;goto m_b_60_Es_SD001

m_b_60_Es_SD002

movlw .2
movwf LOCAL_3

bsf LOCAL_2,4

goto m_b_60_NoEs_SD

m_b_60_Es_SD001

movlw .1

movwf LOCAL_3

bsf LOCAL_2,4

goto m_b_60_NoEs_SD

m_b_60_Es_SD000

movlw .0

movwf LOCAL_3

bsf LOCAL_2,4

goto m_b_60_NoEs_SD

m_b_60_NoEs_SD

movf FSR,W ;Salvamos el valor de FSR porque se usa en DameBooleano

movwf LOCAL_4

;Funcion DameBooleano

;Esta función coge un operando de pseudo-código y obtiene su valor lógico 0 ó 1

;Parametros: B0:LOCAL_2, B0:LOCAL_3

;Temporales: B0:LOCAL_0, B0:LOCAL_1, FSR-INDF

bsf PCLATH,3

call DameBooleano

bcf PCLATH,3

movwf LOCAL_2 ;El resultado esta en el acumulador, lo salvamos en


LOCAL_2
movf LOCAL_4,W ;Restauramos el valor de FSR

movwf FSR

;En la misma trama recibida ponemos el valor del bit.

decf FSR,F

decf FSR,F

btfss LOCAL_2,0

goto m_b_60_EsCero

goto m_b_60_EsUno

m_b_60_EsCero

bcf INDF,3

goto m_b_60_Seguir

m_b_60_EsUno

bsf INDF,3

m_b_60_Seguir

incf FSR,F

incf FSR,F

incf FSR,F

decfsz 0x2E,F

goto m_b_60_bucle

m_b_60_Fin

call mandar_trama_a_maestro

goto m_b_16
;
*************************************************************************************
*****

;* Hemos recibido por USART el comando .2: Lectura de la configuración de I/O de FLASH

;
*************************************************************************************
*****

m_b_80

sBanco0

;Vamos a enviar 28 nibbles en la trama, que son 7 posiciones de memoria FLASH

;empezando en la posición (0x17F9)

movlw 0x17

movwf LOCAL_4

movlw 0xF9

movwf LOCAL_5

;Primero tenemos que comprobar que no excede de un valor para no pasarnos del

;final de la memoria flash.

movlw .7

movwf LOCAL_1

bcf STATUS,IRP ;Selecciona el banco 0-1 en direccionamiento indirecto

movlw 0x2E ;En 0x2E pondremos el primer nibble leido de Flash.

movwf FSR

m_b_80_Bucle_7_Posiciones
call LeerDeFlash ;Lee de la memoria FLASH apuntada en (LOCAL_4,LOCAL_5) y
deja

;el resultado en (LOCAL_6,LOCAL_7)

;Guardamos el resultado en la trama a enviar.

;Ahora tenemos que guardar los nibble de (LOCAL_6,LOCAL_7) en (FSR,FSR+1,FSR+2,FSR+3)

swapf LOCAL_6,W

andlw 0x0F

movwf INDF

incf FSR,F

movf LOCAL_6,W

andlw 0x0F

movwf INDF

incf FSR,F

swapf LOCAL_7,W

andlw 0x0F

movwf INDF

incf FSR,F

movf LOCAL_7,W

andlw 0x0F

movwf INDF

incf FSR,F
;Incrementamos la posicion a leer. (LOCAL_4,LOCAL_5)

movf LOCAL_5,W

addlw 1

movwf LOCAL_5

btfsc STATUS,C

incf LOCAL_4,F

decfsz LOCAL_1

goto m_b_80_Bucle_7_Posiciones

movlw .2

movwf BUFFER_RX_2 ;Comando 2

movlw .28

movwf BUFFER_RX_3 ;Queremos enviar 7 posiciones de FLASH, 28 nibbles

call mandar_trama_a_maestro

goto m_b_16

;
*************************************************************************************
*****

;* Hemos recibido por USART el comando .1: Lectura de programa LADDER

;
*************************************************************************************
*****

m_b_78

sBanco0
;Vamos a enviar 40 nibbles en la trama, que son 10 posiciones de memoria FLASH

;empezando en la posición (0x2E,0x2F,0x30,0x31)

;A partir de los nibbles recibidos por USART formamos el byte.

;(0x2E,0x2F) -> LOCAL_4

movf 0x2E,W ;Nibble-3 de la direccion FLASH

movwf LOCAL_0

swapf LOCAL_0,F

movf 0x2F,W ;Nibble-2 de la direccion FLASH

iorwf LOCAL_0,W

movwf LOCAL_4

;A partir de los nibbles recibidos por USART formamos el byte.

;(0x30,0x31) -> LOCAL_5

movf 0x30,W ;Nibble-1 de la direccion FLASH

movwf LOCAL_0

swapf LOCAL_0,F

movf 0x31,W ;Nibble-0 de la direccion FLASH

iorwf LOCAL_0,W

movwf LOCAL_5

;Primero tenemos que comprobar que no excede de un valor para no pasarnos del

;final de la memoria flash.

movlw .10

movwf LOCAL_1

bcf STATUS,IRP ;Selecciona el banco 0-1 en direccionamiento indirecto

movlw 0x32 ;En 0x2F pondremos el primer nibble leido de Flash.


movwf FSR

m_b_78_Bucle_10_Posiciones

call LeerDeFlash ;Lee de la memoria FLASH apuntada en (LOCAL_4,LOCAL_5) y


deja

;el resultado en (LOCAL_6,LOCAL_7)

;Guardamos el resultado en la trama a enviar.

;Ahora tenemos que guardar los nibble de (LOCAL_6,LOCAL_7) en (FSR,FSR+1,FSR+2,FSR+3)

swapf LOCAL_6,W

andlw 0x0F

movwf INDF

incf FSR,F

movf LOCAL_6,W

andlw 0x0F

movwf INDF

incf FSR,F

swapf LOCAL_7,W

andlw 0x0F

movwf INDF

incf FSR,F

movf LOCAL_7,W

andlw 0x0F
movwf INDF

incf FSR,F

;Incrementamos la posicion a leer. (LOCAL_4,LOCAL_5)

movf LOCAL_5,W

addlw 1

movwf LOCAL_5

btfsc STATUS,C

incf LOCAL_4,F

decfsz LOCAL_1

goto m_b_78_Bucle_10_Posiciones

movlw .1

movwf BUFFER_RX_2 ;Comando 1

movlw .44

movwf BUFFER_RX_3 ;Queremos enviar 4 datos

call mandar_trama_a_maestro

goto m_b_16

;
*************************************************************************************
*****

;* Hemos recibido por USART el comando .4: Monitorización de todas las E/S

;
*************************************************************************************
*****
m_b_84

;;Vamos a tener que leer de memoria RAM en banco 3 y enviar por RS232

;;B0:LOCAL_0 Utilizado para recorrer en direccionamiento indirecto la zona

;; del Banco 3 donde estan los valores a leer.

;;B0:LOCAL_1 Utilizado para recorrer en direccionamiento indirecto la zona

;; del Banco 0 donde esta el buffer de envio.

;;B0:LOCAL_2 Utilizado para poder realizar un bucle 20 veces

;;B0:LOCAL_3 temporal, utilizado para meter el valor leido

;;

sBanco0

movlw 0x17 ;En 0x17 tenemos el primer byte del banco 3 a leer

movwf LOCAL_0

movlw 0x2E ;En 0x2E pondremos la primera posicion del buffer Tx-232

movwf LOCAL_1

movlw .21 ;Queremos hacer el bucle 20 veces.

movwf LOCAL_2

m_b_84_Bucle_21_Posiciones

sBanco0

bsf STATUS,IRP ;Seleccionamos bancos 2-3 en direccionamiento


indirecto

movf LOCAL_0,W

iorlw 0x80 ;Seleccionamos banco 3 en direccionamiento indirecto

movwf FSR

incf LOCAL_0,F ;Incrementamos el puntero de B3.RAM


movf INDF,W

movwf LOCAL_3 ;Guardamos el valor leido en LOCAL_3

bcf STATUS,IRP ;Seleccionamos bancos 0-1 en direccionamiento


indirecto

movf LOCAL_1,W ;Banco 0 en direccionamiento indirecto

movwf FSR

; swapf LOCAL_3,W ;Metemos el valor leido de RAM en Buffer de TX-232

movf LOCAL_3,W ;Metemos el valor leido de RAM en Buffer de TX-232

andlw 0x0F

movwf INDF

incf LOCAL_1,F

movf LOCAL_1,W ;Banco 0 en direccionamiento indirecto

movwf FSR

swapf LOCAL_3,W ;Metemos el valor leido de RAM en Buffer de TX-232

andlw 0x0F

movwf INDF

incf LOCAL_1,F

decfsz LOCAL_2

goto m_b_84_Bucle_21_Posiciones

m_b_84_Fin

sBanco0
bcf STATUS,IRP ;Selecciona el banco 0-1 en direccionamiento indirecto

movlw .4

movwf BUFFER_RX_2 ;Comando 4

movlw .42

movwf BUFFER_RX_3 ;Queremos enviar 42 datos

call mandar_trama_a_maestro

goto m_b_16

;
*************************************************************************************
*****

;* Hemos recibido por USART el comando .16: Monitorización de bytes

;
*************************************************************************************
*****

m_b_76

sBanco0

movf 0x2E,W ;En 0x2E tenemos el numero de operandos a monitorizar

btfsc STATUS,Z

goto m_b_76_Fin

bcf STATUS,IRP ;Selecciona el banco 0-1 en direccionamiento indirecto

movlw 0x2F ;En 0x2F tenemos el primer byte.

movwf FSR

m_b_76_bucle

movf INDF,W
movwf LOCAL_2

incf FSR,F

movf INDF,W

swapf INDF,W

andlw 0xF0

movwf LOCAL_3

incf FSR,F

movf INDF,W

andlw 0x0F

iorwf LOCAL_3,F

movf FSR,W ;Salvamos el valor de FSR porque se usa en DameBooleano

movwf LOCAL_4

;Funcion DameByte

;Esta función coge un operando de pseudo-código y obtiene su valor.

;Parametros: B0:LOCAL_2, B0:LOCAL_3 en B0:LOCAL_2 Tenemos el tipo de memoria, en


B0:LOCAL_3 el byte

;Temporales: B0:LOCAL_0, B0:LOCAL_1, FSR-INDF

bsf PCLATH,3

call DameByte

bcf PCLATH,3

movwf LOCAL_2 ;El resultado esta en el acumulador, lo salvamos en


LOCAL_2
movf LOCAL_4,W ;Restauramos el valor de FSR

movwf FSR

;En la misma trama recibida ponemos el valor del bit.

incf FSR,F

;Escribimos el nibble alto del byte

;A partir de un byte formamos los nibbles a enviar por USART.

;LOCAL_2 -> (FSR,FSR+1)

movf LOCAL_2,W

movwf LOCAL_0

swapf LOCAL_0,W

andlw 0x0F

movwf INDF

incf FSR,F

;Escribimos el nibble bajo del byte

movf LOCAL_0,W

andlw 0x0F

movwf INDF

;Fin formacion nibbles

incf FSR,F

decfsz 0x2E,F

goto m_b_76_bucle

m_b_76_Fin
call mandar_trama_a_maestro

goto m_b_16

;
*************************************************************************************
*****

;* Hemos recibido por USART el comando 0x23: Debugger 1 instrucción

;
*************************************************************************************
*****

m_b_62

goto m_b_16

;
*************************************************************************************
*****

;* Hemos recibido por USART el comando .12: Forzado

;
*************************************************************************************
*****

m_b_64

sBanco0

;!!!!!!!Habria que comprobar que esta trama tiene longitud 4

;movf 0x2E,W ;En 0x2E tenemos el valor 0x00 0x01 a forzar

movf 0x2F,W

movwf LOCAL_2

btfss 0x2E,0

goto m_b_64_Poner0

goto m_b_64_Poner1

m_b_64_Poner0
bcf LOCAL_2,3

goto m_b_64_Salir

m_b_64_Poner1

bsf LOCAL_2,3

m_b_64_Salir

movf 0x30,W

andlw 0x0F

movwf LOCAL_3

swapf LOCAL_3,F

movf 0x31,W

andlw 0x0F

iorwf LOCAL_3,F

bsf PCLATH,3

call SetBooleano

bcf PCLATH,3

movlw .12

movwf BUFFER_RX_2 ;Cargamos el comando .12

clrf BUFFER_RX_3 ;Tamaño de datos : 0

call mandar_trama_a_maestro

goto m_b_16

;
*************************************************************************************
*****
;* Hemos recibido por USART el comando .13: Poner CPU a START

;
*************************************************************************************
*****

m_b_66 ;Hemos recibido el mensaje de poner la CPU a START

sBanco0

bsf Bx_SD_2RUN

bsf B0_bPLConRUN

movlw .13

movwf BUFFER_RX_2 ;Cargamos el comando .13

clrf BUFFER_RX_3 ;Tamaño de datos : 0

call mandar_trama_a_maestro

goto m_b_16

;
*************************************************************************************
*****

;* Hemos recibido por USART el comando .14: poner CPU a STOP

;
*************************************************************************************
*****

m_b_68 ;Hemos recibido el mensaje de poner la CPU a STOP

pPagina3

call Pg3_PonerCPUaSTOP

pPagina0

sBanco0

;;Ponemos en STOP
;sBanco3

;clrf B3_ByteIO_P1_p8

;clrf B3_ByteIO_P9_p16

;clrf B3_ByteIO_P17_p24

;clrf B3_ByteIO_P25_p32

;clrf B3_ByteIO_P33_p40

;bsf PCLATH,3

;call Pg1_EntradasSalidas

;bcf PCLATH,3

;sBanco0

;bcf B0_bPLConRUN

pPagina2

call Pg2_LimpiarTimers

pPagina0

movlw .14

movwf BUFFER_RX_2 ;Cargamos el comando .14

clrf BUFFER_RX_3 ;Tamaño de datos : 0

call mandar_trama_a_maestro

goto m_b_16

;
*************************************************************************************
*****

;* Hemos recibido por USART el comando .11: ACK

;
*************************************************************************************
*****
;m_b_70

; ;ping-pong

; sBanco0

; call mandar_trama_a_maestro

; goto m_b_16

m_b_70

pPagina3

call Pg3_RespondeTramaVersion

pPagina0

; ;ping-pong

; sBanco0

; ;Ponemos el MLCHIP y version

; movlw .2

; movwf BUFFER_RX_3 ;Tamaño de datos utiles: 2

; movlw .1

; movwf 0x2E ;MLCHIP1

; movwf 0x2F ;Version 1

; call mandar_trama_a_maestro

goto m_b_16

;
*************************************************************************************
*****

;* Hemos recibido por USART el comando .12: Nos piden el contenido de una posicion FLASH

;
*************************************************************************************
*****

; ESTO HAY QUE REVISARLO PORQUE SEGURAMENTE NO FUNCIONA

;m_b_72
; sBanco0

; goto m_b_16

;
*************************************************************************************
*****

;* Hemos recibido por USART el comando .39: Nos piden el contenido de una posicion RAM

;
*************************************************************************************
*****

m_b_74

sBanco0

goto m_b_16

;+++++++++++++++++++++++++++++++++++++++RUTINAS++++++++++++++++++++++++++++++++++++++
++++++++

;++++++++++++++++++++++++++RUTINAS++++++++++++++++++RUTINAS++++++++++++++++++++++++++
++++++++

;+++++++++++++++++++++++RUTINAS+++++RUTINAS++++++++++++++++++++++++++++++++++++++++++
++++++++

;+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++RUTINAS++++++++++++++
++++++++

;++++++++++++++++++++++++++++++++++++++++++++RUTINAS+++++++++++++++++++++++++++++++++
++++++++

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++RUTINAS+++++++++++++++++++++
++++++++

;++++++RUTINAS++++++RUTINAS++++++++++++++++++++++++++++++++++++++++++RUTINAS+++++++++
++++++++

Pg0_EEPROM

;Esta rutina se ejecuta siempre. (En RUN o STOP) y lo que hace es terminar el

;proceso de escritura en EEPROM, ya sea de 1 o 2 bytes.


btfss Bx_EE_EnMarcha

goto Pg0_EEPROM_Salir

;Aqui tenemos un proceso de escritura en marcha

sBanco3

btfsc EECON1,WR ;Mientras este bit este a 1 el PIC esta escribiendo en EEPROM

goto Pg0_EEPROM_Salir

;El proceso de escritura en curso de EEPROM ha terminado.

sBanco3

movf B3_PunteroUltEEPROM,W

subwf B3_PunteroSigEEPROM,W

btfsc STATUS,C

goto Pg0_EEPROM_Terminar ;Hemos terminado de escribir el ultimo byte en


EEPROM

;Tenemos que enviar el siguiente byte

incf B3_PunteroSigEEPROM,F

;******************************************************************************
**************

; Parametro de entrada:

; B0:LOCAL_0 direccion EEPROM donde escribir

; B0:LOCAL_1 Valor a Escribir

movf B3_PunteroSigEEPROM,W

addwf B3_DireccionEEPROM,W

sBanco0

movwf LOCAL_0

sBanco3

movf B3_SegundoByteEEPROM,W
sBanco0

movwf LOCAL_1

call Pg0_EscribirEnEEPROM

goto Pg0_EEPROM_Salir

Pg0_EEPROM_Terminar

;sBanco0

;bsf B0_Pre_SD_EE_FREE

bsf Bx_SD_EE_FREE

bcf Bx_EE_EnMarcha

;Tenemos que poner el valor de B0_Pre_SD_EE_WROK o B0_Pre_SD_EE_WRER

sBanco3

movf B3_PunteroSigEEPROM,W

btfsc STATUS,Z

goto Pg0_EE_Term_1Byte

;goto int_EE_Term_2Byte

Pg0_EE_Term_2Byte

;Leemos para comprobar si es lo mismo que se mando escribir

;******************************************************************************
**************

; Parametro de entrada:

; B0:LOCAL_0 direccion EEPROM donde leer.

; W: Devuelve el valor en el acumulador.

movf B3_DireccionEEPROM,W

addlw .1

sBanco0

movwf LOCAL_0

call Pg0_LeerDeEEPROM
sBanco3

subwf B3_SegundoByteEEPROM,W

btfss STATUS,Z

goto Pg0_EE_TermERROR

Pg0_EE_Term_1Byte

;Leemos para comprobar si es lo mismo que se mando escribir

;******************************************************************************
**************

; Parametro de entrada:

; B0:LOCAL_0 direccion EEPROM donde leer.

; W: Devuelve el valor en el acumulador.

movf B3_DireccionEEPROM,W

sBanco0

movwf LOCAL_0

call Pg0_LeerDeEEPROM

sBanco3

subwf B3_PrimerByteEEPROM,W

btfss STATUS,Z

goto Pg0_EE_TermERROR

Pg0_EE_TermOK

;Sí es igual

;sBanco0

bsf Bx_SD_EE_WROK

bcf Bx_SD_EE_WRER

goto Pg0_EEPROM_Salir
;goto salir_inter

Pg0_EE_TermERROR

;No es igual

;sBanco0

bcf Bx_SD_EE_WROK

bsf Bx_SD_EE_WRER

Pg0_EEPROM_Salir

sBanco0

return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Pg0_ActualizaTimers

;Vamos a actualizar los temporizadores.

sBanco1

movf B1_BT_1,W

movwf B1_DEC_BT_1

movf B1_BT_10,W

movwf B1_DEC_BT_10

movf B1_BT_100,W

movwf B1_DEC_BT_100

movf B1_BT_1000,W

movwf B1_DEC_BT_1000

;Recorremos los temporizadores que esten activos.


bsf STATUS,IRP ;Direccionamiento indirecto en bancos 2 y 3.

movlw 0x3E ;Byte de control del timer 0

iorlw 0x80 ;Vamos al banco3

movwf FSR

Pg0_BucleTimers

;Primero evaluamos si el timer esta activado

btfss INDF,TimControl_ActivacionBT

goto Pg0_BucleTimers_SaltarEsteTimer

;... Hacemos lo pertinente con el timer (Begin)

;... Ojo: Aqui hay que incrementar FSR una vez para acceder al valor del byte

; del timer

;Comprobamos si hay que descontar

incf FSR,F

movf INDF,W

;btfsc STATUS,Z

;goto Pg0_BucleTimers_Seguir

;El valor del timer es distinto de cero. Vemos para descontar la base de tiempos.

decf FSR,F ;Vamos otra vez al byte de registro.

movf INDF,W

andlw 0x18 ;Para acceder solo a la base de tiempos

btfsc STATUS,Z

goto Pg0_BucleTimers_BT_1mseg
movf INDF,W

andlw 0x18

xorlw 0x18 ;Para acceder solo a la base de tiempos

btfsc STATUS,Z

goto Pg0_BucleTimers_BT_1000mseg

btfss INDF,TimControl_BaseTiempo_BitBajo

goto Pg0_BucleTimers_BT_100mseg

goto Pg0_BucleTimers_BT_10mseg

Pg0_BucleTimers_SaltarEsteTimer

incf FSR,F

goto Pg0_BucleTimers_Seguir

Pg0_BucleTimers_BT_1mseg

movf B1_DEC_BT_1,W

movwf B1_DEC_BT

goto Pg0_BucleTimers_Decrementar

Pg0_BucleTimers_BT_10mseg

movf B1_DEC_BT_10,W

movwf B1_DEC_BT

goto Pg0_BucleTimers_Decrementar

Pg0_BucleTimers_BT_100mseg

movf B1_DEC_BT_100,W

movwf B1_DEC_BT

goto Pg0_BucleTimers_Decrementar

Pg0_BucleTimers_BT_1000mseg

movf B1_DEC_BT_1000,W
movwf B1_DEC_BT

;goto Pg0_BucleTimers_Decrementar

Pg0_BucleTimers_Decrementar

incf FSR,F ;Estamos otra vez en el valor

;Ya tenemos la cantidad a decrementar en B1_DEC_BT

movf B1_DEC_BT,W ;Aqui esta el descontaje

subwf INDF,W ;En INDF esta el valor

btfsc STATUS,Z

goto Pg0_BucleTimers_ValorIgualQueDescontaje

btfsc STATUS,C

goto Pg0_BucleTimers_ValorMayorQueDescontaje

goto Pg0_BucleTimers_ValorMenorQueDescontaje

Pg0_BucleTimers_ValorMayorQueDescontaje

movf B1_DEC_BT,W ;Aqui esta el descontaje

subwf INDF,F ;En INDF esta el valor

goto Pg0_BucleTimers_DescontajeHecho

Pg0_BucleTimers_ValorMenorQueDescontaje

Pg0_BucleTimers_ValorIgualQueDescontaje

clrf INDF

Pg0_BucleTimers_DescontajeHecho

;Aqui tenemos que chequear el tipo de timer. TON,TOFF,TIMEUP,TIMEDN

movf INDF,W
btfss STATUS,Z

goto Pg0_BucleTimers_Seguir

decf FSR,F

movf INDF,W

andlw 0x06 ;Para acceder solo al tipo de timer

btfsc STATUS,Z

goto Pg0_BucleTimers_Ton

movf INDF,W

andlw 0x06

xorlw 0x06 ;Para acceder solo al tipo de timer

btfsc STATUS,Z

goto Pg0_BucleTimers_TimeDn

btfss INDF,TimControl_TipoTimer_BitBajo

goto Pg0_BucleTimers_TimeUp

goto Pg0_BucleTimers_Toff

Pg0_BucleTimers_Ton

;bsf INDF,TimControl_SalidaTimer

goto Pg0_BucleTimers_FinAccion

Pg0_BucleTimers_Toff

; bcf INDF,TimControl_SalidaTimer

; bcf INDF,TimControl_ActivacionBT

goto Pg0_BucleTimers_FinAccion

Pg0_BucleTimers_TimeUp
Pg0_BucleTimers_TimeDn

bcf INDF,TimControl_SalidaTimer

bcf INDF,TimControl_ActivacionBT

bcf INDF,TimControl_YaEnMarcha

Pg0_BucleTimers_FinAccion

incf FSR,F

;... Hacemos lo pertinente con el timer (End)

Pg0_BucleTimers_Seguir

movlw 0x6F

iorlw 0x80

subwf FSR,W

btfsc STATUS,Z

goto Pg0_BucleTimersEnd ;FSR es >= que 0x6F que es el valor del T24 el ultimo

incf FSR,F

goto Pg0_BucleTimers

Pg0_BucleTimersEnd

bcf INTCON,GIE ;Inhabilitamos interrupciones globalmente.

movf B1_DEC_BT_1,W

subwf B1_BT_1,F

movf B1_DEC_BT_10,W

subwf B1_BT_10,F
movf B1_DEC_BT_100,W

subwf B1_BT_100,F

movf B1_DEC_BT_1000,W

subwf B1_BT_1000,F

bsf INTCON,GIE ;Habilitamos interrupciones globalmente.

sBanco0

return

SaltoTimers

;
*************************************************************************************
****

;* CogeConfigIO_DeFLASH_ARAM

;
*************************************************************************************
****

CogeConfigIO_DeFLASH_ARAM

;Cogemos de Flash la configuración de Entradas/Salidas y lo ponemos en RAM

pPagina2

;bsf PCLATH,3

sBanco3

call Pg2_Byte_ConfiguracionIO_1

movwf Banco3Reg0x10

call Pg2_Byte_ConfiguracionIO_2

movwf Banco3Reg0x11

call Pg2_Byte_ConfiguracionIO_3
movwf Banco3Reg0x12

call Pg2_Byte_ConfiguracionIO_4

movwf Banco3Reg0x13

call Pg2_Byte_ConfiguracionIO_5

movwf Banco3Reg0x14

call Pg2_Byte_ConfiguracionIO_6

movwf Banco3Reg0x15

call Pg2_Byte_ConfiguracionIO_7

movwf Banco3Reg0x16

;bcf PCLATH,3

pPagina0

sBanco0

;Ademas tenemos que configurar los TRIS y ADCON1

movlw 0xFF

movwf AI_YaRealizada1Vez

;bsf bTodasADLeidas

;Limpiamos el registro indicando que SI hemos


leido por 1 vez

;las A/D (Esto por si acaso hay algun error en el


software que

;no se quede bloqueado esperando.

clrf AI_EntradaAnalogLeida

;La ultima Analog Input leida es la 0 (Es decir


ninguna)

clrf COMUN_PORT_A

clrf COMUN_PORT_B

clrf COMUN_PORT_C
sBanco3

btfss bConfig_0_EA ;A 1 tenemos configurada 0 Analog Input

goto _0_EA_End

;Configuramos todas las patas como digitales.

sBanco1

movlw b'10000110'

movwf ADCON1

goto _x_EA_End

_0_EA_End

btfss bConfig_1_EA ;A 1 tenemos configurada 1 Analog Input

goto _1_EA_End

;Configuramos 1 pata como analogica.

sBanco1

movlw b'10001110'

movwf ADCON1

sBanco0

movlw b'11111110' ;Damos por leidas las que no estan configuradas

movwf AI_YaRealizada1Vez

;bcf bTodasADLeidas

goto _x_EA_End

_1_EA_End

btfss bConfig_3_EA ;A 1 tenemos configurada 3 Analog Input


goto _3_EA_End

;Configuramos 3 patas como analogicas.

sBanco1

movlw b'10000100'

movwf ADCON1

sBanco0

movlw b'11110100' ;Damos por leidas las que no estan configuradas

movwf AI_YaRealizada1Vez

;bcf bTodasADLeidas

goto _x_EA_End

_3_EA_End

btfss bConfig_5_EA ;A 1 tenemos configurada 5 Analog Input

goto _x_EA_End

;Configuramos 5 patas como analogicas.

sBanco1

movlw b'10000000'

movwf ADCON1

sBanco0

movlw b'11100000' ;Damos por leidas las que no estan configuradas

movwf AI_YaRealizada1Vez

;bcf bTodasADLeidas

_x_EA_End
sBanco3

;Aqui vamos a poner el valor de TRIS

;A las entradas analogicas hay que ponerlas como entrada.

Config_P2

btfsc bConfig_1_EA ;A 1 tenemos configurada 1 Analog Input

goto P2_EsAnalogica

btfsc bConfig_3_EA ;A 1 tenemos configurada 3 Analog Input

goto P2_EsAnalogica

btfsc bConfig_5_EA ;A 1 tenemos configurada 3 Analog Input

goto P2_EsAnalogica

P2_EsDigital

bsf COMUN_PORT_A,0

btfss P2_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

bcf COMUN_PORT_A,0

goto Config_P3

P2_EsAnalogica

bsf COMUN_PORT_A,0

Config_P3

btfsc bConfig_3_EA ;A 1 tenemos configurada 3 Analog Input

goto P3_EsAnalogica

btfsc bConfig_5_EA ;A 1 tenemos configurada 3 Analog Input

goto P3_EsAnalogica

P3_EsDigital
bsf COMUN_PORT_A,1

btfss P3_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

bcf COMUN_PORT_A,1

goto Config_P4

P3_EsAnalogica

bsf COMUN_PORT_A,1

Config_P4

btfsc bConfig_5_EA ;A 1 tenemos configurada 3 Analog Input

goto P4_EsAnalogica

P4_EsDigital

bsf COMUN_PORT_A,2

btfss P4_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

bcf COMUN_PORT_A,2

goto Config_P5

P4_EsAnalogica

bsf COMUN_PORT_A,2

Config_P5

btfsc bConfig_3_EA ;A 1 tenemos configurada 3 Analog Input

goto P5_EsAnalogica

btfsc bConfig_5_EA ;A 1 tenemos configurada 3 Analog Input

goto P5_EsAnalogica

P5_EsDigital

bsf COMUN_PORT_A,3

btfss P5_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

bcf COMUN_PORT_A,3
goto Config_P6

P5_EsAnalogica

bsf COMUN_PORT_A,3

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;Esto se nos habia olvidado. Insertado el 23-04-2003 (BEGIN)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Config_P6

btfsc bConfigSHUT ;A 1 tenemos configurada 3 Analog Input

goto P6_EsShutDown

P6_EsDigital

bsf COMUN_PORT_A,4

btfss P6_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

bcf COMUN_PORT_A,4

goto Config_P7

P6_EsShutDown

bsf COMUN_PORT_A,4 ;Si es shutdown la declaramos como Digital Input

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;Esto se nos habia olvidado. Insertado el 23-04-2003 (END)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Config_P7

;Corrección del BUG_1 (Begin)

; btfsc bConfig_3_EA ;A 1 tenemos configurada 3 Analog Input

; goto P7_EsAnalogica

;Corrección del BUG_1 (End)

btfsc bConfig_5_EA ;A 1 tenemos configurada 3 Analog Input


goto P7_EsAnalogica

P7_EsDigital

bsf COMUN_PORT_A,5

btfss P7_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

bcf COMUN_PORT_A,5

goto Config_P7_End

P7_EsAnalogica

bsf COMUN_PORT_A,5

Config_P7_End

bsf COMUN_PORT_C,0

btfss P11_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

bcf COMUN_PORT_C,0

bsf COMUN_PORT_C,1

btfss P12_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

bcf COMUN_PORT_C,1

bsf COMUN_PORT_C,2

btfss P13_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

bcf COMUN_PORT_C,2

;;Aqui hay que considerar el I2C

bsf COMUN_PORT_C,3

btfss P14_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

bcf COMUN_PORT_C,3

;;Aqui hay que considerar el I2C


bsf COMUN_PORT_C,4

btfss P15_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

bcf COMUN_PORT_C,4

bsf COMUN_PORT_C,5

btfss P16_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

bcf COMUN_PORT_C,5

;;TX-232

bcf COMUN_PORT_C,6

;;RX-232

bsf COMUN_PORT_C,7

bsf COMUN_PORT_B,0

btfss P21_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

bcf COMUN_PORT_B,0

bsf COMUN_PORT_B,1

btfss P22_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

bcf COMUN_PORT_B,1

bsf COMUN_PORT_B,2

btfss P23_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

bcf COMUN_PORT_B,2

bsf COMUN_PORT_B,3

btfss P24_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

bcf COMUN_PORT_B,3
bsf COMUN_PORT_B,4

btfss P25_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

bcf COMUN_PORT_B,4

bsf COMUN_PORT_B,5

btfss P26_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

bcf COMUN_PORT_B,5

bsf COMUN_PORT_B,6

btfss P27_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

bcf COMUN_PORT_B,6

bsf COMUN_PORT_B,7

btfss P28_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

bcf COMUN_PORT_B,7

;Sacamos valores al puerto

sBanco1

movf COMUN_PORT_A,W

movwf TRISA

movf COMUN_PORT_B,W

movwf TRISB

movf COMUN_PORT_C,W

movwf TRISC

;Aqui configuro LCD si procede


sBanco3

;;OJOJOJOJOJOJOJOJOJOJOJOJ esto hay que quitarlo

;bsf bConfigLCD ;Esto es de prueba, hay que quitarlo

btfss bConfigLCD

goto CogeConfigIO_DeFLASH_ARAM_End

sBanco1

clrf TRISB

bcf B1_LCD_RS

bcf B1_LCD_RW

bcf B1_LCD_E

sBanco0

bcf B0_LCD_RS

bcf B0_LCD_RW

bcf B0_LCD_E

CogeConfigIO_DeFLASH_ARAM_End

sBanco0

return

;
*************************************************************************************
****

;* RUTINA de comparación (>)

;
*************************************************************************************
****

byte_mayor_que

;Resultado B0:LOCAL_1<0>=1 si LOCAL_0 > LOCAL_1


sBanco0

movf LOCAL_1,W

subwf LOCAL_0,W

;Primero comprobamos si son iguales

btfsc STATUS,Z

goto m0123_i_no_es_mayor

btfss STATUS,C

goto m0123_i_no_es_mayor

m0123_i_es_mayor

bsf LOCAL_1,0

return

m0123_i_no_es_mayor

bcf LOCAL_1,0

return

;
*************************************************************************************
****

;* RUTINA de comparación (>=)

;
*************************************************************************************
****

byte_mayorigual_que

;Resultado B0:LOCAL_1<0>=1 si LOCAL_0 >= LOCAL_1

sBanco0

movf LOCAL_1,W

subwf LOCAL_0,W
;Primero comprobamos si son iguales

btfss STATUS,C

goto m123_i_no_es_mayor

m123_i_es_igual

m123_i_es_mayor

bsf LOCAL_1,0

return

m123_i_no_es_mayor

bcf LOCAL_1,0

return

;***************************************************************************

;* RUTINA que manda una trama:

;* chr(3),dirL,dirH,Comando,long.Datos,Dn,Dn-1,...,D0,Checksum,chr(4)

;***************************************************************************

mandar_trama_a_maestro

sBanco0

; bcf STATUS,RP0 ;Banco 0

; bcf STATUS,RP1

movf FSR,W ;Salvamos el valor de FSR

movwf LOCAL_4

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Enviamos el caracter de dirL del PIC

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

movf RX_232_DIRL,W ;dirL del PIC

movwf BUFFER_RX_0
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Enviamos el caracter de dirH del PIC

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

movf RX_232_DIRH,W ;dirH del PIC

movwf BUFFER_RX_1

bcf STATUS,RP0 ;seleccionamos banco 0

clrf LOCAL_5 ;En LOCAL_5 vamos a tener el checksum del campo de


datos variable

bcf STATUS,IRP ;Selecciona el banco 0 en direccionamiento indirecto

movlw 0x2E ;Empezamos en la posición 0x2E

movwf FSR

movf BUFFER_RX_3,W

btfsc STATUS,Z ;Comprobamos si hay datos variables para enviar

goto m_trama_i2

;Enviamos campo de datos de longitud variable

;****************************************************************************

;* Utilizamos un bucle con direccionamiento indirecto para calcular el

;* checksum de la trama recibida, lo almacenamos en LOCAL_0

;* Usamos como variable temporal LOCAL_1

;****************************************************************************

bcf STATUS,RP0 ;seleccionamos banco 0

clrf LOCAL_1 ;En LOCAL_1 vamos a tener la posición del ultimo


caracter a enviar

;mas 1 para poder parar el bucle de


direccionamiento indirecto

movf LOCAL_1,W
addlw 0x2E ;Es la dirección de BufferTransmision[0]

addwf BUFFER_RX_3,W ;Le sumamos el byte longitud campo de datos variable

movwf LOCAL_1

bcf STATUS,IRP ;Selecciona el banco 0 en direccionamiento indirecto

movlw 0x2E ;Empezamos en la posición 0x2E

movwf FSR

m_trama_i1

;Sumamos a Checksum

movf LOCAL_5,W ;Cargamos el Cheksum en el acumulador

addwf INDF,W

movwf LOCAL_5

incf FSR,F ;Incrementamos FSR

;Comprobamos si hemos llegado a 0x3F

movf LOCAL_1,W

subwf FSR,W ;Le restamos FSR y lo dejamos en W

btfss STATUS,Z ;Comprobamos si es cero la resta

goto m_trama_i1 ;Todavia no

;Ya hemos terminado de calcular el Checksum, lo


tenemos

;en LOCAL_5

;YA TENEMOS EL CHECKSUM EN LOCAL_5

;*****************************************************************************

;* Fin del bucle con direccionamiento indirecto

;*****************************************************************************
m_trama_i2 ;datos variables ya enviados

;Mandamos checksum de la trama

movf LOCAL_5,W ;Cargamos el checksum calculado de la trama de datos de


longitud

;variable

addlw .203 ;El caracter 203 de comienzo de trama de esclavo

addwf BUFFER_RX_0,W

addwf BUFFER_RX_1,W

addwf BUFFER_RX_2,W ;Comando.

addwf BUFFER_RX_3,W ;Longitud del campo de datos variable

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Comprobamos que checksum %= 201

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

movwf LOCAL_5 ;Lo guardamos temporalmente en LOCAL_5

movwf LOCAL_0

movlw .200 ;0xC8

movwf LOCAL_1

call byte_mayor_que

btfss LOCAL_1,0

goto m_b_10_No_es_mayor_que_200

movlw 0xC9

subwf LOCAL_5,F

m_b_10_No_es_mayor_que_200

movf LOCAL_5,W

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Enviamos el caracter de checksum

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

movwf INDF ;Enviamos el dato

incf FSR,F ;Incrementamos FSR

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Enviamos el caracter de final de trama

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

movlw .204 ;204 Antes 0x04

movwf INDF ;Enviamos el dato

incf FSR,W ;Incrementamos FSR

movwf BUFFER_TX_LAST

; bcf STATUS,RP0 ;Banco 0

; bcf STATUS,RP1

sBanco0

movf LOCAL_4,W ;Restauramos el valor de FSR

movwf FSR

movlw BUFFER_RX_0

movwf BUFFER_TX_NEXT

bsf 0x23,7

movlw .203

movwf TXREG

; bsf STATUS,RP0 ;Banco 1

sBanco1

bsf PIE1,TXIE

sBanco0

; bcf STATUS,RP0 ;Banco 0

return
;
*************************************************************************************
*******

;
*************************************************************************************
*******

;
*************************************************************************************
*******

;
*************************************************************************************
*******

;
*************************************************************************************
*******

; Mandar14Bits_A_BufferFLASH

; Mandamos una palabra de 14 bits al buffer de escritura en FLASH, si es la 4ª graba

; en flash.

; Parametro de entrada:

; B0:(LOCAL_0,LOCAL_1) Palabra de 14 bits

Mandar14Bits_A_BufferFLASH

sBanco1

bcf STATUS,IRP ;Banco 0-1 en direccionamiento indirecto

movlw GF_0

addwf GF_CONTADOR_UP,W

iorlw 0x80

movwf FSR
bcf STATUS,RP0 ;Banco 0

movf LOCAL_0,W

movwf INDF

incf FSR,F

movf LOCAL_1,W

movwf INDF

bsf STATUS,RP0 ;Banco 1

incf GF_CONTADOR_UP,F

incf GF_CONTADOR_UP,F

decfsz GF_CONTADOR_DOWN,F

goto Mandar14Bits_A_BufferFLASH_seguir

;Vamos a realizar la grabacion de las 4 palabras en FLASH

bcf STATUS,RP0 ;Banco 0

movf PCaPIC_FLASH_H,W

movwf LOCAL_0 ;Byte alto de la dirección a grabar en la FLASH

movf PCaPIC_FLASH_L,W

movwf LOCAL_1 ;Byte bajo de la dirección a grabar en la FLASH

call GrabarEnFlash

movlw .4

addwf PCaPIC_FLASH_L,F

btfsc STATUS,C

incf PCaPIC_FLASH_H,F
bsf STATUS,RP0 ;Banco 1

clrf GF_CONTADOR_UP

movlw .4

movwf GF_CONTADOR_DOWN

Mandar14Bits_A_BufferFLASH_seguir

sBanco0

return

;
*************************************************************************************
*******

;
*************************************************************************************
*******

;
*************************************************************************************
*******

;
*************************************************************************************
*******

;
*************************************************************************************
*******

; Mandar14Bits_A_BufferFLASH_Y_ForzarEscritura

; Mandamos una palabra de 14 bits al buffer de escritura en FLASH, si es la 4ª graba

; en flash.

; Parametro de entrada:

; B0:(LOCAL_0,LOCAL_1) Palabra de 14 bits

;
Mandar14Bits_A_BufferFLASH_Y_ForzarEscritura

sBanco1

; bsf STATUS,RP0 ;Banco 1

; bcf STATUS,RP1

bcf STATUS,IRP ;Banco 0-1 en direccionamiento indirecto

movlw GF_0

addwf GF_CONTADOR_UP,W

iorlw 0x80

movwf FSR

bcf STATUS,RP0 ;Banco 0

movf LOCAL_0,W

movwf INDF

incf FSR,F

movf LOCAL_1,W

movwf INDF

bsf STATUS,RP0 ;Banco 1

;Vamos a realizar la grabacion de las 4 palabras en FLASH

bcf STATUS,RP0 ;Banco 0

movf PCaPIC_FLASH_H,W

movwf LOCAL_0 ;Byte alto de la dirección a grabar en la FLASH

movf PCaPIC_FLASH_L,W

movwf LOCAL_1 ;Byte bajo de la dirección a grabar en la FLASH

call GrabarEnFlash
movlw .4

addwf PCaPIC_FLASH_L,F

btfsc STATUS,C

incf PCaPIC_FLASH_H,F

bsf STATUS,RP0 ;Banco 1

clrf GF_CONTADOR_UP

movlw .4

movwf GF_CONTADOR_DOWN

sBanco0

return

;
*************************************************************************************
*******

;
*************************************************************************************
*******

; Parametro de entrada:

; B0:(LOCAL_0,LOCAL_1) direccion FLASH donde escribir

; B1:GF_0 primera direccion RAM de los 4 datos a escribir

GrabarEnFlash

;Para PIC16F876A

sBanco0

movf LOCAL_0,W

bsf STATUS,RP1 ;Banco 2

movwf EEADRH
bcf STATUS,RP1 ;Banco 0

movf LOCAL_1,W

bsf STATUS,RP1 ;Banco 2

movwf EEADR

movlw GF_0 ;Cargamos el comienzo del buffer de escritura en FSR

bcf STATUS,IRP

iorlw 0x80

movwf FSR

GrabarEnFlash_Loop

movf INDF,W

movwf EEDATH

incf FSR,F

movf INDF,W

movwf EEDATA

incf FSR,F

bsf STATUS,RP0 ;Banco 3

bsf EECON1,EEPGD

bsf EECON1,WREN

bcf INTCON,GIE

movlw 0x55

movwf EECON2

movlw 0xAA

movwf EECON2

bsf EECON1,WR

nop

nop

bcf EECON1,WREN
bsf INTCON,GIE

bcf STATUS,RP0 ;Banco 2

movf EEADR,W

andlw 0x03

xorlw 0x03

btfsc STATUS,Z

goto GrabarEnFlash_Ssalir

incf EEADR,F

goto GrabarEnFlash_Loop

GrabarEnFlash_Ssalir

sBanco0

; bcf STATUS,RP0

; bcf STATUS,RP1 ;Banco 0

return

;
*************************************************************************************
*******

;
*************************************************************************************
*******

;
*************************************************************************************
*******

;
*************************************************************************************
*******

;
*************************************************************************************
*******
; Saltamos al ciclo de SCAN

;CicloScan

; movlw ByteAltoBeginLADDER

; movwf PCLATH

; movlw ByteBajoBeginLADDER

; movwf PCL

; return ;Aqui nunca llega.

;
*************************************************************************************
*******

;
*************************************************************************************
*******

; Parametro de entrada:

; Banco 0:

; (LOCAL_4,LOCAL_5) direccion donde leer

; Parametro de salida:

; Banco 0:

; (LOCAL_6,LOCAL_7) dato leido

LeerDeFlash

bcf STATUS,RP0 ;Banco 0

bcf STATUS,RP1

movf LOCAL_4,W

bcf STATUS,RP0 ;Banco 2

bsf STATUS,RP1
movwf EEADRH

bcf STATUS,RP0 ;Banco 0

bcf STATUS,RP1

movf LOCAL_5,W

bcf STATUS,RP0 ;Banco 2

bsf STATUS,RP1

movwf EEADR

bsf STATUS,RP0 ;Banco 3

bsf STATUS,RP1

bsf EECON1,EEPGD ;Seleccionamos FLASH

bsf EECON1,RD ;Damos la orden de lectura de FLASH

nop

nop

bcf STATUS,RP0 ;Banco 2

bsf STATUS,RP1

movf EEDATH,W

bcf STATUS,RP0 ;Banco 0

bcf STATUS,RP1

movwf LOCAL_6

bcf STATUS,RP0 ;Banco 2

bsf STATUS,RP1

movf EEDATA,W

bcf STATUS,RP0 ;Banco 0

bcf STATUS,RP1

movwf LOCAL_7
return

;
*************************************************************************************
*******

;
*************************************************************************************
*******

; Parametro de entrada:

; B0:LOCAL_0 direccion EEPROM donde escribir

; B0:LOCAL_1 Valor a Escribir

Pg0_EscribirEnEEPROM

sBanco3

btfsc EECON1,WR

goto $-1 ;Esperamos hasta que la ultima escritura haya terminado

sBanco0

movf LOCAL_0,W ;Cargamos la direccion donde escribir.

bsf STATUS,RP1 ;Vamos a Banco2

movwf EEADR

bcf STATUS,RP1 ;Vamos a Banco0

movf LOCAL_1,W

bsf STATUS,RP1 ;Vamos a Banco2

movwf EEDATA

bsf STATUS,RP0 ;Vamos a Banco3

bcf EECON1,EEPGD ;Seleccionamos EEPROM

bsf EECON1,WREN ;Habilitamos la escritura en EEPROM

bcf INTCON,GIE ;Inhabilitamos interrupciones globalmente.

movlw 0x55

movwf EECON2

movlw 0xAA
movwf EECON2

bsf EECON1,WR ;Lanzamos la escritura, este bit se pondra a 0 cuando

;haya terminado la escritura y lanzara una


interrupcion

bsf INTCON,GIE ;Habilitamos interrupciones globalmente.

bcf EECON1,WREN ;Inhabilitamos la escritura en EEPROM

sBanco0

return

;
*************************************************************************************
*******

;
*************************************************************************************
*******

; Parametro de entrada:

; B0:LOCAL_0 direccion EEPROM donde leer.

; W: Devuelve el valor en el acumulador.

Pg0_LeerDeEEPROM

sBanco0

movf LOCAL_0,W ;Cargamos la direccion donde escribir.

bsf STATUS,RP1 ;Vamos a Banco2

movwf EEADR

bsf STATUS,RP0 ;Vamos a Banco3

bcf EECON1,EEPGD ;Seleccionamos EEPROM

bsf EECON1,RD ;Lanzamos la lectura

bcf STATUS,RP0 ;Vamos a Banco2

movf EEDATA,W

bcf STATUS,RP1 ;Vamos a Banco0


return ;Devolvemos el valor en W

;Para PIC16F876A

sBanco0

movf LOCAL_0,W

bsf STATUS,RP1 ;Banco 2

movwf EEADRH

bcf STATUS,RP1 ;Banco 0

movf LOCAL_1,W

bsf STATUS,RP1 ;Banco 2

movwf EEADR

movlw GF_0 ;Cargamos el comienzo del buffer de escritura en FSR

bcf STATUS,IRP
iorlw 0x80

movwf FSR

GrabarEnEEPROM_Loop

movf INDF,W

movwf EEDATH

incf FSR,F

movf INDF,W

movwf EEDATA

incf FSR,F

bsf STATUS,RP0 ;Banco 3

bsf EECON1,EEPGD

bsf EECON1,WREN

bcf INTCON,GIE

movlw 0x55

movwf EECON2

movlw 0xAA

movwf EECON2

bsf EECON1,WR

nop

nop

bcf EECON1,WREN

bsf INTCON,GIE

bcf STATUS,RP0 ;Banco 2

movf EEADR,W

andlw 0x03

xorlw 0x03

btfsc STATUS,Z

goto GrabarEnFlash_Ssalir

incf EEADR,F
goto GrabarEnFlash_Loop

GrabarEnEEPROM_Ssalir

sBanco0

return

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x701 ;Estamos en Banco 0, accesible con PCLATH=0x00

fDOWN

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto fDOWN_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x703 ;Estamos en Banco 0, accesible con PCLATH=0x00

PREPARA_OPER

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto PREPARA_OPER_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x705 ;Estamos en Banco 0, accesible con PCLATH=0x00

DIV_TD3

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto fDIV_INT8U_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x707 ;Estamos en Banco 0, accesible con PCLATH=0x00

DIV_TD4
bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto fDIV_INT8S_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x709 ;Estamos en Banco 0, accesible con PCLATH=0x00

DIV_TD5

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto fDIV_INT16U_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x70B ;Estamos en Banco 0, accesible con PCLATH=0x00

DIV_TD6

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto fDIV_INT16S_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x70D ;Estamos en Banco 0, accesible con PCLATH=0x00

;DIV_TD7

; bsf PCLATH,3 ;Nos vamos a la página FLASH 1

; goto default ;fDIV_INT32U_SO

fPUT_EE

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto fPUT_EE_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x70F ;Estamos en Banco 0, accesible con PCLATH=0x00

;DIV_TD8

; bsf PCLATH,3 ;Nos vamos a la página FLASH 1

; goto default

fGET_EE

bsf PCLATH,4 ;Nos vamos a la página FLASH 2

goto Pg2_fGET_EE_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


ORG 0x711 ;Estamos en Banco 0, accesible con PCLATH=0x00

;DIV_TD9

; bsf PCLATH,3 ;Nos vamos a la página FLASH 1

; goto default

fNOP

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto default

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x713 ;Estamos en Banco 0, accesible con PCLATH=0x00

MUL_TD3

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto fMUL_INT8U_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x715 ;Estamos en Banco 0, accesible con PCLATH=0x00

MUL_TD4

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto fMUL_INT8S_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x717 ;Estamos en Banco 0, accesible con PCLATH=0x00

MUL_TD5

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto fMUL_INT16U_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x719 ;Estamos en Banco 0, accesible con PCLATH=0x00

MUL_TD6

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto fMUL_INT16S_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


ORG 0x71B ;Estamos en Banco 0, accesible con PCLATH=0x00

;MUL_TD7

; bsf PCLATH,3 ;Nos vamos a la página FLASH 1

; goto default ;fMUL_INT32U_SO

fCONV_INT8U_2_INT16U

bsf PCLATH,4 ;Nos vamos a la página FLASH 2

goto Pg2_Conv8U_16U_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x71D ;Estamos en Banco 0, accesible con PCLATH=0x00

;MUL_TD8

; bsf PCLATH,3 ;Nos vamos a la página FLASH 1

; goto default ;fMUL_INT32S_SO

fCONV_INT8S_2_INT16S

bsf PCLATH,4 ;Nos vamos a la página FLASH 2

goto Pg2_Conv8S_16S_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x71F ;Estamos en Banco 0, accesible con PCLATH=0x00

;MUL_TD9

; bsf PCLATH,3 ;Nos vamos a la página FLASH 1

; goto default

fCONV_INT16U_2_INT32U_Disponible

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto default

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x721 ;Estamos en Banco 0, accesible con PCLATH=0x00

;ASIGNAR_TD0_DISPONIBLE

; bsf PCLATH,3 ;Nos vamos a la página FLASH 1

; goto default
fCONV_INT16S_2_INT32S_Disponible

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto default

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x723 ;Estamos en Banco 0, accesible con PCLATH=0x00

;ASIGNAR_TD1_DISPONIBLE

; bsf PCLATH,3 ;Nos vamos a la página FLASH 1

; goto default

fGET_EE_BYTE_DISPONIBLE

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto default

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x725 ;Estamos en Banco 0, accesible con PCLATH=0x00

fGET_EE_WORD_DISPONIBLE

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto default

;ASIGNAR_TD2_DISPONIBLE

; bsf PCLATH,3 ;Nos vamos a la página FLASH 1

; goto default

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x727 ;Estamos en Banco 0, accesible con PCLATH=0x00

fINTLCD_TD3

bsf PCLATH,4 ;Nos vamos a la página FLASH 2

goto Pg2_fINT8uLCD_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x729 ;Estamos en Banco 0, accesible con PCLATH=0x00

fINTLCD_TD4

bsf PCLATH,4 ;Nos vamos a la página FLASH 2

goto Pg2_fINT8sLCD_SO
;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x72B ;Estamos en Banco 0, accesible con PCLATH=0x00

fINTLCD_TD5

bsf PCLATH,4 ;Nos vamos a la página FLASH 2

goto Pg2_fINT16uLCD_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x72D ;Estamos en Banco 0, accesible con PCLATH=0x00

fINTLCD_TD6

bsf PCLATH,4 ;Nos vamos a la página FLASH 2

goto Pg2_fINT16sLCD_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x72F ;Estamos en Banco 0, accesible con PCLATH=0x00

fCHRLCD

bsf PCLATH,4 ;Nos vamos a la página FLASH 2

goto Pg2_fCHRLCD_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x731 ;Estamos en Banco 0, accesible con PCLATH=0x00

fSTRLCD

bsf PCLATH,4 ;Nos vamos a la página FLASH 2

goto Pg2_fSTRLCD_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x733 ;Estamos en Banco 0, accesible con PCLATH=0x00

fGET_EE_DWORD_DISPONIBLE

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto default

;ASIGNAR_TD9_DISPONIBLE

; bsf PCLATH,3 ;Nos vamos a la página FLASH 1

; goto default
;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x735 ;Estamos en Banco 0, accesible con PCLATH=0x00

fGET_EE_INT8U_DISPONIBLE

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto default

;MOVER_TD0_DISPONIBLE

; bsf PCLATH,3 ;Nos vamos a la página FLASH 1

; goto default

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x737 ;Estamos en Banco 0, accesible con PCLATH=0x00

fGET_EE_INT8S_DISPONIBLE

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto default

;MOVER_TD1_DISPONIBLE

; bsf PCLATH,3 ;Nos vamos a la página FLASH 1

; goto default

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x739 ;Estamos en Banco 0, accesible con PCLATH=0x00

fGET_EE_INT16U_DISPONIBLE

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto default

;MOVER_TD2_DISPONIBLE

; bsf PCLATH,3 ;Nos vamos a la página FLASH 1

; goto default

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x73B ;Estamos en Banco 0, accesible con PCLATH=0x00

fGET_EE_INT16S_DISPONIBLE

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto default
;MOVER_TD3_DISPONIBLE

; bsf PCLATH,3 ;Nos vamos a la página FLASH 1

; goto default

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x73D ;Estamos en Banco 0, accesible con PCLATH=0x00

MOVER_TD4_DISPONIBLE

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto default

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x73F ;Estamos en Banco 0, accesible con PCLATH=0x00

fSCL

bsf PCLATH,4 ;Nos vamos a la página FLASH 2

goto Pg2_fSCL_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x741 ;Estamos en Banco 0, accesible con PCLATH=0x00

fFILL

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto fFILL_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x743 ;Estamos en Banco 0, accesible con PCLATH=0x00

fMOVI

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto fMOVI_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x745 ;Estamos en Banco 0, accesible con PCLATH=0x00

fMOV

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto fMOV_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


ORG 0x747 ;Estamos en Banco 0, accesible con PCLATH=0x00

fCOPY

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto fCOPY_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x749 ;Estamos en Banco 0, accesible con PCLATH=0x00

fUP

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto fUP_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x74B ;Estamos en Banco 0, accesible con PCLATH=0x00

fTOGGLE

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto fTOGGLE_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x74D ;Estamos en Banco 0, accesible con PCLATH=0x00

fRESETCF

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto fRESETCF_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x74F ;Estamos en Banco 0, accesible con PCLATH=0x00

fSETCF

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto fSETCF_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x751 ;Estamos en Banco 0, accesible con PCLATH=0x00

fRESET
bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto fRESET_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x753 ;Estamos en Banco 0, accesible con PCLATH=0x00

fSET

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto fSET_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x755 ;Estamos en Banco 0, accesible con PCLATH=0x00

ROR_TB4

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto ROR_TBx_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x757 ;Estamos en Banco 0, accesible con PCLATH=0x00

ROR_TB2

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto ROR_TBx_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x759 ;Estamos en Banco 0, accesible con PCLATH=0x00

ROR_TB1

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto ROR_TBx_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x75B ;Estamos en Banco 0, accesible con PCLATH=0x00

ROL_TB4

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto ROL_TBx_SO
;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x75D ;Estamos en Banco 0, accesible con PCLATH=0x00

ROL_TB2

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto ROL_TBx_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x75F ;Estamos en Banco 0, accesible con PCLATH=0x00

ROL_TB1

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto ROL_TBx_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x761 ;Estamos en Banco 0, accesible con PCLATH=0x00

COMPL_TB4

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto COMPL_TBx_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x763 ;Estamos en Banco 0, accesible con PCLATH=0x00

COMPL_TB2

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto COMPL_TBx_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x765 ;Estamos en Banco 0, accesible con PCLATH=0x00

COMPL_TB1

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto COMPL_TBx_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x767 ;Estamos en Banco 0, accesible con PCLATH=0x00


MENOSMENOS_TD3

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto MENOSMENOS_TDx_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x769 ;Estamos en Banco 0, accesible con PCLATH=0x00

MENOSMENOS_TD4

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto MENOSMENOS_TDx_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x76B ;Estamos en Banco 0, accesible con PCLATH=0x00

MENOSMENOS_TD5

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto MENOSMENOS_TDx_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x76D ;Estamos en Banco 0, accesible con PCLATH=0x00

MENOSMENOS_TD6

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto MENOSMENOS_TDx_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x76F ;Estamos en Banco 0, accesible con PCLATH=0x00

MENOSMENOS_TD7

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto MENOSMENOS_TDx_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x771 ;Estamos en Banco 0, accesible con PCLATH=0x00

MENOSMENOS_TD8

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto MENOSMENOS_TDx_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


ORG 0x773 ;Estamos en Banco 0, accesible con PCLATH=0x00

;MENOSMENOS_TD9

; bsf PCLATH,3 ;Nos vamos a la página FLASH 1

; goto default

fREFLCD

bsf PCLATH,4 ;Nos vamos a la página FLASH 2

goto Pg2_fREFLCD_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x775 ;Estamos en Banco 0, accesible con PCLATH=0x00

MASMAS_TD3

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto MASMAS_TDx_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x777 ;Estamos en Banco 0, accesible con PCLATH=0x00

MASMAS_TD4

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto MASMAS_TDx_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x779 ;Estamos en Banco 0, accesible con PCLATH=0x00

MASMAS_TD5

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto MASMAS_TDx_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x77B ;Estamos en Banco 0, accesible con PCLATH=0x00

MASMAS_TD6

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto MASMAS_TDx_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


ORG 0x77D ;Estamos en Banco 0, accesible con PCLATH=0x00

MASMAS_TD7

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto MASMAS_TDx_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x77F ;Estamos en Banco 0, accesible con PCLATH=0x00

MASMAS_TD8

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto MASMAS_TDx_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x781 ;Estamos en Banco 0, accesible con PCLATH=0x00

;MASMAS_TD9

; bsf PCLATH,3 ;Nos vamos a la página FLASH 1

; goto MASMAS_TDx_SO

fTDN

bsf PCLATH,4 ;Nos vamos a la página FLASH 2

goto Pg2_fTDN_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x783 ;Estamos en Banco 0, accesible con PCLATH=0x00

SUMA_TD3

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto SUMA_TB1_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x785 ;Estamos en Banco 0, accesible con PCLATH=0x00

SUMA_TD4

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto SUMA_TB1_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


ORG 0x787 ;Estamos en Banco 0, accesible con PCLATH=0x00

SUMA_TD5

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto SUMA_TB1_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x789 ;Estamos en Banco 0, accesible con PCLATH=0x00

SUMA_TD6

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto SUMA_TB1_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x78B ;Estamos en Banco 0, accesible con PCLATH=0x00

SUMA_TD7

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto SUMA_TB1_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x78D ;Estamos en Banco 0, accesible con PCLATH=0x00

SUMA_TD8

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto SUMA_TB1_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x78F ;Estamos en Banco 0, accesible con PCLATH=0x00

;SUMA_TD9

; bsf PCLATH,3 ;Nos vamos a la página FLASH 1

; goto default

fTUP

bsf PCLATH,4 ;Nos vamos a la página FLASH 2

goto Pg2_fTUP_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


ORG 0x791 ;Estamos en Banco 0, accesible con PCLATH=0x00

RESTA_TD3

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto RESTA_TB1_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x793 ;Estamos en Banco 0, accesible con PCLATH=0x00

RESTA_TD4

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto RESTA_TB1_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x795 ;Estamos en Banco 0, accesible con PCLATH=0x00

RESTA_TD5

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto RESTA_TB1_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x797 ;Estamos en Banco 0, accesible con PCLATH=0x00

RESTA_TD6

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto RESTA_TB1_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x799 ;Estamos en Banco 0, accesible con PCLATH=0x00

RESTA_TD7

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto RESTA_TB1_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x79B ;Estamos en Banco 0, accesible con PCLATH=0x00

RESTA_TD8

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto RESTA_TB1_SO
;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x79D ;Estamos en Banco 0, accesible con PCLATH=0x00

;RESTA_TD9

; bsf PCLATH,3 ;Nos vamos a la página FLASH 1

; goto default

fTOFF

bsf PCLATH,4 ;Nos vamos a la página FLASH 2

goto Pg2_fTOFF_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x79F ;Estamos en Banco 0, accesible con PCLATH=0x00

CMP_TD3

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto fCMP_INT8U_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x7A1 ;Estamos en Banco 0, accesible con PCLATH=0x00

CMP_TD4

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto fCMP_INT8S_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x7A3 ;Estamos en Banco 0, accesible con PCLATH=0x00

CMP_TD5

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto fCMP_INT16U_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x7A5 ;Estamos en Banco 0, accesible con PCLATH=0x00

CMP_TD6

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto fCMP_INT16S_SO
;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x7A7 ;Estamos en Banco 0, accesible con PCLATH=0x00

CMP_TD7

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto fCMP_INT32U_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x7A9 ;Estamos en Banco 0, accesible con PCLATH=0x00

CMP_TD8

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto fCMP_INT32S_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x7AB ;Estamos en Banco 0, accesible con PCLATH=0x00

;CMP_TD9

fTON

bsf PCLATH,4 ;Nos vamos a la página FLASH 2

goto Pg2_fTON_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x7AD ;Estamos en Banco 0, accesible con PCLATH=0x00

EQ_TB4

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto fEQUAL_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x7AF ;Estamos en Banco 0, accesible con PCLATH=0x00

EQ_TB2

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto fEQUAL_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x7B1 ;Estamos en Banco 0, accesible con PCLATH=0x00


EQ_TB1

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto fEQUAL_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x7B3 ;Estamos en Banco 0, accesible con PCLATH=0x00

XOR_TB4

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto XOR_TBx_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x7B5 ;Estamos en Banco 0, accesible con PCLATH=0x00

XOR_TB2

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto XOR_TBx_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x7B7 ;Estamos en Banco 0, accesible con PCLATH=0x00

XOR_TB1

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto XOR_TBx_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x7B9 ;Estamos en Banco 0, accesible con PCLATH=0x00

OR_TB4

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto OR_TB4_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x7BB ;Estamos en Banco 0, accesible con PCLATH=0x00

OR_TB2

bsf PCLATH,3 ;Nos vamos a la página FLASH 1


goto OR_TB2_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x7BD ;Estamos en Banco 0, accesible con PCLATH=0x00

OR_TB1

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto OR_TB1_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x7BF ;Estamos en Banco 0, accesible con PCLATH=0x00

AND_TB4

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto AND_TBx_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x7C1 ;Estamos en Banco 0, accesible con PCLATH=0x00

AND_TB2

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto AND_TBx_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x7C3 ;Estamos en Banco 0, accesible con PCLATH=0x00

AND_TB1

bsf PCLATH,3 ;Nos vamos a la página FLASH 1

goto AND_TBx_SO

;;Primitiva del S.O.;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ORG 0x7C5 ;Estamos en Banco 0, accesible con PCLATH=0x00

CierraO
clrf STATUS ;Necesario porque vamos a acceder a
B0:LOCAL_O

movf PILA_LOGICA,W

andwf PILA_LOGICA_NIVEL,W

movwf LOCAL_0

bcf STATUS,C

rrf LOCAL_0,W

iorwf PILA_LOGICA,F

bcf STATUS,C

rrf PILA_LOGICA_NIVEL,F

;Ahora tenemos que actualizar 0x7A,1

movf PILA_LOGICA_NIVEL,W

andwf PILA_LOGICA,W

bcf ESTADO_LOGICO_PARA_OL

btfss STATUS,Z

bsf ESTADO_LOGICO_PARA_OL

return

ORG 0x7D5 ;Estamos en Banco 0, accesible con


PCLATH=0x00

CierraU

clrf STATUS ;Necesario porque vamos a acceder a


B0:LOCAL_O

comf PILA_LOGICA_NIVEL,W

iorwf PILA_LOGICA,W

movwf LOCAL_0

bsf STATUS,C

rrf LOCAL_0,W

andwf PILA_LOGICA,F

bcf STATUS,C
rrf PILA_LOGICA_NIVEL,F

;Ahora tenemos que actualizar 0x7A,1

movf PILA_LOGICA_NIVEL,W

andwf PILA_LOGICA,W

bcf ESTADO_LOGICO_PARA_OL

btfss STATUS,Z

bsf ESTADO_LOGICO_PARA_OL

return

ORG 0x7E4 ;Estamos en Banco 0, accesible con


PCLATH=0x00

AbreU

AbreO

bcf STATUS,C

rlf PILA_LOGICA_NIVEL,F

movf PILA_LOGICA_NIVEL,W

iorwf PILA_LOGICA,F

return

ORG 0x7E9 ;Estamos en Banco 0, accesible con


PCLATH=0x00

;Aqui estamos en el banco que haya seleccionado el codigo compilado desde PC

movf PILA_LOGICA_NIVEL,W ;Obtenemos el complemento del indicador de nivel

btfss ESTADO_LOGICO_DE_OL

andlw 0x00 ;Hacemos un AND

iorwf PILA_LOGICA,F ;Hacemos un AND con la pila lógica. y YA ESTÁ

;Ahora tenemos que actualizar 0x7A,1

movf PILA_LOGICA_NIVEL,W
andwf PILA_LOGICA,W

bcf ESTADO_LOGICO_PARA_OL

btfss STATUS,Z

bsf ESTADO_LOGICO_PARA_OL

return

ORG 0x7F3 ;Estamos en Banco 0, accesible con


PCLATH=0x00

MasMasB

movwf FSR

incf INDF,F

return

ORG 0x7F6 ;Estamos en Banco 0, accesible con


PCLATH=0x00

;Aqui estamos en el banco que haya seleccionado el codigo compilado desde PC

comf PILA_LOGICA_NIVEL,W ;Obtenemos el complemento del indicador de nivel

btfsc ESTADO_LOGICO_DE_OL

iorlw 0xFF ;Hacemos un OR

andwf PILA_LOGICA,F ;Hacemos un AND con la pila lógica. y YA ESTÁ

;Ahora tenemos que actualizar 0x7A,1

movf PILA_LOGICA_NIVEL,W

andwf PILA_LOGICA,W

bcf ESTADO_LOGICO_PARA_OL

btfss STATUS,Z

bsf ESTADO_LOGICO_PARA_OL

return
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++

;++++primitivas del S.O.+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++

ORG 0x800 ;(Página 1 de código)

;FSR se utiliza como puntero para acceder a la RD, hay que asegurarse de que

;solo accede en el rango RD0..RD95 que corresponde a B2:0x10 a B2:0x6F

;Utiliza B0:Local_0

;Utiliza B0:Local_1

;Devuelve STATUS,Z==1 (INVALIDO)

;Devuelve STATUS,Z==0 (VALIDO)

;Devuelve en Banco 0 como todas las rutinas

Pg1_EsFSR_unRDValido

sBanco0

movf FSR,W

movwf LOCAL_0

movlw 0x6F ;RD095 es 0x6F en el Banco 2

movwf LOCAL_1

pPagina0

call byte_mayor_que

pPagina1

sBanco0 ;Si FSR es mayor que RD095 entonces


B0:Local_1.0==1

btfsc LOCAL_1,0

goto Pg1_EsFSR_unRDValido_INVALIDO
Pg1_EsFSR_unRDValido_VALIDO

bcf STATUS,Z

return

Pg1_EsFSR_unRDValido_INVALIDO

bsf STATUS,Z

return

LCD_DELAY:

;Hay que usar registros especificos.

sBanco1

clrwdt

movlw .10

movwf B1_LOCAL0_LCD

clrf B1_LOCAL1_LCD

;movwf LOCAL_1

;clrf LOCAL_2

LCD_DELAY_1:

decfsz B1_LOCAL1_LCD,F

goto LCD_DELAY_1

decfsz B1_LOCAL0_LCD,F

goto LCD_DELAY_1

sBanco0

return
Pg1_PedirBusyFlag

sBanco0

bcf B0_LCD_RS

bsf B0_LCD_RW

sBanco1

movlw H'FF'

movwf PORTB ;Puerta B como entrada

sBanco0

bsf B0_LCD_E

sBanco1

bsf B1_bEsperandoBusyFlag

clrf B1_cEsperandoBusyFlag

sBanco0

nop

return

LCD_E

bsf B0_LCD_E

nop

bcf B0_LCD_E

movlw .14

;movwf LOCAL_1

sBanco1

movwf B1_LOCAL1_LCD

LCD_E_1

;decfsz LOCAL_1,F ;Pierde unos 40 uS para la constante de tiempo Tc

decfsz B1_LOCAL1_LCD,F ;Pierde unos 40 uS para la constante de tiempo Tc

goto LCD_E_1 ;de los nuevos módulos LCD de winteck

sBanco0
return

;Enviar siguiente comando/dato al LCD

EnviarSiguienteA_LCD

sBanco1

btfss B1_bEnviandoIniLCD

goto EnviarSiguienteALCD_EndComando

btfsc B1_bIniLCDPaso1

goto IniLCDPaso1

btfsc B1_bIniLCDPaso2

goto IniLCDPaso2

btfsc B1_bIniLCDPaso3

goto IniLCDPaso3

btfsc B1_bIniLCDPaso4

goto IniLCDPaso4

goto EnviarSiguienteALCD_EndComando

IniLCDPaso1

bcf B1_bIniLCDPaso1

bsf B1_bIniLCDPaso2

; movlw 0x38 ;Function SET: Tiene que ser el primero

movlw 0x01 ;Function SET: Tiene que ser el primero

call LCD_CMD

call Pg1_PedirBusyFlag

goto EnviarSiguienteALCD_EndComando

IniLCDPaso2

bcf B1_bIniLCDPaso2

bsf B1_bIniLCDPaso3

movlw 0x0C ;Display ON


call LCD_CMD

call Pg1_PedirBusyFlag

goto EnviarSiguienteALCD_EndComando

IniLCDPaso3

bcf B1_bIniLCDPaso3

bsf B1_bIniLCDPaso4

; movlw 0x01 ;Clear Display

movlw 0x82

call LCD_CMD

call Pg1_PedirBusyFlag

goto EnviarSiguienteALCD_EndComando

IniLCDPaso4

bcf B1_bIniLCDPaso4

bcf B1_bEnviandoIniLCD

bcf B1_bBusyLCD

bsf B1_bIniLCDOK

; movlw 0x06 ;Entry INC

; call LCD_CMD

;movlw '@'

movlw ' '

call LCD_DATA

; call Pg1_PedirBusyFlag

goto EnviarSiguienteALCD_EndComando

EnviarSiguienteALCD_EndComando

sBanco1

btfss B1_bEnviandoDatosLCD

goto EnviarSiguienteALCD_EndDatos
btfss B1_bEnviar1LineaLCD

goto DatosLCDEnviar

DatosLCDLinea1

clrf B1_cCursorLCD

bcf B1_bEnviar1LineaLCD

movlw 0x80

call LCD_CMD

call Pg1_PedirBusyFlag

goto EnviarSiguienteALCD_EndDatos

DatosLCDEnviar

sBanco1

movf B1_cCursorLCD,W

;sublw .40

sublw .32

btfss STATUS,Z

goto cCursorNo40

bsf B1_bDatosLCDOK

bcf B1_bBusyLCD

bcf B1_bEnviandoDatosLCD

goto EnviarSiguienteALCD_EndDatos

cCursorNo40

movf B1_cCursorLCD,W

;sublw .20

sublw .16

btfss STATUS,Z
goto DatosLCDEnviarBuffer

btfss B1_bEnviar2LineaLCD

goto DatosLCDEnviarBuffer

Enviar2LineaLCDSi

bcf B1_bEnviar2LineaLCD

movlw 0xA8

call LCD_CMD

call Pg1_PedirBusyFlag

goto EnviarSiguienteALCD_EndDatos

DatosLCDEnviarBuffer

;Ojo: Estamos en ISR, tenemos que salvaguardar FSR, NO porque ya lo hacemos al

;principio y al final.

sBanco1

bcf STATUS,IRP ;Direccionamiento indirecto en Banco1

movf B1_cCursorLCD,W

;Le tenemos que sumar el origen del buffer y un or para ir al banco 1

addlw B1_IniBufferLCD

iorlw 0x80

movwf FSR

movf INDF,W

call LCD_DATA

sBanco1

incf B1_cCursorLCD,F

call Pg1_PedirBusyFlag

EnviarSiguienteALCD_EndDatos

EnviarSiguienteALCD_End
sBanco0

return

;Ordena al SO el refresco del LCD

Pg1_Refresh_LCD

sBanco3

btfss bConfigLCD

goto Pg1_Refresh_LCD_End

sBanco1

btfsc B1_bBusyLCD

goto Pg1_Refresh_LCD_End

bsf B1_bBusyLCD

bsf B1_bEnviandoDatosLCD

call Pg1_PedirBusyFlag

sBanco1

bcf B1_bDatosLCDOK

bcf B1_bErrorLCD

bsf B1_bEnviar1LineaLCD

bsf B1_bEnviar2LineaLCD

Pg1_Refresh_LCD_End

sBanco0

return

LCD_DATA

sBanco1

clrf TRISB

sBanco0
bcf B0_LCD_E

bsf B0_LCD_RS

bcf B0_LCD_RW

;call DarleVueltaAByte

movwf PORTB ;Valor ASCII a sacar por portb

bsf B0_LCD_RS

;ON_COMANDO ;Activa RS (modo dato).

goto LCD_E ;Genera pulso de E

LCD_CMD

sBanco1

clrf TRISB

sBanco0

bcf B0_LCD_E

bcf B0_LCD_RS

bcf B0_LCD_RW

;call DarleVueltaAByte

movwf PORTB ;Código de comando.

bcf B0_LCD_RS

goto LCD_E ;SI.Genera pulso de E.

Inicializa_LCD_

sBanco1

btfss B1_bEnviarIniLCD

goto Inicializa_LCD_End

bsf B1_bBusyLCD
bcf B1_bErrorLCD

bcf B1_bIniLCDOK

bcf B1_bEnviarIniLCD

bcf B1_bEnviandoDatosLCD

call IniLCDPaso0

call Pg1_PedirBusyFlag

sBanco1

bsf B1_bEnviandoIniLCD

bsf B1_bIniLCDPaso1

Inicializa_LCD_End

sBanco0

return

;;;;;;;;Rutina de inicialización del LCD (Primera parte de inicialización del LCD

IniLCDPaso0

movlw .3

sBanco1

movwf B1_LOCAL1_LCD

IniLCDPaso0_Loop

sBanco1

clrf PORTB ;PORTB como salidas

sBanco0

bcf B0_LCD_E

bcf B0_LCD_RS

bcf B0_LCD_RW
movlw 0x38

;call DarleVueltaAByte

movwf PORTB

;Hay que transferir al LCD

bsf B0_LCD_E

nop

nop

nop

nop

bcf B0_LCD_E

nop

nop

nop

nop

sBanco1

clrf B1_cDelayIniLCD

bsf B1_bDelayIniLCD ;El TMR1 lo incrementará cada mseg

IniLCDPaso0_Espera

movf B1_cDelayIniLCD,W

sublw .10 ;Retardo de 10 mseg

btfsc STATUS,C

goto IniLCDPaso0_Espera

bcf B1_bDelayIniLCD ;El TMR1 lo incrementará cada mseg

decfsz B1_LOCAL1_LCD,F

goto IniLCDPaso0_Loop

sBanco0
return

ActivaAD

call Espera

call Espera

call Espera

call Espera

call Espera

bsf ADCON0,2

return

Espera

nop

nop

nop

nop

nop

nop

nop

nop

nop

nop

return

;
*************************************************************************************
****

;* EntradasSalidas
;
*************************************************************************************
****

Pg1_EntradasSalidas

;Vamos a Realizar la actualización de Entradas/Salidas

sBanco0

movf PORTA,W

movwf COMUN_PORT_A

movf PORTB,W

movwf COMUN_PORT_B

movf PORTC,W

movwf COMUN_PORT_C

sBanco3

;;PIN2 como digital

btfsc bConfig_1_EA ;A 1 tenemos configurada Analog Input

goto P2_Salir

btfsc bConfig_3_EA ;A 1 tenemos configurada Analog Input

goto P2_Salir

btfsc bConfig_5_EA ;A 1 tenemos configurada Analog Input

goto P2_Salir

P2_ComoDIO2

btfss P2_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

goto P2_ComoDO

P2_ComoDI

bsf P2_Valor

btfss COMUN_PORT_A,0

bcf P2_Valor
goto P2_Salir

P2_ComoDO

bsf COMUN_PORT_A,0

btfss P2_Valor

bcf COMUN_PORT_A,0

;;Esto no hay mas remedio que hacerlo asi

sBanco0

btfss COMUN_PORT_A,0

goto PORTA0_a0

PORTA0_a1

bsf PORTA,0

goto PORTA0_end

PORTA0_a0

bcf PORTA,0

PORTA0_end

P2_Salir

;;PIN3 como digital

sBanco3

btfsc bConfig_3_EA ;A 1 tenemos configurada Analog Input

goto P3_Salir

btfsc bConfig_5_EA ;A 1 tenemos configurada Analog Input

goto P3_Salir

P3_ComoDIO3

btfss P3_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

goto P3_ComoDO

P3_ComoDI

bsf P3_Valor
btfss COMUN_PORT_A,1

bcf P3_Valor

goto P3_Salir

P3_ComoDO

bsf COMUN_PORT_A,1

btfss P3_Valor

bcf COMUN_PORT_A,1

;;Esto no hay mas remedio que hacerlo asi

sBanco0

btfss COMUN_PORT_A,1

goto PORTA1_a0

PORTA1_a1

bsf PORTA,1

goto PORTA1_end

PORTA1_a0

bcf PORTA,1

PORTA1_end

P3_Salir

;;PIN4 como digital

sBanco3

btfsc bConfig_5_EA ;A 1 tenemos configurada Analog Input

goto P4_Salir

P4_ComoDIO4

btfss P4_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

goto P4_ComoDO

P4_ComoDI

bsf P4_Valor
btfss COMUN_PORT_A,2

bcf P4_Valor

goto P4_Salir

P4_ComoDO

bsf COMUN_PORT_A,2

btfss P4_Valor

bcf COMUN_PORT_A,2

;;Esto no hay mas remedio que hacerlo asi

sBanco0

btfss COMUN_PORT_A,2

goto PORTA2_a0

PORTA2_a1

bsf PORTA,2

goto PORTA2_end

PORTA2_a0

bcf PORTA,2

PORTA2_end

P4_Salir

;;PIN5 como digital

sBanco3

btfsc bConfig_3_EA ;A 1 tenemos configurada Analog Input

goto P5_Salir

btfsc bConfig_5_EA ;A 1 tenemos configurada Analog Input

goto P5_Salir

P5_ComoDIO5

btfss P5_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

goto P5_ComoDO
P5_ComoDI

bsf P5_Valor

btfss COMUN_PORT_A,3

bcf P5_Valor

goto P5_Salir

P5_ComoDO

bsf COMUN_PORT_A,3

btfss P5_Valor

bcf COMUN_PORT_A,3

;;Esto no hay mas remedio que hacerlo asi

sBanco0

btfss COMUN_PORT_A,3

goto PORTA3_a0

PORTA3_a1

bsf PORTA,3

goto PORTA3_end

PORTA3_a0

bcf PORTA,3

PORTA3_end

P5_Salir

;;PIN6 como digital

sBanco3

btfss P6_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

goto P6_ComoDO

P6_ComoDI

bsf P6_Valor

btfss COMUN_PORT_A,4
bcf P6_Valor

goto P6_Salir

P6_ComoDO

bsf COMUN_PORT_A,4

btfss P6_Valor

bcf COMUN_PORT_A,4

;;Esto no hay mas remedio que hacerlo asi

sBanco0

btfss COMUN_PORT_A,4

goto PORTA4_a0

PORTA4_a1

bsf PORTA,4

goto PORTA4_end

PORTA4_a0

bcf PORTA,4

PORTA4_end

P6_Salir

;;PIN7 como digital

sBanco3

;Corrección del BUG_1 (Begin)

;btfsc bConfig_3_EA ;A 1 tenemos configurada Analog Input

;goto P7_Salir

;Corrección del BUG_1 (Begin)

btfsc bConfig_5_EA ;A 1 tenemos configurada Analog Input

goto P7_Salir

P7_ComoDIO7

btfss P7_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input


goto P7_ComoDO

P7_ComoDI

bsf P7_Valor

btfss COMUN_PORT_A,5

bcf P7_Valor

goto P7_Salir

P7_ComoDO

bsf COMUN_PORT_A,5

btfss P7_Valor

bcf COMUN_PORT_A,5

;;Esto no hay mas remedio que hacerlo asi

sBanco0

btfss COMUN_PORT_A,5

goto PORTA5_a0

PORTA5_a1

bsf PORTA,5

goto PORTA5_end

PORTA5_a0

bcf PORTA,5

PORTA5_end

P7_Salir

;;PIN11 como digital

sBanco3

btfss P11_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

goto P11_ComoDO

P11_ComoDI

bsf P11_Valor
btfss COMUN_PORT_C,0

bcf P11_Valor

goto P11_Salir

P11_ComoDO

bsf COMUN_PORT_C,0

btfss P11_Valor

bcf COMUN_PORT_C,0

;;Esto no hay mas remedio que hacerlo asi

sBanco0

btfss COMUN_PORT_C,0

goto PORTC0_a0

PORTC0_a1

bsf PORTC,0

goto PORTC0_end

PORTC0_a0

bcf PORTC,0

PORTC0_end

P11_Salir

;;PIN12 como digital

sBanco3

btfsc bConfigLCD ;A 1 tenemos configurada LCD

goto P12_Salir

btfss P12_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

goto P12_ComoDO

P12_ComoDI

bsf P12_Valor

btfss COMUN_PORT_C,1
bcf P12_Valor

goto P12_Salir

P12_ComoDO

bsf COMUN_PORT_C,1

btfss P12_Valor

bcf COMUN_PORT_C,1

;;Esto no hay mas remedio que hacerlo asi

sBanco0

btfss COMUN_PORT_C,1

goto PORTC1_a0

PORTC1_a1

bsf PORTC,1

goto PORTC1_end

PORTC1_a0

bcf PORTC,1

PORTC1_end

P12_Salir

;;PIN13 como digital

sBanco3

btfsc bConfigLCD ;A 1 tenemos configurada LCD

goto P13_Salir

btfss P13_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

goto P13_ComoDO

P13_ComoDI

bsf P13_Valor

btfss COMUN_PORT_C,2

bcf P13_Valor
goto P13_Salir

P13_ComoDO

bsf COMUN_PORT_C,2

btfss P13_Valor

bcf COMUN_PORT_C,2

;;Esto no hay mas remedio que hacerlo asi

sBanco0

btfss COMUN_PORT_C,2

goto PORTC2_a0

PORTC2_a1

bsf PORTC,2

goto PORTC2_end

PORTC2_a0

bcf PORTC,2

PORTC2_end

P13_Salir

;;PIN14 como digital

sBanco3

btfsc bConfigI2C ;A 1 tenemos configurada i2c

goto P14_Salir

P14_ComoDIO14

btfss P14_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

goto P14_ComoDO

P14_ComoDI

bsf P14_Valor

btfss COMUN_PORT_C,3

bcf P14_Valor
goto P14_Salir

P14_ComoDO

bsf COMUN_PORT_C,3

btfss P14_Valor

bcf COMUN_PORT_C,3

;;Esto no hay mas remedio que hacerlo asi

sBanco0

btfss COMUN_PORT_C,3

goto PORTC3_a0

PORTC3_a1

bsf PORTC,3

goto PORTC3_end

PORTC3_a0

bcf PORTC,3

PORTC3_end

P14_Salir

;;PIN15 como digital

sBanco3

btfsc bConfigI2C ;A 1 tenemos configurada i2c

goto P15_Salir

P15_ComoDIO15

btfss P15_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

goto P15_ComoDO

P15_ComoDI

bsf P15_Valor

btfss COMUN_PORT_C,4

bcf P15_Valor
goto P15_Salir

P15_ComoDO

bsf COMUN_PORT_C,4

btfss P15_Valor

bcf COMUN_PORT_C,4

;;Esto no hay mas remedio que hacerlo asi

sBanco0

btfss COMUN_PORT_C,4

goto PORTC4_a0

PORTC4_a1

bsf PORTC,4

goto PORTC4_end

PORTC4_a0

bcf PORTC,4

PORTC4_end

P15_Salir

;;PIN16 como digital

sBanco3

btfsc bConfigLCD ;A 1 tenemos configurada LCD

goto P16_Salir

btfss P16_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

goto P16_ComoDO

P16_ComoDI

bsf P16_Valor

btfss COMUN_PORT_C,5

bcf P16_Valor

goto P16_Salir
P16_ComoDO

bsf COMUN_PORT_C,5

btfss P16_Valor

bcf COMUN_PORT_C,5

;;Esto no hay mas remedio que hacerlo asi

sBanco0

btfss COMUN_PORT_C,5

goto PORTC5_a0

PORTC5_a1

bsf PORTC,5

goto PORTC5_end

PORTC5_a0

bcf PORTC,5

PORTC5_end

P16_Salir

;;PIN21 como digital

sBanco3

btfsc bConfigLCD ;A 1 tenemos configurada LCD

goto P21_Salir

P21_ComoDIO21

btfss P21_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

goto P21_ComoDO

P21_ComoDI

bsf P21_Valor

btfss COMUN_PORT_B,0

bcf P21_Valor

goto P21_Salir
P21_ComoDO

bsf COMUN_PORT_B,0

btfss P21_Valor

bcf COMUN_PORT_B,0

;;Esto no hay mas remedio que hacerlo asi

sBanco0

btfss COMUN_PORT_B,0

goto PORTB0_a0

PORTB0_a1

bsf PORTB,0

goto PORTB0_end

PORTB0_a0

bcf PORTB,0

PORTB0_end

P21_Salir

;;PIN22 como digital

sBanco3

btfsc bConfigLCD ;A 1 tenemos configurada LCD

goto P22_Salir

P22_ComoDIO22

btfss P22_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

goto P22_ComoDO

P22_ComoDI

bsf P22_Valor

btfss COMUN_PORT_B,1

bcf P22_Valor

goto P22_Salir
P22_ComoDO

bsf COMUN_PORT_B,1

btfss P22_Valor

bcf COMUN_PORT_B,1

;;Esto no hay mas remedio que hacerlo asi

sBanco0

btfss COMUN_PORT_B,1

goto PORTB1_a0

PORTB1_a1

bsf PORTB,1

goto PORTB1_end

PORTB1_a0

bcf PORTB,1

PORTB1_end

P22_Salir

;;PIN23 como digital

sBanco3

btfsc bConfigLCD ;A 1 tenemos configurada LCD

goto P23_Salir

P23_ComoDIO23

btfss P23_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

goto P23_ComoDO

P23_ComoDI

bsf P23_Valor

btfss COMUN_PORT_B,2

bcf P23_Valor

goto P23_Salir
P23_ComoDO

bsf COMUN_PORT_B,2

btfss P23_Valor

bcf COMUN_PORT_B,2

;;Esto no hay mas remedio que hacerlo asi

sBanco0

btfss COMUN_PORT_B,2

goto PORTB2_a0

PORTB2_a1

bsf PORTB,2

goto PORTB2_end

PORTB2_a0

bcf PORTB,2

PORTB2_end

P23_Salir

;;PIN24 como digital

sBanco3

btfsc bConfigLCD ;A 1 tenemos configurada LCD

goto P24_Salir

P24_ComoDIO24

btfss P24_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

goto P24_ComoDO

P24_ComoDI

bsf P24_Valor

btfss COMUN_PORT_B,3

bcf P24_Valor

goto P24_Salir
P24_ComoDO

bsf COMUN_PORT_B,3

btfss P24_Valor

bcf COMUN_PORT_B,3

;;Esto no hay mas remedio que hacerlo asi

sBanco0

btfss COMUN_PORT_B,3

goto PORTB3_a0

PORTB3_a1

bsf PORTB,3

goto PORTB3_end

PORTB3_a0

bcf PORTB,3

PORTB3_end

P24_Salir

;;PIN25 como digital

sBanco3

btfsc bConfigLCD ;A 1 tenemos configurada LCD

goto P25_Salir

P25_ComoDIO25

btfss P25_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

goto P25_ComoDO

P25_ComoDI

bsf P25_Valor

btfss COMUN_PORT_B,4

bcf P25_Valor

goto P25_Salir
P25_ComoDO

bsf COMUN_PORT_B,4

btfss P25_Valor

bcf COMUN_PORT_B,4

;;Esto no hay mas remedio que hacerlo asi

sBanco0

btfss COMUN_PORT_B,4

goto PORTB4_a0

PORTB4_a1

bsf PORTB,4

goto PORTB4_end

PORTB4_a0

bcf PORTB,4

PORTB4_end

P25_Salir

;;PIN26 como digital

sBanco3

btfsc bConfigLCD ;A 1 tenemos configurada LCD

goto P26_Salir

P26_ComoDIO26

btfss P26_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

goto P26_ComoDO

P26_ComoDI

bsf P26_Valor

btfss COMUN_PORT_B,5

bcf P26_Valor

goto P26_Salir
P26_ComoDO

bsf COMUN_PORT_B,5

btfss P26_Valor

bcf COMUN_PORT_B,5

;;Esto no hay mas remedio que hacerlo asi

sBanco0

btfss COMUN_PORT_B,5

goto PORTB5_a0

PORTB5_a1

bsf PORTB,5

goto PORTB5_end

PORTB5_a0

bcf PORTB,5

PORTB5_end

P26_Salir

;;PIN27 como digital

sBanco3

btfsc bConfigLCD ;A 1 tenemos configurada LCD

goto P27_Salir

P27_ComoDIO27

btfss P27_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

goto P27_ComoDO

P27_ComoDI

bsf P27_Valor

btfss COMUN_PORT_B,6

bcf P27_Valor

goto P27_Salir
P27_ComoDO

bsf COMUN_PORT_B,6

btfss P27_Valor

bcf COMUN_PORT_B,6

;;Esto no hay mas remedio que hacerlo asi

sBanco0

btfss COMUN_PORT_B,6

goto PORTB6_a0

PORTB6_a1

bsf PORTB,6

goto PORTB6_end

PORTB6_a0

bcf PORTB,6

PORTB6_end

P27_Salir

;;PIN28 como digital

sBanco3

btfsc bConfigLCD ;A 1 tenemos configurada LCD

goto P28_Salir

P28_ComoDIO28

btfss P28_DI1_DO0 ;A 1 tenemos configurado P2 como Digital Input

goto P28_ComoDO

P28_ComoDI

bsf P28_Valor

btfss COMUN_PORT_B,7

bcf P28_Valor

goto P28_Salir
P28_ComoDO

bsf COMUN_PORT_B,7

btfss P28_Valor

bcf COMUN_PORT_B,7

;;Esto no hay mas remedio que hacerlo asi

sBanco0

btfss COMUN_PORT_B,7

goto PORTB7_a0

PORTB7_a1

bsf PORTB,7

goto PORTB7_end

PORTB7_a0

bcf PORTB,7

PORTB7_end

P28_Salir

;Leemos Entradas Analogicas

LeyendoEA

sBanco3

btfsc bConfig_0_EA ;A 1 tenemos configurada 0 Analog Input

goto LeyendoEA_End

sBanco0

btfsc ADCON0,2

goto LeyendoEA_End

;En el convertidor se ha terminado una AD, El bit GO/DONE (ADCON0,2) esta a 0


call LeoUltimaAD

call OrdenProximoAD

LeyendoEA_End

sBanco0

return

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++

;+ RUTINA: OrdenProximoAD

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++

OrdenProximoAD

sBanco3

btfsc bConfig_0_EA ;A 1 tenemos configurada 0 Analog Input

goto OrdenProximoAD_End

;Si anteriormente no hemos leido ninguna lanzamos la primera

sBanco0

movf AI_EntradaAnalogLeida,W

btfsc STATUS,Z

goto OrdenProximoAD_Launch1AI
OrdenProximoAD_Config1_

sBanco3

btfss bConfig_1_EA ;A 1 tenemos configurada 1 Analog Input

goto OrdenProximoAD_Config3_

goto OrdenProximoAD_Launch1AI

OrdenProximoAD_Config3_

sBanco3

btfss bConfig_3_EA ;A 1 tenemos configurada Analog Input

goto OrdenProximoAD_Config5_

;;;;;

;Esta configurada 3 Entrada Analogica

;;;;;

sBanco0

btfsc AI_EntradaAnalogLeida,0

goto OrdenProximoAD_Launch2AI

btfsc AI_EntradaAnalogLeida,1

goto OrdenProximoAD_Launch4AI

btfsc AI_EntradaAnalogLeida,3

goto OrdenProximoAD_Launch1AI

goto OrdenProximoAD_Launch1AI

OrdenProximoAD_Config5_

sBanco3

btfss bConfig_5_EA ;A 1 tenemos configurada Analog Input

goto OrdenProximoAD_End

;;;;;

;Esta configurada 5 Entrada Analogica

;;;;;
sBanco0

btfsc AI_EntradaAnalogLeida,0

goto OrdenProximoAD_Launch2AI

btfsc AI_EntradaAnalogLeida,1

goto OrdenProximoAD_Launch3AI

btfsc AI_EntradaAnalogLeida,2

goto OrdenProximoAD_Launch4AI

btfsc AI_EntradaAnalogLeida,3

goto OrdenProximoAD_Launch5AI

btfsc AI_EntradaAnalogLeida,4

goto OrdenProximoAD_Launch1AI

OrdenProximoAD_Launch1AI

sBanco0

clrf AI_EntradaAnalogLeida

bsf AI_EntradaAnalogLeida,0

movlw b'10000001' ;Ponemos en marcha el A/D

movwf ADCON0

call ActivaAD

; bsf ADCON0,2 ;Ordenamos lectura.

goto OrdenProximoAD_End

OrdenProximoAD_Launch2AI

sBanco0

clrf AI_EntradaAnalogLeida

bsf AI_EntradaAnalogLeida,1

movlw b'10001001' ;Ponemos en marcha el A/D

movwf ADCON0

call ActivaAD

; bsf ADCON0,2 ;Ordenamos lectura.


goto OrdenProximoAD_End

OrdenProximoAD_Launch3AI

sBanco0

clrf AI_EntradaAnalogLeida

bsf AI_EntradaAnalogLeida,2

movlw b'10010001' ;Ponemos en marcha el A/D

movwf ADCON0

call ActivaAD

; bsf ADCON0,2 ;Ordenamos lectura.

goto OrdenProximoAD_End

OrdenProximoAD_Launch4AI

sBanco0

clrf AI_EntradaAnalogLeida

bsf AI_EntradaAnalogLeida,3

movlw b'10011001' ;Ponemos en marcha el A/D

movwf ADCON0

call ActivaAD

; bsf ADCON0,2 ;Ordenamos lectura.

goto OrdenProximoAD_End

OrdenProximoAD_Launch5AI

sBanco0

clrf AI_EntradaAnalogLeida

bsf AI_EntradaAnalogLeida,4

movlw b'10100001' ;Ponemos en marcha el A/D

movwf ADCON0

call ActivaAD

; bsf ADCON0,2 ;Ordenamos lectura.

goto OrdenProximoAD_End
OrdenProximoAD_End

sBanco0

return

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++

;+ RUTINA: LeoUltimaAD lee del conversor AD y lo guarda en RAM

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++

LeoUltimaAD

;Aqui ya venimos porque ha habido una conversion

sBanco0

movf AI_EntradaAnalogLeida,W

;Si la ultima Analog Input leida es la 0 (Es decir


ninguna)

;no tengo que leer nada del convertidor

btfsc STATUS,Z

return

;Hemos leido una A/D

;¿Cual es?

LeoUltimaAD_EsLa1_

;¿Es la Primera-AI?

btfss AI_EntradaAnalogLeida,0
goto LeoUltimaAD_EsLa2_

;Hemos leido 1ªAI=AI2 lo metemos en su sitio

sBanco0

movf ADRESH,W

sBanco3

movwf ByteAlto1AI

sBanco1

movf ADRESL,W

sBanco3

movwf ByteBajo1AI

goto LeoUltimaAD_End

LeoUltimaAD_EsLa2_

;¿Es la Segunda-AI?

btfss AI_EntradaAnalogLeida,1

goto LeoUltimaAD_EsLa3_

;Hemos leido 2ªAI=AI3 lo metemos en su sitio

sBanco0

movf ADRESH,W

sBanco3

movwf ByteAlto2AI

sBanco1

movf ADRESL,W

sBanco3

movwf ByteBajo2AI

goto LeoUltimaAD_End

LeoUltimaAD_EsLa3_
;¿Es la Tercera-AI?

btfss AI_EntradaAnalogLeida,2

goto LeoUltimaAD_EsLa4_

;Hemos leido 3ªAI=AI4 lo metemos en su sitio

sBanco0

movf ADRESH,W

sBanco3

movwf ByteAlto3AI

sBanco1

movf ADRESL,W

sBanco3

movwf ByteBajo3AI

goto LeoUltimaAD_End

LeoUltimaAD_EsLa4_

;¿Es la Cuarta-AI?

btfss AI_EntradaAnalogLeida,3

goto LeoUltimaAD_EsLa5_

;Hemos leido 4ªAI=AI5 lo metemos en su sitio

sBanco0

movf ADRESH,W

sBanco3

movwf ByteAlto4AI

sBanco1

movf ADRESL,W

sBanco3

movwf ByteBajo4AI

goto LeoUltimaAD_End
LeoUltimaAD_EsLa5_

;¿Es la Quinta-AI?

btfss AI_EntradaAnalogLeida,4

goto LeoUltimaAD_End

;Hemos leido 5ªAI=AI7 lo metemos en su sitio

sBanco0

movf ADRESH,W

sBanco3

movwf ByteAlto5AI

sBanco1

movf ADRESL,W

sBanco3

movwf ByteBajo5AI

LeoUltimaAD_End

sBanco0

return

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++

SetBooleano

;Funcion SetBooleano

;Esta función coge un operando de pseudo-código y pone su valor lógico a 0 ó 1

;Parametros: B0:LOCAL_2, B0:LOCAL_3

;Temporales: B0:LOCAL_0, B0:LOCAL_1, FSR-INDF


;

; Operando I1 Operando I0

; +------------+-------------+

; | 8 bits | 8 bits |

; +------------+-------------+

; B0:LOCAL_2 B0:LOCAL_3

; Ejemplo RD23.4

; +------+------+-------------+

; |4 bits|4 bits| 8 bits |

; +------+------+-------------+

; | | +------+------+

; | | 23

; | 4 (Indica el bit) (El bit mas alto indica a el valor que hay que poner)

; 0 (La memoria RAM volátil del micro)

sBanco0

;Vamos a comprobar en que RD,SD,ED,FD esta

swapf LOCAL_2,W

andlw 0x0F

movwf LOCAL_0 ;0:RD,1:SD,2:ED,3:FD,

btfss STATUS,Z

goto SBool_1 ;Vamos a la siguiente comparacion

goto SBool_EsRD

SBool_1

movlw .1
subwf LOCAL_0,W

btfss STATUS,Z

goto SBool_EsRD ;Por defecto es RD

goto SBool_EsSD

SBool_EsRD

bsf STATUS,IRP ;Selecciona el banco 2-3 en direccionamiento indirecto

movf LOCAL_3,W ;Colocamos la dirección relativa

addlw 0x10 ;Le sumamos 0x10 para que empiece por los registros libres

;del banco 2

; iorlw 0x80 ;Selecciona el banco 1 en direccionamiento indirecto

movwf FSR

goto SBool_Seguir

SBool_EsSD

bcf STATUS,IRP ;Selecciona el banco 0-1 en direccionamiento indirecto

movf LOCAL_3,W ;Colocamos la dirección relativa

addlw 0x74 ;Le sumamos 0x20 para que empiece por los registros libres

;del banco

;iorlw 0x80 ;Selecciona el banco 1 en direccionamiento indirecto

movwf FSR

SBool_Seguir

;Este codigo hay que optimizarlo en una subrutina que use tablas:

;Entrada Salida

;0 0000 0001

;1 0000 0010

;2 0000 0100

;3 0000 1000
;4 0001 0000

;5 0010 0000

;6 0100 0000

;7 1000 0000

movf LOCAL_2,W

andlw 0x07 ;Antes 0x03

movwf LOCAL_0

movlw 0x01

movwf LOCAL_1

movf LOCAL_0,W

btfsc STATUS,Z

goto sb_reg0x63_Completo

sb_reg0x63_NoCompleto

bcf STATUS,C

rlf LOCAL_1,F

decfsz LOCAL_0,F

goto sb_reg0x63_NoCompleto

sb_reg0x63_Completo

;si es el bit 3 en LOCAL_1 tenemos 00001000

btfss LOCAL_2,3

goto SetA0

goto SetA1

SetA0

comf LOCAL_1,W

andwf INDF,F
bcf STATUS,IRP ;Selecciona el banco 2-3 en direccionamiento indirecto

return

SetA1

movf LOCAL_1,W

iorwf INDF,F

bcf STATUS,IRP ;Selecciona el banco 2-3 en direccionamiento indirecto

return

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++

DameByte

;Funcion DameByte

;Esta función coge un operando de pseudo-código y obtiene su valor.

;Parametros:

; En B0:LOCAL_2 Tenemos el tipo de memoria,

; En B0:LOCAL_3 el byte

;Temporales: B0:LOCAL_0, B0:LOCAL_1, FSR-INDF

; Operando I1 Operando I0

; +------------+-------------+

; | 8 bits | 8 bits | Devuelve en W su valor

; +------------+-------------+

; B0:LOCAL_2 B0:LOCAL_3
;

; Ejemplo RD23

; +------+------+-------------+

; |4 bits|4 bits| 8 bits |

; +------+------+-------------+

; | +------+------+

; | |

; | 23

; 0 (La memoria RAM volátil del micro)

sBanco0

;Ahora para pruebas vamos a suponer que todos los operandos estan en zona RD.

bsf STATUS,IRP ;Selecciona el banco 2-3 en direccionamiento indirecto

movf LOCAL_3,W ;Colocamos la dirección relativa

addlw 0x10 ;Le sumamos 0x10 para que empiece por los registros libres

;del banco 2

movwf FSR

movf INDF,W ;Ya tenemos el byte correcto de la palabra en el acumulador.

;Ahora nos queda coger el valor del bit en


concreto.

bcf STATUS,IRP ;Selecciona el banco 2-3 en direccionamiento indirecto

return

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++

SetByte

;Funcion SetByte

;Esta función coge un operando de pseudo-código y pone un valor.

;Parametros:

; En B0:LOCAL_2 Tenemos el tipo de memoria,

; En B0:LOCAL_3 el byte

; En B0:LOCAL_4 el valor

;Temporales: B0:LOCAL_0, B0:LOCAL_1, FSR-INDF

; Operando I1 Operando I0

; +------------+-------------+

; | 8 bits | 8 bits | Devuelve en W su valor

; +------------+-------------+

; B0:LOCAL_2 B0:LOCAL_3

; Ejemplo RD23

; +------+------+-------------+

; |4 bits|4 bits| 8 bits |

; +------+------+-------------+

; | +------+------+

; | |

; | 23

; 0 (La memoria RAM volátil del micro)

bcf STATUS,RP0 ;Banco 0


bcf STATUS,RP1

;Ahora para pruebas vamos a suponer que todos los operandos estan en zona RD.

; bcf STATUS,IRP ;Selecciona el banco 0-1 en direccionamiento indirecto

bsf STATUS,IRP ;Selecciona el banco 2-3 en direccionamiento indirecto

movf LOCAL_3,W ;Colocamos la dirección relativa

addlw 0x10 ;Le sumamos 0x10 para que empiece por los registros libres

;del banco 2

; iorlw 0x80 ;Selecciona el banco 1 en direccionamiento indirecto

movwf FSR

movf LOCAL_4,W

movwf INDF

bcf STATUS,IRP ;Selecciona el banco 2-3 en direccionamiento indirecto

return

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
++

DameBooleano

;Funcion DameBooleano

;Esta función coge un operando de pseudo-código y obtiene su valor lógico 0 ó 1

;
;Parametros: B0:LOCAL_2, B0:LOCAL_3

;Temporales: B0:LOCAL_0, B0:LOCAL_1, FSR-INDF

; Operando I1 Operando I0

; +------------+-------------+

; | 8 bits | 8 bits | Devuelve en W 0x00 o 0xFF

; +------------+-------------+

; B0:LOCAL_2 B0:LOCAL_3

; Ejemplo RD23.4

; +------+------+-------------+

; |4 bits|4 bits| 8 bits |

; +------+------+-------------+

; | | +------+------+

; | | |

; | | 23

; | 4 (Indica el bit) (El bit mas alto indica a 1 que es referencia de bit)

; 0 (La memoria RAM volátil del micro)

sBanco0

;Vamos a comprobar en que RD,SD,ED,FD esta

swapf LOCAL_2,W

andlw 0x0F

movwf LOCAL_0 ;0:RD,1:SD,2:ED,3:FD,

btfss STATUS,Z

goto DBool_1 ;Vamos a la siguiente comparacion

goto DBool_EsRD
DBool_1

movlw .1

subwf LOCAL_0,W

btfss STATUS,Z

goto DBool_EsRD ;Por defecto es RD

goto DBool_EsSD

DBool_EsRD

;Ahora para pruebas vamos a suponer que todos los operandos estan en zona RD.

; bcf STATUS,IRP ;Selecciona el banco 0-1 en direccionamiento indirecto

bsf STATUS,IRP ;Selecciona el banco 2-3 en direccionamiento indirecto

movf LOCAL_3,W ;Colocamos la dirección relativa

addlw 0x10 ;Le sumamos 0x10 para que empiece por los registros libres

;del banco 2

; iorlw 0x80 ;Selecciona el banco 1 en direccionamiento indirecto

movwf FSR

goto DBool_Seguir

DBool_EsSD

;Ahora para pruebas vamos a suponer que todos los operandos estan en zona RD.

bcf STATUS,IRP ;Selecciona el banco 0-1 en direccionamiento indirecto

movf LOCAL_3,W ;Colocamos la dirección relativa

addlw 0x74 ;Le sumamos 0x74 para que vaya a SD

movwf FSR

DBool_Seguir

;Este codigo hay que optimizarlo en una subrutina que use tablas:

;Entrada Salida
;0 0000 0001

;1 0000 0010

;2 0000 0100

;3 0000 1000

;4 0001 0000

;5 0010 0000

;6 0100 0000

;7 1000 0000

movf LOCAL_2,W

andlw 0x07 ;Antes 0x03

movwf LOCAL_0

movlw 0x01

movwf LOCAL_1

movf LOCAL_0,W

btfsc STATUS,Z

goto reg0x63_Completo

reg0x63NoCompleto

bcf STATUS,C

rlf LOCAL_1,F

decfsz LOCAL_0,F

goto reg0x63NoCompleto

reg0x63_Completo

;si es el bit 3 en LOCAL_1 tenemos 00001000

movf INDF,W ;Ya tenemos el byte correcto de la palabra en el acumulador.

;Ahora nos queda coger el valor del bit en concreto.


andwf LOCAL_1,W

;En el acumulador tenemos 0 o 1 según el valor del bit.

bcf STATUS,IRP ;Selecciona el banco 2-3 en direccionamiento indirecto

btfss STATUS,Z

retlw 0xFF

retlw 0x00

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+

;Función: DebemosEjecutar_

;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+

;Esta funcion es muy importante, la llaman las funciones que anteriormente no han

;llamado a PREPARA_OPER

;Evaluamos el flanco que tiene la función y el estado de la pila logica.

;A esta funcion se accede :

;En FlancoNO: Entramos siempre que bPilaLogica es 1

;En FlancoUP: Entramos cuando el estado del flag es 0

;En FlancoDOWN: Entramos cuando el estado del flag es 1

Pg1_DebemosEjecutar_

btfsc bFlancoUP ;Evaluamos el Flanco de Subida

goto Pg1_DebemosEjecutar_Flanco_Up

btfsc bFlancoDOWN ;Evaluamos el Flanco de Bajada


goto Pg1_DebemosEjecutar_Flanco_Down

Pg1_DebemosEjecutar_Flanco_No

Pg1_DebemosEjecutar_Flanco_Up

btfsc bPilaLogica ;Evaluamos si la pila lógica vale 1 ó 0

retlw 0xFF

retlw 0x00

Pg1_DebemosEjecutar_Flanco_Down

btfsc bPilaLogica ;Evaluamos si la pila lógica vale 1 ó 0

retlw 0x00

retlw 0xFF

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

PREPARA_OPER_SO

bcf bRunPrimitSO ;Primero inhabilitamos la ejecución de la función

btfsc bFlancoUP ;Evaluamos el Flanco de Subida

goto Flanco_Up

btfsc bFlancoDOWN ;Evaluamos el Flanco de Bajada

goto Flanco_Down

Flanco_No

Flanco_Up
btfsc bPilaLogica ;Evaluamos si la pila lógica vale 1 ó 0

goto Flanco_End

goto PREPARA_OPER_SO_Salir

Flanco_Down

btfsc bPilaLogica ;Evaluamos si la pila lógica vale 1 ó 0

goto PREPARA_OPER_SO_Salir

Flanco_End

bsf bRunPrimitSO ;Habilitamos la ejecución de la función

sBanco1

;Reg0x70->BARGB

btfsc bBit0Modalidad ;Si la Modalidad es la adecuada traemos el valor apuntado

;por Reg0x70

goto Reg0x70_End

bsf STATUS,IRP ;Seleccionamos Banco 2-3 en direccionamiento indirecto

movf 0x70,W

movwf FSR

btfsc bTamano2B ;Evaluamos el tamaño; ¿Es de 2 Bytes?

goto Reg0x70_Tamano_2B

btfsc bTamano4B ;Evaluamos el tamaño; ¿Es de 4 Bytes?

goto Reg0x70_Tamano_4B

goto Reg0x70_Tamano_1B

Reg0x70_Tamano_4B

movf INDF,W
movwf BARGB3

incf FSR,F

movf INDF,W

movwf BARGB2

incf FSR,F

Reg0x70_Tamano_2B

movf INDF,W

movwf BARGB1

incf FSR,F

Reg0x70_Tamano_1B

movf INDF,W

movwf BARGB0

Reg0x70_End

;Reg0x71->AARGB

btfsc bBit1Modalidad ;Si la Modalidad es la adecuada traemos el valor apuntado

;por Reg0x70

goto Reg0x71_End

bsf STATUS,IRP ;Seleccionamos Banco 2-3 en direccionamiento indirecto

movf 0x71,W

movwf FSR

btfsc bTamano2B ;Evaluamos el tamaño; ¿Es de 2 Bytes?

goto Reg0x71_Tamano_2B

btfsc bTamano4B ;Evaluamos el tamaño; ¿Es de 4 Bytes?

goto Reg0x71_Tamano_4B

goto Reg0x71_Tamano_1B
Reg0x71_Tamano_4B

movf INDF,W

movwf AARGB3

incf FSR,F

movf INDF,W

movwf AARGB2

incf FSR,F

Reg0x71_Tamano_2B

movf INDF,W

movwf AARGB1

incf FSR,F

Reg0x71_Tamano_1B

movf INDF,W

movwf AARGB0

Reg0x71_End

PREPARA_OPER_SO_Salir

goto xxx_TBx_SO_Salir

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

OR_TB4_SO

btfss bRunPrimitSO ;Primero averiguamos si podemos ejecutar la función

goto OR_TB4_SO_Salir
bsf STATUS,RP0 ;Banco 1 en direccionamiento directo

bcf STATUS,RP1

bsf STATUS,IRP ;Banco 2-3 en direccionamiento indirecto

movf 0x72,W

movwf FSR

movf BARGB3,W

iorwf AARGB3,W

movwf INDF

incf FSR,F

movf BARGB2,W

iorwf AARGB2,W

movwf INDF

incf FSR,F

movf BARGB1,W

iorwf AARGB1,W

movwf INDF

incf FSR,F

movf BARGB0,W

iorwf AARGB0,W

movwf INDF
OR_TB4_SO_Salir

goto xxx_TBx_SO_Salir

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

OR_TB2_SO

btfss bRunPrimitSO ;Primero averiguamos si podemos ejecutar la función

goto OR_TB2_SO_Salir

bsf STATUS,RP0 ;Banco 1 en direccionamiento directo

bcf STATUS,RP1

bsf STATUS,IRP ;Banco 2-3 en direccionamiento indirecto

movf 0x72,W

movwf FSR

movf BARGB1,W

iorwf AARGB1,W

movwf INDF

incf FSR,F

movf BARGB0,W

iorwf AARGB0,W

movwf INDF
OR_TB2_SO_Salir

goto xxx_TBx_SO_Salir

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

OR_TB1_SO

btfss bRunPrimitSO ;Primero averiguamos si podemos ejecutar la función

goto OR_TB1_SO_Salir

bsf STATUS,RP0 ;Banco 1 en direccionamiento directo

bcf STATUS,RP1

bsf STATUS,IRP ;Banco 2-3 en direccionamiento indirecto

movf 0x72,W

movwf FSR

movf BARGB0,W

iorwf AARGB0,W

movwf INDF

OR_TB1_SO_Salir

goto xxx_TBx_SO_Salir

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

AND_TBx_SO

btfss bRunPrimitSO ;Primero averiguamos si podemos ejecutar la función

goto xxx_TBx_SO_Salir

bsf STATUS,RP0 ;Banco 1 en direccionamiento directo

bcf STATUS,RP1

bsf STATUS,IRP ;Banco 2-3 en direccionamiento indirecto

movf 0x72,W

movwf FSR

btfsc bTamano2B ;Evaluamos el tamaño; ¿Es de 2 Bytes?

goto AND_TBx_SO_2B

btfsc bTamano4B ;Evaluamos el tamaño; ¿Es de 4 Bytes?

goto AND_TBx_SO_4B

goto AND_TBx_SO_1B

AND_TBx_SO_4B

movf BARGB3,W

andwf AARGB3,W

movwf INDF

incf FSR,F

movf BARGB2,W

andwf AARGB2,W

movwf INDF
incf FSR,F

AND_TBx_SO_2B

movf BARGB1,W

andwf AARGB1,W

movwf INDF

incf FSR,F

AND_TBx_SO_1B

movf BARGB0,W

andwf AARGB0,W

movwf INDF

goto xxx_TBx_SO_Salir

fEQUAL_SO

btfss bRunPrimitSO ;Primero averiguamos si podemos ejecutar la función

goto fEQUAL_SO_Salir

sBanco1

btfsc bTamano2B ;Evaluamos el tamaño; ¿Es de 2 Bytes?

goto fEQUAL_SO_2B

btfsc bTamano4B ;Evaluamos el tamaño; ¿Es de 4 Bytes?

goto fEQUAL_SO_4B

goto fEQUAL_SO_1B

fEQUAL_SO_4B

movf BARGB3,W
subwf AARGB3,W

btfss STATUS,Z

goto fEQUAL_SO_NoSonIguales

movf BARGB2,W

subwf AARGB2,W

btfss STATUS,Z

goto fEQUAL_SO_NoSonIguales

fEQUAL_SO_2B

movf BARGB1,W

subwf AARGB1,W

btfss STATUS,Z

goto fEQUAL_SO_NoSonIguales

fEQUAL_SO_1B

movf BARGB0,W

subwf AARGB0,W

btfss STATUS,Z

goto fEQUAL_SO_NoSonIguales

fEQUAL_SO_SonIguales

bsf Bx_SD_EQ

bcf Bx_SD_NEQ

goto fEQUAL_SO_Salir

fEQUAL_SO_NoSonIguales

bcf Bx_SD_EQ

bsf Bx_SD_NEQ
fEQUAL_SO_Salir

goto xxx_TBx_SO_Salir

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

XOR_TBx_SO

btfss bRunPrimitSO ;Primero averiguamos si podemos ejecutar la función

goto xxx_TBx_SO_Salir

bsf STATUS,RP0 ;Banco 1 en direccionamiento directo

bcf STATUS,RP1

bsf STATUS,IRP ;Banco 2-3 en direccionamiento indirecto

movf 0x72,W

movwf FSR

btfsc bTamano2B ;Evaluamos el tamaño; ¿Es de 2 Bytes?

goto XOR_TBx_SO_2B

btfsc bTamano4B ;Evaluamos el tamaño; ¿Es de 4 Bytes?

goto XOR_TBx_SO_4B

goto XOR_TBx_SO_1B

XOR_TBx_SO_4B

movf BARGB3,W

xorwf AARGB3,W

movwf INDF
incf FSR,F

movf BARGB2,W

xorwf AARGB2,W

movwf INDF

incf FSR,F

XOR_TBx_SO_2B

movf BARGB1,W

xorwf AARGB1,W

movwf INDF

incf FSR,F

XOR_TBx_SO_1B

movf BARGB0,W

xorwf AARGB0,W

movwf INDF

goto xxx_TBx_SO_Salir

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

MENOSMENOS_TDx_SO

call Pg1_DebemosEjecutar_
;Nos devuelve 0xFF en W si debemos ejecutar la
función

;Nos devuelve 0x00 en W si NO debemos


ejecutar la función

andlw 0xFF ;Como retlw no afecta a los bits de STATUS hacemos esto

btfsc STATUS,Z

goto xxx_TBx_SO_Salir

bsf STATUS,IRP ;Banco 2-3 en direccionamiento indirecto

movf 0x70,W

movwf FSR

movlw .1

subwf INDF,F

btfss bTamano2B ;Evaluamos el tamaño; ¿Es de 2 Bytes?

goto MENOSMENOS_TDx_SO_4B

incf FSR,F

btfss STATUS,C

decf INDF,F

goto xxx_TBx_SO_Salir

MENOSMENOS_TDx_SO_4B

btfss bTamano4B ;Evaluamos el tamaño; ¿Es de 2 Bytes?

goto xxx_TBx_SO_Salir

btfsc STATUS,C
goto xxx_TBx_SO_Salir

incf FSR,F

movlw .1

subwf INDF,F

btfsc STATUS,C

goto xxx_TBx_SO_Salir

incf FSR,F

movlw .1

subwf INDF,F

btfsc STATUS,C

goto xxx_TBx_SO_Salir

incf FSR,F

movlw .1

subwf INDF,F

goto xxx_TBx_SO_Salir

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

MASMAS_TDx_SO

call Pg1_DebemosEjecutar_
;Nos devuelve 0xFF en W si debemos ejecutar la
función

;Nos devuelve 0x00 en W si NO debemos


ejecutar la función

andlw 0xFF ;Como retlw no afecta a los bits de STATUS hacemos esto

btfsc STATUS,Z

goto xxx_TBx_SO_Salir

bsf STATUS,IRP ;Banco 2-3 en direccionamiento indirecto

movf 0x70,W

movwf FSR

movf INDF,W

addlw .1

movwf INDF

btfss bTamano2B ;Evaluamos el tamaño; ¿Es de 2 Bytes?

goto MASMAS_TDx_SO_4B

incf FSR,F

btfsc STATUS,C

incf INDF,F

goto xxx_TBx_SO_Salir

MASMAS_TDx_SO_4B

btfss bTamano4B ;Evaluamos el tamaño; ¿Es de 2 Bytes?

goto xxx_TBx_SO_Salir
btfss STATUS,C

goto xxx_TBx_SO_Salir

incf FSR,F

movf INDF,W

addlw .1

movwf INDF

btfss STATUS,C

goto xxx_TBx_SO_Salir

incf FSR,F

movf INDF,W

addlw .1

movwf INDF

btfss STATUS,C

goto xxx_TBx_SO_Salir

incf FSR,F

movf INDF,W

addlw .1

movwf INDF

goto xxx_TBx_SO_Salir

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

COMPL_TBx_SO

call Pg1_DebemosEjecutar_

;Nos devuelve 0xFF en W si debemos ejecutar la


función

;Nos devuelve 0x00 en W si NO debemos


ejecutar la función

andlw 0xFF ;Como retlw no afecta a los bits de STATUS hacemos esto

btfsc STATUS,Z

goto xxx_TBx_SO_Salir

bsf STATUS,IRP ;Banco 2-3 en direccionamiento indirecto

movf 0x70,W

movwf FSR

comf INDF,F

btfss bTamano2B ;Evaluamos el tamaño; ¿Es de 2 Bytes?

goto COMPL_TBx_SO_4B

incf FSR,F

comf INDF,F

goto xxx_TBx_SO_Salir

COMPL_TBx_SO_4B

btfss bTamano4B ;Evaluamos el tamaño; ¿Es de 2 Bytes?

goto xxx_TBx_SO_Salir
incf FSR,F

comf INDF,F

incf FSR,F

comf INDF,F

incf FSR,F

comf INDF,F

goto xxx_TBx_SO_Salir

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ROL_TBx_SO

call Pg1_DebemosEjecutar_

;Nos devuelve 0xFF en W si debemos ejecutar la


función

;Nos devuelve 0x00 en W si NO debemos


ejecutar la función

andlw 0xFF ;Como retlw no afecta a los bits de STATUS hacemos esto

btfsc STATUS,Z

goto xxx_TBx_SO_Salir

bsf STATUS,IRP ;Banco 2-3 en direccionamiento indirecto

movf 0x70,W
movwf FSR

bsf STATUS,C ;;Ponemos el valor del CF en STATUS,C

btfss Bx_SD_CF

bcf STATUS,C

rlf INDF,F ;Llevamos a cabo la rotación a la izquierda del primer


byte

btfss bTamano2B ;Evaluamos el tamaño; ¿Es de 2 Bytes?

goto ROL_TBx_SO_4B

incf FSR,F

rlf INDF,F

goto ROL_TBx_SO_Salir

ROL_TBx_SO_4B

btfss bTamano4B ;Evaluamos el tamaño; ¿Es de 2 Bytes?

goto ROL_TBx_SO_Salir

incf FSR,F

rlf INDF,F

incf FSR,F

rlf INDF,F

incf FSR,F

rlf INDF,F

goto ROL_TBx_SO_Salir
ROL_TBx_SO_Salir

bsf Bx_SD_CF

btfss STATUS,C

bcf Bx_SD_CF

goto xxx_TBx_SO_Salir

;Implementacion de RESET: 01-05-2003 (Begin)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

fRESET_SO

call Pg1_DebemosEjecutar_

;Nos devuelve 0xFF en W si debemos ejecutar la


función

;Nos devuelve 0x00 en W si NO debemos


ejecutar la función

andlw 0xFF ;Como retlw no afecta a los bits de STATUS hacemos esto

btfsc STATUS,Z

goto fRESET_SO_Salir

;A lo que tenemos en INDF tenemos que hacerle un OR con un byte que representa

;el numero de bit que hay que poner a 1

;Ejemplo RESET RD023.2

;En Reg0x70 tendremos la posicion equivalente de 023

;En B1:AARGB0 tendremos el bit que hay que poner a 1, en este caso tendremos
;el valor 2

;Primero tendremos que poner, por ejemplo en AARGB1 el byte con el bit correcto

;para hacer el AND.

sBanco1

movlw .1

movwf AARGB1

movf AARGB0,W

btfsc STATUS,Z

goto fRESET_YaTenemosAARGB1

fResetComienzoAARGB1

bcf STATUS,C

rlf AARGB1,F

decfsz AARGB0,F

goto fResetComienzoAARGB1

fRESET_YaTenemosAARGB1

;Ahora tenemos que hacer un AND de AARGB1 y INDF

comf AARGB1,F

bsf STATUS,IRP ;Banco 2-3 en direccionamiento indirecto

movf 0x70,W

movwf FSR

movf AARGB1,W

andwf INDF,F
fRESET_SO_Salir

goto xxx_TBx_SO_Salir

;Implementacion de RESET: 01-05-2003 (End)

;Implementacion de SET: 01-05-2003 (Begin)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

fSET_SO

call Pg1_DebemosEjecutar_

;Nos devuelve 0xFF en W si debemos ejecutar la


función

;Nos devuelve 0x00 en W si NO debemos


ejecutar la función

andlw 0xFF ;Como retlw no afecta a los bits de STATUS hacemos esto

btfsc STATUS,Z

goto fSET_SO_Salir

;A lo que tenemos en INDF tenemos que hacerle un OR con un byte que representa

;el numero de bit que hay que poner a 1

;Ejemplo SET RD023.2

;En Reg0x70 tendremos la posicion equivalente de 023

;En B1:AARGB0 tendremos el bit que hay que poner a 1, en este caso tendremos

;el valor 2

;Primero tendremos que poner, por ejemplo en AARGB1 el byte con el bit correcto
;para hacer el OR.

sBanco1

movlw .1

movwf AARGB1

movf AARGB0,W

btfsc STATUS,Z

goto fSET_YaTenemosAARGB1

fSetComienzoAARGB1

bcf STATUS,C

rlf AARGB1,F

decfsz AARGB0,F

goto fSetComienzoAARGB1

fSET_YaTenemosAARGB1

;Ahora tenemos que hacer un OR de AARGB1 y INDF

bsf STATUS,IRP ;Banco 2-3 en direccionamiento indirecto

movf 0x70,W

movwf FSR

movf AARGB1,W

iorwf INDF,F

fSET_SO_Salir

goto xxx_TBx_SO_Salir
;Implementacion de SET: 01-05-2003 (End)

;Implementacion de UP: 01-05-2003 (Begin)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

fUP_SO

btfss bPilaLogica ;Evaluamos si la pila lógica vale 1 ó 0

goto fUP_SO_Salir

goto fUP_SO_Seguir

fDOWN_SO

btfsc bPilaLogica ;Evaluamos si la pila lógica vale 1 ó 0

goto fUP_SO_Salir

goto fUP_SO_Seguir

;A lo que tenemos en INDF tenemos que hacerle un OR con un byte que representa

;el numero de bit que hay que poner a 1

;Ejemplo SET RD023.2

;En Reg0x70 tendremos la posicion equivalente de 023

;En B1:AARGB0 tendremos el bit que hay que poner a 1, en este caso tendremos

;el valor 2

;Primero tendremos que poner, por ejemplo en AARGB1 el byte con el bit correcto

;para hacer el OR.

fUP_SO_Seguir

sBanco1
movlw .1

movwf AARGB1

movf AARGB0,W

btfsc STATUS,Z

goto fUP_YaTenemosAARGB1

fUpComienzoAARGB1

bcf STATUS,C

rlf AARGB1,F

decfsz AARGB0,F

goto fUpComienzoAARGB1

fUP_YaTenemosAARGB1

;Ahora tenemos que hacer un OR de AARGB1 y INDF

bsf STATUS,IRP ;Banco 2-3 en direccionamiento indirecto

movf 0x70,W

movwf FSR

movf AARGB1,W

iorwf INDF,F

fUP_SO_Salir

goto xxx_TBx_SO_Salir

;Implementacion de UP: 01-05-2003 (End)


;Implementacion de SETCF: 01-05-2003 (Begin)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

fSETCF_SO

call Pg1_DebemosEjecutar_

;Nos devuelve 0xFF en W si debemos ejecutar la


función

;Nos devuelve 0x00 en W si NO debemos


ejecutar la función

andlw 0xFF ;Como retlw no afecta a los bits de STATUS hacemos esto

btfsc STATUS,Z

goto fSETCF_SO_Salir

bsf Bx_SD_CF

fSETCF_SO_Salir

goto xxx_TBx_SO_Salir

;Implementacion de SETCF: 01-05-2003 (End)

;Implementacion de RESETCF: 01-05-2003 (Begin)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

fRESETCF_SO
call Pg1_DebemosEjecutar_

;Nos devuelve 0xFF en W si debemos ejecutar la


función

;Nos devuelve 0x00 en W si NO debemos


ejecutar la función

andlw 0xFF ;Como retlw no afecta a los bits de STATUS hacemos esto

btfsc STATUS,Z

goto fRESETCF_SO_Salir

bcf Bx_SD_CF

fRESETCF_SO_Salir

goto xxx_TBx_SO_Salir

;Implementacion de RESETCF: 01-05-2003 (End)

;Implementacion de TOGGLE: 01-05-2003 (Begin)

fTOGGLE_SO

call Pg1_DebemosEjecutar_

;Nos devuelve 0xFF en W si debemos ejecutar la


función

;Nos devuelve 0x00 en W si NO debemos


ejecutar la función

andlw 0xFF ;Como retlw no afecta a los bits de STATUS hacemos esto

btfsc STATUS,Z

goto fTOGGLE_SO_Salir

;A lo que tenemos en INDF tenemos que hacerle un XOR con un byte que representa

;el numero de bit que hay que poner a 1


;Ejemplo SET RD023.2

;En Reg0x70 tendremos la posicion equivalente de 023

;En B1:AARGB0 tendremos el bit que hay que poner a 1, en este caso tendremos

;el valor 2

;Primero tendremos que poner, por ejemplo en AARGB1 el byte con el bit correcto

;para hacer el OR.

sBanco1

movlw .1

movwf AARGB1

movf AARGB0,W

btfsc STATUS,Z

goto fTOGGLE_YaTenemosAARGB1

fTOGGLEComienzoAARGB1

bcf STATUS,C

rlf AARGB1,F

decfsz AARGB0,F

goto fTOGGLEComienzoAARGB1

fTOGGLE_YaTenemosAARGB1

;Ahora tenemos que hacer un OR de AARGB1 y INDF

bsf STATUS,IRP ;Banco 2-3 en direccionamiento indirecto

movf 0x70,W

movwf FSR
movf AARGB1,W

xorwf INDF,F

fTOGGLE_SO_Salir

goto xxx_TBx_SO_Salir

;Implementacion de TOGGLE: 01-05-2003 (End)

;Implementacion de MOV: 02-05-2003 (Begin)

fMOV_SO

call Pg1_DebemosEjecutar_

;Nos devuelve 0xFF en W si debemos ejecutar la


función

;Nos devuelve 0x00 en W si NO debemos


ejecutar la función

andlw 0xFF ;Como retlw no afecta a los bits de STATUS hacemos esto

btfsc STATUS,Z

goto fMOV_SO_Salir

bsf STATUS,IRP ;Direccionamiento indirecto en Bancos 2 y 3

movf 0x70,W

movwf FSR

;Utilizamos el mismo registro 0x70 para guardar el valor inicial

movf INDF,W

movwf 0x70

movf 0x71,W

movwf FSR
movf 0x70,W

movwf INDF

fMOV_SO_Salir

goto xxx_TBx_SO_Salir

;Implementacion de MOV: 02-05-2003 (End)

;Implementacion de fCMP_INT8U_SO: 04-05-2003 (Begin)

fCMP_INT8U_SO

btfss bRunPrimitSO ;Primero averiguamos si podemos ejecutar la función

goto fCMP_INT8U_SO_Salir

;******************************************************************************
**************

; Comparación SIN SIGNO de 8 bits.

; Parametro de entrada:

; Banco de Trabajo: Banco 1.

; Operando 1 (8Bits): (BARGB0)

; Operando 2 (8Bits): (AARGB0)

; Banco de Trabajo: Banco Común.

; Resultado (Varios Bits): SD_EQ,SD_NEQ,SD_GT,SD_GE,SD_LT,SD_LE

pPagina2

call Pg2_COMP_U8

pPagina1

fCMP_INT8U_SO_Salir

goto xxx_TBx_SO_Salir

;Implementacion de fCMP_INT8U_SO: 04-05-2003 (End)


;Implementacion de fCMP_INT16U_SO: 05-05-2003 (Begin)

fCMP_INT16U_SO

btfss bRunPrimitSO ;Primero averiguamos si podemos ejecutar la función

goto fCMP_INT16U_SO_Salir

pPagina2

call Pg2_COMP_U16

pPagina1

fCMP_INT16U_SO_Salir

goto xxx_TBx_SO_Salir

;Implementacion de fCMP_INT16U_SO: 05-05-2003 (End)

;Implementacion de fCMP_INT16S_SO: 05-05-2003 (Begin)

fCMP_INT16S_SO

btfss bRunPrimitSO ;Primero averiguamos si podemos ejecutar la función

goto fCMP_INT16S_SO_Salir

pPagina2

call Pg2_COMP_S16

pPagina1

fCMP_INT16S_SO_Salir

goto xxx_TBx_SO_Salir

;Implementacion de fCMP_INT16S_SO: 05-05-2003 (End)


;Implementacion de fCMP_INT32U_SO: 05-05-2003 (Begin)

fCMP_INT32U_SO

btfss bRunPrimitSO ;Primero averiguamos si podemos ejecutar la función

goto fCMP_INT32U_SO_Salir

pPagina2

call Pg2_COMP_U32

pPagina1

fCMP_INT32U_SO_Salir

goto xxx_TBx_SO_Salir

;Implementacion de fCMP_INT32U_SO: 05-05-2003 (End)

;Implementacion de fCMP_INT32S_SO: 05-05-2003 (Begin)

fCMP_INT32S_SO

btfss bRunPrimitSO ;Primero averiguamos si podemos ejecutar la función

goto fCMP_INT32S_SO_Salir

pPagina2

call Pg2_COMP_S32

pPagina1

fCMP_INT32S_SO_Salir

goto xxx_TBx_SO_Salir

;Implementacion de fCMP_INT32S_SO: 05-05-2003 (End)


;Implementacion de fCMP_INT8S_SO: 04-05-2003 (Begin)

fCMP_INT8S_SO

btfss bRunPrimitSO ;Primero averiguamos si podemos ejecutar la función

goto fCMP_INT8S_SO_Salir

;******************************************************************************
**************

; Comparación SIN SIGNO de 8 bits.

; Parametro de entrada:

; Banco de Trabajo: Banco 1.

; Operando 1 (8Bits): (BARGB0)

; Operando 2 (8Bits): (AARGB0)

; Banco de Trabajo: Banco Común.

; Resultado (Varios Bits): SD_EQ,SD_NEQ,SD_GT,SD_GE,SD_LT,SD_LE

pPagina2

call Pg2_COMP_S8

pPagina1

fCMP_INT8S_SO_Salir

goto xxx_TBx_SO_Salir

;Implementacion de fCMP_INT8S_SO: 04-05-2003 (End)

;Implementacion de MOVI: 02-05-2003 (Begin)

fMOVI_SO

call Pg1_DebemosEjecutar_

;Nos devuelve 0xFF en W si debemos ejecutar la


función

;Nos devuelve 0x00 en W si NO debemos


ejecutar la función
andlw 0xFF ;Como retlw no afecta a los bits de STATUS hacemos esto

btfsc STATUS,Z

goto fMOVI_SO_Salir

bsf STATUS,IRP ;Direccionamiento indirecto en Bancos 2 y 3

movf 0x70,W

movwf FSR

movf INDF,W

addlw 0x10

movwf FSR

;Utilizamos el mismo registro 0x70 para guardar el valor inicial

movf INDF,W

movwf 0x70

movf 0x71,W

movwf FSR

movf 0x70,W

movwf INDF

fMOVI_SO_Salir

goto xxx_TBx_SO_Salir

;Implementacion de MOVI: 02-05-2003 (End)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Pg1_MueveResultadosMul_TB2

bsf STATUS,IRP ;Bancos 2 y 3 en direccionamiento indirecto


;Resultado (32Bits): (AARGB0,AARGB1,AARGB2,AARGB3)

movf 0x72,W

movwf FSR

;..............

incf FSR,F

;Comprobamos que lo vamos a poner en un RD correcto

call Pg1_EsFSR_unRDValido;Devolvera Z=1(Invalido) Z=0(Valido)

btfsc STATUS,Z ;que podemos evaluar BTFSS STATUS,Z

goto Pg1_MueveResultadosMul_TB2_Salir

sBanco1

decf FSR,F

movf AARGB3,W

movwf INDF

incf FSR,F

movf AARGB2,W

movwf INDF

movf 0x73,W

movwf FSR

;..............

incf FSR,F

;Comprobamos que lo vamos a poner en un RD correcto

call Pg1_EsFSR_unRDValido;Devolvera Z=1(Invalido) Z=0(Valido)

btfsc STATUS,Z ;que podemos evaluar BTFSS STATUS,Z

goto Pg1_MueveResultadosMul_TB2_Salir

sBanco1
decf FSR,F

movf AARGB1,W

movwf INDF

incf FSR,F

movf AARGB0,W

movwf INDF

Pg1_MueveResultadosMul_TB2_Salir

bcf STATUS,IRP

sBanco0

return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Pg1_MueveResultadosMul_TB1

bsf STATUS,IRP ;Bancos 2 y 3 en direccionamiento indirecto

movf 0x72,W

movwf FSR

;Comprobamos que lo vamos a poner en un RD correcto

call Pg1_EsFSR_unRDValido;Devolvera Z=1(Invalido) Z=0(Valido)

btfsc STATUS,Z ;que podemos evaluar BTFSS STATUS,Z

goto Pg1_MueveResultadosMul_TB1_Salir

sBanco1

movf AARGB1,W

movwf INDF
movf 0x73,W

movwf FSR

;Comprobamos que lo vamos a poner en un RD correcto

call Pg1_EsFSR_unRDValido;Devolvera Z=1(Invalido) Z=0(Valido)

btfsc STATUS,Z ;que podemos evaluar BTFSS STATUS,Z

goto Pg1_MueveResultadosMul_TB1_Salir

sBanco1

movf AARGB0,W

movwf INDF

Pg1_MueveResultadosMul_TB1_Salir

bcf STATUS,IRP

sBanco0

return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

; Division de operandos de 8 bits sin signo. AARGB0/BARGB0=AARGB0 + Resto=REMB0

Pg1_MueveResultadosDiv_TB1

bsf STATUS,IRP ;Bancos 2 y 3 en direccionamiento indirecto

movf 0x72,W

movwf FSR

;Comprobamos que lo vamos a poner en un RD correcto

call Pg1_EsFSR_unRDValido;Devolvera Z=1(Invalido) Z=0(Valido)

btfsc STATUS,Z ;que podemos evaluar BTFSS STATUS,Z

goto Pg1_MueveResultadosDiv_TB1_Salir

sBanco1
movf AARGB0,W

movwf INDF

movf 0x73,W

movwf FSR

;Comprobamos que lo vamos a poner en un RD correcto

call Pg1_EsFSR_unRDValido;Devolvera Z=1(Invalido) Z=0(Valido)

btfsc STATUS,Z ;que podemos evaluar BTFSS STATUS,Z

goto Pg1_MueveResultadosDiv_TB1_Salir

sBanco1

movf REMB0,W

movwf INDF

Pg1_MueveResultadosDiv_TB1_Salir

bcf STATUS,IRP

sBanco0

return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Pg1_MueveResultadosDiv_TB2

bsf STATUS,IRP ;Bancos 2 y 3 en direccionamiento indirecto

;Division de operandos de 16 bits sin signo. (A0,A1)/(B1,B0)=(A0,A1) + (R0,R1)

movf 0x72,W

movwf FSR

;..............

incf FSR,F
;Comprobamos que lo vamos a poner en un RD correcto

call Pg1_EsFSR_unRDValido;Devolvera Z=1(Invalido) Z=0(Valido)

btfsc STATUS,Z ;que podemos evaluar BTFSS STATUS,Z

goto Pg1_MueveResultadosDiv_TB2_Salir

sBanco1

decf FSR,F

movf AARGB1,W

movwf INDF

incf FSR,F

movf AARGB0,W

movwf INDF

movf 0x73,W

movwf FSR

;..............

incf FSR,F

;Comprobamos que lo vamos a poner en un RD correcto

call Pg1_EsFSR_unRDValido;Devolvera Z=1(Invalido) Z=0(Valido)

btfsc STATUS,Z ;que podemos evaluar BTFSS STATUS,Z

goto Pg1_MueveResultadosDiv_TB2_Salir

sBanco1

decf FSR,F

movf REMB1,W

movwf INDF
incf FSR,F

movf REMB0,W

movwf INDF

Pg1_MueveResultadosDiv_TB2_Salir

bcf STATUS,IRP

sBanco0

return

;Implementacion de DIV_INT8U: 04-05-2003 (Begin)

fDIV_INT8U_SO

btfss bRunPrimitSO ;Primero averiguamos si podemos ejecutar la función

goto fDIV_INT8U_SO_Salir

pPagina2

call Pg2_IntercambiaAARGByBARGB

pPagina1

;******************************************************************************
**************

; Division de operandos de 8 bits sin signo. AARGB0/BARGB0=AARGB0 + Resto=REMB0

;Comprobamos si el divisor es 0

sBanco1

movf BARGB0,W

btfss STATUS,Z

goto fDIV_INT8U_SO_DivisorNoNulo

bsf Bx_SD_DIV_BY0
clrf AARGB0

clrf REMB0

goto fDIV_INT8U_SO_Seguir

fDIV_INT8U_SO_DivisorNoNulo

bcf Bx_SD_DIV_BY0

pPagina2

call Pg2_UDIV_8x8

pPagina1

fDIV_INT8U_SO_Seguir

call Pg1_MueveResultadosDiv_TB1

fDIV_INT8U_SO_Salir

goto xxx_TBx_SO_Salir

;Implementacion de DIV_INT8U: 04-05-2003 (End)

;Implementacion de DIV_INT16U: 04-05-2003 (Begin)

fDIV_INT16U_SO

btfss bRunPrimitSO ;Primero averiguamos si podemos ejecutar la función

goto fDIV_INT16U_SO_Salir

pPagina2

call Pg2_IntercambiaAARGByBARGB

pPagina1

;Division de operandos de 16 bits sin signo. (A0,A1)/(B1,B0)=(A0,A1) + (R0,R1)

;Comprobamos si el divisor es 0
sBanco1

movf BARGB0,W

btfss STATUS,Z

goto fDIV_INT16U_SO_DivisorNoNulo

movf BARGB1,W

btfss STATUS,Z

goto fDIV_INT16U_SO_DivisorNoNulo

bsf Bx_SD_DIV_BY0

clrf AARGB0

clrf AARGB1

clrf REMB0

clrf REMB1

goto fDIV_INT16U_SO_Seguir

fDIV_INT16U_SO_DivisorNoNulo

bcf Bx_SD_DIV_BY0

pPagina2

call Pg2_UDIV_16x16

pPagina1

fDIV_INT16U_SO_Seguir

call Pg1_MueveResultadosDiv_TB2

fDIV_INT16U_SO_Salir

goto xxx_TBx_SO_Salir

;Implementacion de DIV_INT16U: 04-05-2003 (End)

;Implementacion de DIV_INT16S: 04-05-2003 (Begin)


fDIV_INT16S_SO

btfss bRunPrimitSO ;Primero averiguamos si podemos ejecutar la función

goto fDIV_INT16S_SO_Salir

pPagina2

call Pg2_IntercambiaAARGByBARGB

pPagina1

;Division de operandos de 16 bits sin signo. (A0,A1)/(B1,B0)=(A0,A1) + (R0,R1)

;Comprobamos si el divisor es 0

sBanco1

movf BARGB0,W

btfss STATUS,Z

goto fDIV_INT16S_SO_DivisorNoNulo

movf BARGB1,W

btfss STATUS,Z

goto fDIV_INT16S_SO_DivisorNoNulo

bsf Bx_SD_DIV_BY0

clrf AARGB0

clrf AARGB1

clrf REMB0

clrf REMB1

goto fDIV_INT16S_SO_Seguir

fDIV_INT16S_SO_DivisorNoNulo

bcf Bx_SD_DIV_BY0

pPagina2

call Pg2_SDIV_16x16
pPagina1

fDIV_INT16S_SO_Seguir

call Pg1_MueveResultadosDiv_TB2

fDIV_INT16S_SO_Salir

goto xxx_TBx_SO_Salir

;Implementacion de DIV_INT16S: 04-05-2003 (End)

;Implementacion de DIV_INT8S: 04-05-2003 (Begin)

fDIV_INT8S_SO

btfss bRunPrimitSO ;Primero averiguamos si podemos ejecutar la función

goto fDIV_INT8S_SO_Salir

pPagina2

call Pg2_IntercambiaAARGByBARGB

pPagina1

;******************************************************************************
**************

; Division de operandos de 8 bits con signo. AARGB0/BARGB0=AARGB0 + Resto=REMB0

;Comprobamos si el divisor es 0

sBanco1

movf BARGB0,W

btfss STATUS,Z

goto fDIV_INT8S_SO_DivisorNoNulo

bsf Bx_SD_DIV_BY0

clrf AARGB0
clrf REMB0

goto fDIV_INT8S_SO_Seguir

fDIV_INT8S_SO_DivisorNoNulo

bcf Bx_SD_DIV_BY0

pPagina2

call Pg2_SDIV_8x8

pPagina1

fDIV_INT8S_SO_Seguir

call Pg1_MueveResultadosDiv_TB1

fDIV_INT8S_SO_Salir

goto xxx_TBx_SO_Salir

;Implementacion de DIV_INT8S: 04-05-2003 (End)

;Implementacion de MUL_INT8U: 03-05-2003 (Begin)

fMUL_INT8U_SO

btfss bRunPrimitSO ;Primero averiguamos si podemos ejecutar la función

goto fMUL_INT8U_SO_Salir

sBanco1

; Multiplicacion de operandos de 8 bits sin signo, resultado en 16 bits.

; Parametro de entrada:

; Banco de Trabajo: Banco 1.

; Operando 1 (8Bits): AARGB0

; Operando 2 (8Bits): BARGB0

; Resultado (16Bits): (AARGB0,AARGB1)


;

pPagina2

call Pg2_UMUL_8x8

pPagina1

bsf STATUS,IRP ;Bancos 2 y 3 en direccionamiento indirecto

call Pg1_MueveResultadosMul_TB1

;Calculo Overflow

sBanco1

bcf Bx_SD_MUL_OVF

movf AARGB0,W

btfss STATUS,Z

bsf Bx_SD_MUL_OVF

fMUL_INT8U_SO_Salir

goto xxx_TBx_SO_Salir

;Implementacion de MUL_INT8U: 03-05-2003 (End)

;Implementacion de MUL_INT8S: 03-05-2003 (Begin)

fMUL_INT8S_SO

btfss bRunPrimitSO ;Primero averiguamos si podemos ejecutar la función

goto fMUL_INT8S_SO_Salir

sBanco1

; Multiplicacion de operandos de 8 bits sin signo, resultado en 16 bits.

; Parametro de entrada:

; Banco de Trabajo: Banco 1.


; Operando 1 (8Bits): AARGB0

; Operando 2 (8Bits): BARGB0

; Resultado (16Bits): (AARGB0,AARGB1)

pPagina2

call Pg2_SMUL_8x8

pPagina1

bsf STATUS,IRP ;Bancos 2 y 3 en direccionamiento indirecto

call Pg1_MueveResultadosMul_TB1

;Calculo Overflow

; sBanco1

; bcf Bx_SD_MUL_OVF

; comf AARGB0,W

; btfss STATUS,Z

; bsf Bx_SD_MUL_OVF

fMUL_INT8S_SO_Salir

goto xxx_TBx_SO_Salir

;Implementacion de MUL_INT8S: 03-05-2003 (End)

;Implementacion de MUL_INT16U: 03-05-2003 (Begin)

fMUL_INT16U_SO

btfss bRunPrimitSO ;Primero averiguamos si podemos ejecutar la función

goto fMUL_INT16U_SO_Salir

sBanco1

; Multiplicacion de operandos de 16 bits sin signo, resultado en 32 bits.


; Parametro de entrada:

; Banco de Trabajo: Banco 1.

; Operando 1 (16Bits): (AARGB0,AARGB1)

; Operando 2 (16Bits): (BARGB0,BARGB1)

; Resultado (32Bits): (AARGB0,AARGB1,AARGB2,AARGB3)

pPagina2

call Pg2_UMUL_16x16

pPagina1

bsf STATUS,IRP ;Bancos 2 y 3 en direccionamiento indirecto

call Pg1_MueveResultadosMul_TB2

;Calculo Overflow

sBanco1

bcf Bx_SD_MUL_OVF

movf AARGB1,W

btfss STATUS,Z

goto fMUL_INT16U_SO_OVF_A1

movf AARGB0,W

btfsc STATUS,Z

goto fMUL_INT16U_SO_Salir

fMUL_INT16U_SO_OVF_A1

bsf Bx_SD_MUL_OVF

fMUL_INT16U_SO_Salir

goto xxx_TBx_SO_Salir

;Implementacion de MUL_INT16U: 04-05-2003 (End)


;Implementacion de MUL_INT16S: 03-05-2003 (Begin)

fMUL_INT16S_SO

btfss bRunPrimitSO ;Primero averiguamos si podemos ejecutar la función

goto fMUL_INT16S_SO_Salir

sBanco1

;******************************************************************************
**************

; Multiplicacion de operandos de 16 bits con signo, resultado en 32 bits.

; Parametro de entrada:

; Banco de Trabajo: Banco 1.

; Operando 1 (16Bits): (AARGB0,AARGB1)

; Operando 2 (16Bits): (BARGB0,BARGB1)

; Resultado (32Bits): (AARGB0,AARGB1,AARGB2,AARGB3)

pPagina2

call Pg2_SMUL_16x16

pPagina1

bsf STATUS,IRP ;Bancos 2 y 3 en direccionamiento indirecto

call Pg1_MueveResultadosMul_TB2

;Calculo Overflow

; sBanco1

; bcf Bx_SD_MUL_OVF

; movf AARGB1,W

; btfss STATUS,Z
; goto fMUL_INT16U_SO_OVF_A1

; movf AARGB0,W

; btfsc STATUS,Z

; goto fMUL_INT16U_SO_Salir

;fMUL_INT16U_SO_OVF_A1

; bsf Bx_SD_MUL_OVF

fMUL_INT16S_SO_Salir

goto xxx_TBx_SO_Salir

;Implementacion de MUL_INT16S: 04-05-2003 (End)

;Implementacion de COPY: 02-05-2003 (End)

fCOPY_SO

btfss bRunPrimitSO ;Primero averiguamos si podemos ejecutar la función

goto fCOPY_SO_Salir

sBanco1

btfsc bTamano2B ;Evaluamos el tamaño; ¿Es de 2 Bytes?

goto fCOPY_SO_2B

btfsc bTamano4B ;Evaluamos el tamaño; ¿Es de 2 Bytes?

goto fCOPY_SO_4B

fCOPY_SO_1B

bsf STATUS,IRP ;Seleccionamos bancos 2 y 3 en direccionamiento


indirecto

movf 0x71,W ;Cuando es un byte se almacena en AARGB0


movwf FSR

movf BARGB0,W

movwf INDF

goto fCOPY_SO_Salir

fCOPY_SO_2B

bsf STATUS,IRP ;Seleccionamos bancos 2 y 3 en direccionamiento


indirecto

movf 0x71,W ;Cuando son 2 bytes se almacena en (AARGB0,AARGB1)

movwf FSR

movf BARGB1,W

movwf INDF

incf FSR,F

movf BARGB0,W

movwf INDF

goto fCOPY_SO_Salir

fCOPY_SO_4B

bsf STATUS,IRP ;Seleccionamos bancos 2 y 3 en direccionamiento


indirecto

movf 0x71,W ;Cuando son 4 bytes se almacena en


(AARGB0,AARGB1,AARGB2,AARGB3)

movwf FSR

movf BARGB3,W

movwf INDF

incf FSR,F

movf BARGB2,W
movwf INDF

incf FSR,F

movf BARGB1,W

movwf INDF

incf FSR,F

movf BARGB0,W

movwf INDF

goto fCOPY_SO_Salir

fCOPY_SO_Salir

goto xxx_TBx_SO_Salir

;Implementacion de COPY: 02-05-2003 (End)

;Implementacion de fPUT_EE: 12-05-2003 (Begin)

fPUT_EE_SO

btfss bRunPrimitSO ;Primero averiguamos si podemos ejecutar la función

goto fPUT_EE_SO_Salir

;Si esta ocupado escribiendo en eeprom nos salimos.

btfss Bx_SD_EE_FREE ;Primero averiguamos si esta libre la escritura en EEPROM

goto fPUT_EE_SO_Salir

;sBanco0

;bcf B0_Pre_SD_EE_FREE

bcf Bx_SD_EE_FREE
;

;Tenemos en (BARGB0) el valor a escribir en la flash si es 1 byte

;Tenemos en (BARGB0,BARGB1) el valor a escribir en la flash si es 2 bytes

;Tenemos en 0x71 la direccion de la memoria EEPROM donde escribir BARGB0 (1 byte)

;Tenemos en 0x71 la direccion de la memoria EEPROM donde escribir BARGB1 (2 byte)

sBanco1

;bsf STATUS,RP0 ;Banco1

btfsc bTamano2B ;Evaluamos el tamaño; ¿Es de 2 Bytes?

goto fPUT_EE_SO_2B

btfsc bTamano4B ;Evaluamos el tamaño; ¿Es de 4 Bytes?

goto fPUT_EE_SO_Salir

fPUT_EE_SO_1B

movf BARGB0,W

bsf STATUS,RP1 ;Vamos a Banco3

movwf B3_PrimerByteEEPROM

clrf B3_SegundoByteEEPROM

movf 0x71,W

movwf B3_DireccionEEPROM

clrf B3_PunteroSigEEPROM

clrf B3_PunteroUltEEPROM

goto fPUT_EE_SO_Lanzar

fPUT_EE_SO_2B
movf BARGB1,W

bsf STATUS,RP1 ;Vamos a Banco3

movwf B3_PrimerByteEEPROM

bcf STATUS,RP1 ;Vamos a Banco1

movf BARGB0,W

bsf STATUS,RP1 ;Vamos a Banco3

movwf B3_SegundoByteEEPROM

movf 0x71,W

movwf B3_DireccionEEPROM

clrf B3_PunteroSigEEPROM

movlw .1

movwf B3_PunteroUltEEPROM

fPUT_EE_SO_Lanzar

;******************************************************************************
**************

;******************************************************************************
**************

; Parametro de entrada:

; B0:LOCAL_0 direccion EEPROM donde escribir

; B0:LOCAL_1 Valor a Escribir

sBanco0

movf 0x71,W

movwf LOCAL_0

sBanco3
movf B3_PrimerByteEEPROM,W

sBanco0

movwf LOCAL_1

; ;Limpiamos el flag de interrupcion de escritura en EEPROM

; bcf PIR2,EEIF

; ;Habilitamos interrupciones de escritura en EEPROM

; bsf STATUS,RP0 ;Banco1

; bsf PIE2,EEIE

bsf Bx_EE_EnMarcha

pPagina0

call Pg0_EscribirEnEEPROM

pPagina1

fPUT_EE_SO_Salir

goto xxx_TBx_SO_Salir

;Implementacion de fPUT_EE: 12-05-2003 (End)

;Implementacion de FILL: 03-05-2003 (Begin)

fFILL_SO

btfss bRunPrimitSO ;Primero averiguamos si podemos ejecutar la función

goto fFILL_SO_Salir

;En BARGB0 tenemos el valor a rellenar desde *(0x71) a *(0x72)

;sBanco1

movf 0x71,W
movwf FSR

;Funcion a usar:

; byte_mayor_que

; Resultado B0:LOCAL_1<0>=1 si LOCAL_0 > LOCAL_1

fFILL_LOOP

;Primero comprobamos si es mayor que RD095

;Comprobamos que lo vamos a poner en un RD correcto

call Pg1_EsFSR_unRDValido;Devolvera Z=1(Invalido) Z=0(Valido)

btfsc STATUS,Z ;que podemos evaluar BTFSS STATUS,Z

goto fFILL_SO_Salir

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;Ahora comprobamos que no hemos llegado todavía a *(0x72)

movf 0x72,W

movwf LOCAL_1

bcf PCLATH,4

bcf PCLATH,3 ;Saltamos a pagina 0 de FLASH

call byte_mayor_que

bsf PCLATH,3 ;Seguimos en pagina 1 de FLASH

sBanco0

;Si FSR es mayor que el tope final entonces


B0:Local_1.0==1

btfsc LOCAL_1,0

goto fFILL_SO_Salir ;Es mayor, terminamos.


;Aqui esta todo bien para hacer el relleno

bsf STATUS,IRP ;Direccionamiento en banco 2y3

sBanco1

movf BARGB0,W

movwf INDF

incf FSR,F

goto fFILL_LOOP

fFILL_SO_Salir

goto xxx_TBx_SO_Salir

;Implementacion de FILL: 03-05-2003 (End)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

ROR_TBx_SO

call Pg1_DebemosEjecutar_

;Nos devuelve 0xFF en W si debemos ejecutar la


función

;Nos devuelve 0x00 en W si NO debemos


ejecutar la función

andlw 0xFF ;Como retlw no afecta a los bits de STATUS hacemos esto

btfsc STATUS,Z

goto xxx_TBx_SO_Salir
bsf STATUS,IRP ;Banco 2-3 en direccionamiento indirecto

movf 0x70,W

movwf FSR

bsf STATUS,C ;;Ponemos el valor del CF en STATUS,C

btfss Bx_SD_CF

bcf STATUS,C

btfsc bTamano2B ;Evaluamos el tamaño; ¿Es de 2 Bytes?

goto ROR_TBx_SO_2B

btfsc bTamano4B ;Evaluamos el tamaño; ¿Es de 2 Bytes?

goto ROR_TBx_SO_4B

ROR_TBx_SO_1B

rrf INDF,F ;Llevamos a cabo la rotación a la izquierda del primer


byte

goto ROR_TBx_SO_Salir

ROR_TBx_SO_2B

incf FSR,F

rrf INDF,F

decf FSR,F

rrf INDF,F

goto ROR_TBx_SO_Salir

ROR_TBx_SO_4B

incf FSR,F

incf FSR,F

incf FSR,F
rrf INDF,F

decf FSR,F

rrf INDF,F

decf FSR,F

rrf INDF,F

decf FSR,F

rrf INDF,F

goto ROR_TBx_SO_Salir

ROR_TBx_SO_Salir

bsf Bx_SD_CF

btfss STATUS,C

bcf Bx_SD_CF

goto xxx_TBx_SO_Salir

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

RESTA_TB1_SO

btfss bRunPrimitSO ;Primero averiguamos si podemos ejecutar la función

goto xxx_TBx_SO_Salir

bsf STATUS,RP0 ;Banco 1 en direccionamiento directo

bcf STATUS,RP1

bsf STATUS,IRP ;Banco 2-3 en direccionamiento indirecto

btfsc bTamano2B ;Evaluamos el tamaño; ¿Es de 2 Bytes?

goto RESTA_TBx_SO_2B

btfsc bTamano4B ;Evaluamos el tamaño; ¿Es de 4 Bytes?


goto RESTA_TBx_SO_4B

goto RESTA_TBx_SO_1B

RESTA_TBx_SO_4B

pPagina2

call Pg2_RESTA_32 ;RESTA_32 trabaja en Banco1 y se lo tenemos que


preparar

pPagina1

movf 0x72,W

movwf FSR

movf BARGB3,W

movwf INDF

incf FSR,F

movf BARGB2,W

movwf INDF

incf FSR,F

movf BARGB1,W

movwf INDF

incf FSR,F

movf BARGB0,W

movwf INDF

goto xxx_TBx_SO_Salir

RESTA_TBx_SO_2B
pPagina2

call Pg2_RESTA_16 ;RESTA_16 trabaja en Banco1 y se lo tenemos que


preparar

pPagina1

movf 0x72,W

movwf FSR

movf BARGB1,W

movwf INDF

incf FSR,F

movf BARGB0,W

movwf INDF

goto xxx_TBx_SO_Salir

RESTA_TBx_SO_1B

movf 0x72,W

movwf FSR

movf AARGB0,W

subwf BARGB0,W

movwf INDF

goto xxx_TBx_SO_Salir

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

SUMA_TB1_SO

btfss bRunPrimitSO ;Primero averiguamos si podemos ejecutar la función

goto xxx_TBx_SO_Salir

bsf STATUS,RP0 ;Banco 1 en direccionamiento directo

bcf STATUS,RP1

bsf STATUS,IRP ;Banco 2-3 en direccionamiento indirecto

btfsc bTamano2B ;Evaluamos el tamaño; ¿Es de 2 Bytes?

goto SUMA_TBx_SO_2B

btfsc bTamano4B ;Evaluamos el tamaño; ¿Es de 4 Bytes?

goto SUMA_TBx_SO_4B

goto SUMA_TBx_SO_1B

SUMA_TBx_SO_4B

pPagina2

call Pg2_SUMA_32 ;SUMA_32 trabaja en Banco1 y se lo tenemos que


preparar

pPagina1

movf 0x72,W

movwf FSR

movf BARGB3,W

movwf INDF

incf FSR,F

movf BARGB2,W
movwf INDF

incf FSR,F

movf BARGB1,W

movwf INDF

incf FSR,F

movf BARGB0,W

movwf INDF

goto xxx_TBx_SO_Salir

SUMA_TBx_SO_2B

pPagina2

call Pg2_SUMA_16 ;SUMA_16 trabaja en Banco1 y se lo tenemos que


preparar

pPagina1

movf 0x72,W

movwf FSR

movf BARGB1,W

movwf INDF

incf FSR,F

movf BARGB0,W

movwf INDF

goto xxx_TBx_SO_Salir

SUMA_TBx_SO_1B

movf 0x72,W
movwf FSR

movf BARGB0,W

addwf AARGB0,W

movwf INDF

goto xxx_TBx_SO_Salir

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

xxx_TBx_SO_Salir

bcf STATUS,IRP ;Banco 0-1 en direccionamiento indirecto

bsf STATUS,RP0 ;Banco 3 en direccionamiento directo

bsf STATUS,RP1

clrf PCLATH

return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

default

goto xxx_TBx_SO_Salir
;
*************************************************************************************
*******

;
*************************************************************************************
*******

;
*************************************************************************************
*******

;
*************************************************************************************
*******

;
*************************************************************************************
*******

ORG 0x1000 ;Comienzo de pagina 2 de FLASH

Pg2_xxx_TBx_SO_Salir

pPagina1

goto xxx_TBx_SO_Salir

;Implementacion de Pg2_Conv16S_32S_SO: 15-05-2003 (Begin)

;Pg2_Conv16S_32S_SO

; pPagina1

; goto xxx_TBx_SO_Salir

;Implementacion de Pg2_Conv16U_32U_SO: 15-05-2003 (End)

;Implementacion de Pg2_Conv16U_32U_SO: 15-05-2003 (Begin)

;Pg2_Conv16U_32U_SO

; pPagina1

; goto xxx_TBx_SO_Salir

;Implementacion de Pg2_Conv16U_32U_SO: 15-05-2003 (End)


;Implementacion de Pg2_Conv8U_16U_SO: 15-05-2003 (Begin)

Pg2_Conv8U_16U_SO

sBanco0

bcf LOCAL_0,0

goto Pg2_Conv8X_16X_SO

;Implementacion de Pg2_Conv8U_16U_SO: 15-05-2003 (End)

;Implementacion de Pg2_Conv8S_16S_SO: 15-05-2003 (Begin)

Pg2_Conv8S_16S_SO

sBanco0

bsf LOCAL_0,0

goto Pg2_Conv8X_16X_SO

;Implementacion de Pg2_Conv8S_16S_SO: 15-05-2003 (End)

;Implementacion de Pg2_Conv8X_16X_SO: 15-05-2003 (Begin)

Pg2_Conv8X_16X_SO

btfss bRunPrimitSO ;Primero averiguamos si podemos ejecutar la función

goto Pg2_Conv8X_16X_SO_Salir

;Tenemos en 0x70 la direccion de la memoria RAM origen

;Tenemos en 0x71 la direccion de la memoria RAM destino

bsf STATUS,IRP

;Tenemos que verificar que 0x71 + 1 es un RD valido

movf 0x71,W

movwf FSR

incf FSR,F
;Primero comprobamos si es mayor que RD095

;Comprobamos que lo vamos a poner en un RD correcto

pPagina1

call Pg1_EsFSR_unRDValido;Devolvera Z=1(Invalido) Z=0(Valido)

pPagina2

btfsc STATUS,Z ;que podemos evaluar BTFSS STATUS,Z

goto Pg2_Conv8X_16X_SO_Salir

decf FSR,F

sBanco0

;Ahora tenemos que copiar *0x70 en *0x71 tal cual.

movf 0x70,W

movwf FSR

movf INDF,W

movwf LOCAL_1

movf 0x71,W

movwf FSR

movf LOCAL_1,W

movwf INDF

incf FSR,F

;Ahora evaluamos el bit alto de LOCAL_0,0, si es 1 es SIGNED

btfss LOCAL_0,0

goto Pg2_Conv8X_16X_SO_UUU

movlw 0xFF

movwf INDF

btfss LOCAL_1,7
Pg2_Conv8X_16X_SO_UUU

clrf INDF

Pg2_Conv8X_16X_SO_Salir

goto Pg2_xxx_TBx_SO_Salir

;Implementacion de Pg2_Conv8X_16X_SO: 15-05-2003 (End)

;Implementacion de fGET_EE: 12-05-2003 (Begin)

Pg2_fGET_EE_SO

btfss bRunPrimitSO ;Primero averiguamos si podemos ejecutar la función

goto Pg2_fGET_EE_SO_Salir

bcf Bx_SD_EE_RDOK

;Si esta ocupado escribiendo en eeprom nos salimos.

btfss Bx_SD_EE_FREE ;Primero averiguamos si esta libre la escritura en EEPROM

goto Pg2_fGET_EE_SO_Salir

;Tenemos en 0x70 la direccion de la memoria EEPROM donde leer

;Tenemos en 0x71 la direccion de la memoria RAM donde escribir

sBanco0

bsf STATUS,IRP ;Direccionamiento Indirecto en Bancos 2 y 3.

btfsc bTamano2B ;Evaluamos el tamaño; ¿Es de 2 Bytes?

goto Pg2_fGET_EE_SO_2B

btfsc bTamano4B ;Evaluamos el tamaño; ¿Es de 4 Bytes?

goto Pg2_fGET_EE_SO_Salir
goto Pg2_fGET_EE_SO_1B

Pg2_fGET_EE_SO_2B

movf 0x71,W

movwf FSR

incf FSR,F

;Primero comprobamos si es mayor que RD095

;Comprobamos que lo vamos a poner en un RD correcto

pPagina1

call Pg1_EsFSR_unRDValido;Devolvera Z=1(Invalido) Z=0(Valido)

pPagina2

btfsc STATUS,Z ;que podemos evaluar BTFSS STATUS,Z

goto Pg2_fGET_EE_SO_Salir

decf FSR,F

;Es valido, entonces leemos.

;******************************************************************************
**************

; Parametro de entrada:

; B0:LOCAL_0 direccion EEPROM donde leer.

; W: Devuelve el valor en el acumulador.

movf 0x70,W

movwf LOCAL_0

pPagina0

call Pg0_LeerDeEEPROM

pPagina1

movwf INDF

incf 0x70,F
incf 0x71,F

Pg2_fGET_EE_SO_1B

movf 0x71,W

movwf FSR

;Primero comprobamos si es mayor que RD095

;Comprobamos que lo vamos a poner en un RD correcto

pPagina1

call Pg1_EsFSR_unRDValido;Devolvera Z=1(Invalido) Z=0(Valido)

pPagina2

btfsc STATUS,Z ;que podemos evaluar BTFSS STATUS,Z

goto Pg2_fGET_EE_SO_Salir

;Es valido, entonces leemos.

;******************************************************************************
**************

; Parametro de entrada:

; B0:LOCAL_0 direccion EEPROM donde leer.

; W: Devuelve el valor en el acumulador.

movf 0x70,W

movwf LOCAL_0

pPagina0

call Pg0_LeerDeEEPROM

pPagina2

movwf INDF

bsf Bx_SD_EE_RDOK

goto Pg2_fGET_EE_SO_Salir
Pg2_fGET_EE_SO_Salir

pPagina1

goto xxx_TBx_SO_Salir

;Implementacion de fGET_EE: 13-05-2003 (End)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Rutina 'Pg2_WEsPunteroLCDValido'

Pg2_WEsPunteroLCDValido

;Chequeamos si W contiene un INT8U [0,31], devuelve en Z (1 valido,0 invalido)

sublw .31

btfss STATUS,C

goto Pg2_WEsPunteroLCDValido_INVALIDO

Pg2_WEsPunteroLCDValido_VALIDO

bsf STATUS,Z

return

Pg2_WEsPunteroLCDValido_INVALIDO

bcf STATUS,Z

return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Rutina 'Pg2_PonPunteroLCD'

Pg2_PonPunteroLCD

;El numero pasado en W lo ponemos como puntero del LCD.

;Hay que comprobar que no sobrepasa la zona de LCD, si la sobrepasa ponemos 0

sBanco1

movwf B1_PunteroLCD

call Pg2_WEsPunteroLCDValido
btfsc STATUS,Z ;Si Z==1 es valido

goto Pg2_PonPunteroLCD_Salir

;Es invalido

clrf B1_PunteroLCD

Pg2_PonPunteroLCD_Salir

return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Rutina 'Pg2_CorrigePunteroLCD'

Pg2_CorrigePunteroLCD

sBanco1

movf B1_PunteroLCD,W

call Pg2_WEsPunteroLCDValido

btfsc STATUS,Z ;Si Z==1 es valido

goto Pg2_CorrigePunteroLCD_Salir

;Es invalido

clrf B1_PunteroLCD

Pg2_CorrigePunteroLCD_Salir

return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Rutina 'Pg2_IncPunteroLCD'

Pg2_IncPunteroLCD

sBanco1

incf B1_PunteroLCD,F

movf B1_PunteroLCD,W

call Pg2_WEsPunteroLCDValido
btfsc STATUS,Z ;Si Z==1 es valido

goto Pg2_IncPunteroLCD_Salir

;Es invalido

clrf B1_PunteroLCD

Pg2_IncPunteroLCD_Salir

return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Rutina 'Pg2_DecPunteroLCD'

Pg2_DecPunteroLCD

sBanco1

decf B1_PunteroLCD,F

movf B1_PunteroLCD,W

call Pg2_WEsPunteroLCDValido

btfsc STATUS,Z ;Si Z==1 es valido

goto Pg2_DecPunteroLCD_Salir

;Es invalido

movlw .31

movwf B1_PunteroLCD

Pg2_DecPunteroLCD_Salir

return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Rutina 'Pg2_Char2LCD'

;Parametros : B0:LOCAL_0 : Caracter

; B0:LOCAL_1 : Numero de veces a mostrar

Pg2_Char2LCD

;Modificado el 10-05-2003, probar!!!


; sBanco0

; movf LOCAL_1,W

; btfss STATUS,Z

; goto Pg2_Char2LCD_End

sBanco1

call Pg2_CorrigePunteroLCD ;Con esto nos aseguramos de que el puntero esta

;dentro de la zona de memoria.

sBanco1

bcf STATUS,IRP ;Direccionamiento indirecto a bancos 0 y


1

movf B1_PunteroLCD,W

addlw B1_IniBufferLCD

iorlw 0x80

movwf FSR

sBanco0

movf LOCAL_0,W

movwf INDF

decfsz LOCAL_1,F

goto Pg2_Char2LCD_SeguirBucle

goto Pg2_Char2LCD_Salir

Pg2_Char2LCD_SeguirBucle

call Pg2_IncPunteroLCD

goto Pg2_Char2LCD

Pg2_Char2LCD_Salir

;Modificado el 10-05-2003, probar!!!

; call Pg2_IncPunteroLCD
;Pg2_Char2LCD_End

return

Pg2_PreparaParametrosParafSTRLCD_SO

sBanco1

;Primero truncamos el inicio (Como mucho 31)

movlw .32

subwf BARGB0,W ;B0 tenemos inicio

btfss STATUS,C

goto Pg2_fCHRLCD_SO_NoTruncarInicio

clrf BARGB0

Pg2_fCHRLCD_SO_NoTruncarInicio

;Primero truncamos el tamaño (Como mucho 32)

movlw .32

subwf AARGB0,W ;A0 tenemos tamaño

btfss STATUS,C

goto Pg2_fCHRLCD_SO_NoTruncarTamano

movlw .32

movwf AARGB0

Pg2_fCHRLCD_SO_NoTruncarTamano

sBanco1

movf BARGB0,W

sBanco0

movwf LOCAL_2 ;Guardamos en LOCAL_2 la posicion de inicio del integer


a escribir,
;por si acaso no cabe y tenemos que poner
******

;Ponemos la posicion final del LCD

sBanco1

movf AARGB0,W ;A0 tenemos tamaño ya truncado

addwf BARGB0,F ;B0 tenemos inicio ya truncado

decf BARGB0,F ;TENEMOS QUE RESTARLE 1

movlw .32

subwf BARGB0,W ;Tenemos que hacer el modulo 32 de la posicion final

btfss STATUS,C

goto Pg2_fCHRLCD_SO_Seguir1

movlw .32

subwf BARGB0,F

Pg2_fCHRLCD_SO_Seguir1

movf BARGB0,W

call Pg2_PonPunteroLCD

sBanco1

movf AARGB0,W

sBanco0

movwf LOCAL_3 ;Guardamos en LOCAL_3 el tamaño del integer a escribir,


por

;si acaso no cabe y tenemos que poner ******

return
;Implementacion de rutinas para fINTxxLCD_SO: 09-05-2003 (Begin)

Pg2_PreparaParametrosParafINTxxLCD_SO

; sBanco1

; ;Primero truncamos el inicio (Como mucho 31)

; movlw .32

; subwf BARGB0,W ;B0 tenemos inicio

; btfss STATUS,C

; goto Pg2_fINTxxLCD_SO_NoTruncarInicio

; clrf BARGB0

;Pg2_fINTxxLCD_SO_NoTruncarInicio

; ;Primero truncamos el tamaño (Como mucho 32)

; movlw .32

; subwf AARGB0,W ;A0 tenemos tamaño

; btfss STATUS,C

; goto Pg2_fINTxxLCD_SO_NoTruncarTamano

; movlw .32

; movwf AARGB0

;Pg2_fINTxxLCD_SO_NoTruncarTamano

; sBanco1

; movf BARGB0,W

; sBanco0

; movwf LOCAL_2 ;Guardamos en LOCAL_2 la posicion de inicio del integer


a escribir,
; ;por si acaso no cabe y tenemos que poner
******

; ;Ponemos la posicion final del LCD

; sBanco1

; movf AARGB0,W ;A0 tenemos tamaño ya truncado

; addwf BARGB0,F ;B0 tenemos inicio ya truncado

; decf BARGB0,F ;TENEMOS QUE RESTARLE 1

; movlw .32

; subwf BARGB0,W ;Tenemos que hacer el modulo 32 de la posicion final

; btfss STATUS,C

; goto Pg2_fINTxxLCD_SO_Seguir1

; movlw .32

; subwf BARGB0,F

;Pg2_fINTxxLCD_SO_Seguir1

; movf BARGB0,W

; call Pg2_PonPunteroLCD

; sBanco1

; movf AARGB0,W

; sBanco0

; movwf LOCAL_3 ;Guardamos en LOCAL_3 el tamaño del integer a escribir,


por

; ;si acaso no cabe y tenemos que poner ******


call Pg2_PreparaParametrosParafSTRLCD_SO

;Cogemos el valor que queremos representar que lo tenemos apuntado por 0x72

sBanco1

bsf STATUS,IRP ;Direccionamiento indirecto en bancos 2 y 3

movf 0x72,W

movwf FSR

btfsc bTamano2B ;Evaluamos el tamaño; ¿Es de 2 Bytes?

goto Pg2_fINTxxLCD_SO_Tamano_2B

btfsc bTamano4B ;Evaluamos el tamaño; ¿Es de 4 Bytes?

goto Pg2_fINTxxLCD_SO_Tamano_4B

goto Pg2_fINTxxLCD_SO_Tamano_1B

Pg2_fINTxxLCD_SO_Tamano_4B

movf INDF,W

movwf AARGB3

incf FSR,F

movf INDF,W

movwf AARGB2

incf FSR,F

Pg2_fINTxxLCD_SO_Tamano_2B

movf INDF,W

movwf AARGB1

incf FSR,F

Pg2_fINTxxLCD_SO_Tamano_1B

movf INDF,W

movwf AARGB0
return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Pg2_fINTxuLCD_SO_RellenamosParaINT

;Aqui tenemos que completar con espacios para limpiar.

sBanco0

movf LOCAL_4,W

subwf LOCAL_3,W ;Comprobamos que cabe en el espacio que nos han dejado

btfsc STATUS,Z

return

;goto Pg2_fINTxuLCD_SO_Salir

btfss STATUS,C

goto PG2_fINTxuLCD_SO_NoCupio

;goto PG2_fINTxuLCD_SO_SiCupio

PG2_fINTxuLCD_SO_SiCupio

;Rellenamos con ' ' lo que queda

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Rutina 'Pg2_Char2LCD'

;Parametros : B0:LOCAL_0 : Caracter

; B0:LOCAL_1 : Numero de veces a mostrar

sBanco0

movf LOCAL_2,W ;Aqui tenemos guardado el origen

call Pg2_PonPunteroLCD

sBanco0

movlw ' '

movwf LOCAL_0

movf LOCAL_4,W

subwf LOCAL_3,W

movwf LOCAL_1
call Pg2_Char2LCD

return

;goto Pg2_fINT8uLCD_SO_Salir

PG2_fINTxuLCD_SO_NoCupio

;Rellenamos con '*' todo el espacio

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Rutina 'Pg2_Char2LCD'

;Parametros : B0:LOCAL_0 : Caracter

; B0:LOCAL_1 : Numero de veces a mostrar

sBanco0

movf LOCAL_2,W ;Aqui tenemos guardado el origen

call Pg2_PonPunteroLCD

sBanco0

movlw '*'

movwf LOCAL_0

movf LOCAL_3,W

movwf LOCAL_1

call Pg2_Char2LCD

return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Pg2_fINTxsLCD_SO_RellenamosParaINT

;Aqui tenemos que completar con espacios para limpiar.

sBanco0

movf LOCAL_4,W

subwf LOCAL_3,W ;Comprobamos que cabe en el espacio que nos han dejado

btfsc STATUS,Z

goto PG2_fINTxuLCD_SO_NoCupio
btfss STATUS,C

goto PG2_fINTxuLCD_SO_NoCupio

PG2_fINTxsLCD_SO_SiCupio

;Rellenamos con ' ' lo que queda

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Rutina 'Pg2_Char2LCD'

;Parametros : B0:LOCAL_0 : Caracter

; B0:LOCAL_1 : Numero de veces a mostrar

sBanco0

movf LOCAL_2,W ;Aqui tenemos guardado el origen

call Pg2_PonPunteroLCD

sBanco0

movlw ' '

movwf LOCAL_0

movf LOCAL_4,W

subwf LOCAL_3,W

movwf LOCAL_1

call Pg2_Char2LCD

movlw '-'

movwf LOCAL_0

PG2_fINTxsLCD_SO_SiCupio_MaMenos

movlw .1

movwf LOCAL_1

call Pg2_Char2LCD

return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Pg2_fINTxxLCD_SO_ImprimeCaracter

;sBanco1

;movf REMB0,W

sBanco0

addlw '0'

movwf LOCAL_0

movlw .1

movwf LOCAL_1

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Rutina 'Pg2_Char2LCD'

;Parametros : B0:LOCAL_0 : Caracter

; B0:LOCAL_1 : Numero de veces a mostrar

call Pg2_Char2LCD

call Pg2_DecPunteroLCD

return

;Implementacion de rutinas para fINTxxLCD_SO: 09-05-2003 (End)

;Implementacion de fINT8uLCD_SO: 07-05-2003 (Begin)

Pg2_fINT8uLCD_SO

btfss bRunPrimitSO ;Primero averiguamos si podemos ejecutar la función

goto Pg2_fINT8uLCD_SO_Salir

call Pg2_PreparaParametrosParafINTxxLCD_SO

;Esta funcion anterior nos dejara en :

;B0:LOCAL_2 Inicio en RAM


;B0:LOCAL_3 Tamaño de RAM a ocupar

;B1:(AARGB0,AARGB1,AARGB2,AARGB3) el numero a mostrar dependiendo del TBytes

;Posicionara el puntero de LCD en la ultima posicion, donde hay que escribir el

;digito menos significativo.

sBanco0

clrf LOCAL_4 ;Ponemos en LOCAL_4 los digitos que estamos poniendo.

movf LOCAL_3,W ;Si es cero el tamaño nos vamos.

btfsc STATUS,Z

goto Pg2_fINT8uLCD_SO_Salir

Pg2_fINT8uLCD_SO_BeginDivisionesPor10

sBanco0

incf LOCAL_4,F

movf LOCAL_4,W

subwf LOCAL_3,W ;Comprobamos que cabe en el espacio que nos han dejado

btfsc STATUS,Z

goto Pg2_fINT8uLCD_SO_SiCabe

btfss STATUS,C

goto Pg2_fINT8uLCD_SO_NoCabe

Pg2_fINT8uLCD_SO_SiCabe

sBanco1

movlw .10

movwf BARGB0

call Pg2_UDIV_8x8
sBanco1

movf REMB0,W

call Pg2_fINTxxLCD_SO_ImprimeCaracter

sBanco1

movf AARGB0,W

btfss STATUS,Z

goto Pg2_fINT8uLCD_SO_BeginDivisionesPor10

Pg2_fINT8uLCD_SO_NoCabe

call Pg2_fINTxuLCD_SO_RellenamosParaINT

Pg2_fINT8uLCD_SO_Salir

pPagina1

goto xxx_TBx_SO_Salir

;Implementacion de fINT8uLCD_SO: 07-05-2003 (Begin)

;Implementacion de fCHRLCD_SO: 09-05-2003 (Begin)

Pg2_fCHRLCD_SO

btfss bRunPrimitSO ;Primero averiguamos si podemos ejecutar la función

goto Pg2_fCHRLCD_SO_Salir

call Pg2_PreparaParametrosParafINTxxLCD_SO

;Esta funcion anterior nos dejara en :

;B0:LOCAL_2 Inicio en RAM

;B0:LOCAL_3 Tamaño de RAM a ocupar

;B1:AARGB0 el caracter a mostrar


sBanco0

movf LOCAL_3,W ;Si es cero el tamaño nos vamos.

btfsc STATUS,Z

goto Pg2_fCHRLCD_SO_Salir

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Rutina 'Pg2_Char2LCD'

;Parametros : B0:LOCAL_0 : Caracter

; B0:LOCAL_1 : Numero de veces a mostrar

sBanco0

movf LOCAL_2,W ;Aqui tenemos guardado el origen

call Pg2_PonPunteroLCD

sBanco1

movf AARGB0,W

sBanco0

movwf LOCAL_0

movf LOCAL_3,W

movwf LOCAL_1

call Pg2_Char2LCD

Pg2_fCHRLCD_SO_Salir

pPagina1

goto xxx_TBx_SO_Salir

;Implementacion de fCHRLCD_SO: 09-05-2003 (End)

Pg2_DameFDValor

sBanco1

movlw ByteAltoBeginFD
movwf PCLATH

movf AARGB0,W

addlw ByteBajoBeginFD

movwf PCL

return ;Aqui nunca llega

;Implementacion de fSTRLCD_SO: 10-05-2003 (Begin)

Pg2_fSTRLCD_SO

btfss bRunPrimitSO ;Primero averiguamos si podemos ejecutar la función

goto Pg2_fSTRLCD_SO_Salir

call Pg2_PreparaParametrosParafSTRLCD_SO

;Esta funcion anterior nos dejara en :

;B0:LOCAL_2 Inicio en RAM

;B0:LOCAL_3 Tamaño de RAM a ocupar

;B1:AARGB0 el Flash Data de comienzo

sBanco1

movf 0x72,W

movwf AARGB0

;Primero nos aseguramos de que AARGB0 (FD100) + LOCAL_3 (Tamaño) es <= 200

sBanco1

movf AARGB0,W

sBanco0

addwf LOCAL_3,W

sublw .200

btfss STATUS,C

goto Pg2_fSTRLCD_SO_Salir
sBanco0

movf LOCAL_2,W ;Aqui tenemos guardado el origen

call Pg2_PonPunteroLCD

Pg2_fSTRLCD_SO_BeginBucle

sBanco0

movf LOCAL_3,W ;Si es cero el tamaño nos vamos.

btfsc STATUS,Z

goto Pg2_fSTRLCD_SO_Salir

decf LOCAL_3,F

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;Rutina 'Pg2_Char2LCD'

;Parametros : B0:LOCAL_0 : Caracter

; B0:LOCAL_1 : Numero de veces a mostrar

; sBanco1

; movlw ByteAltoBeginFD

; movwf PCLATH

; movf AARGB0,W

; addlw ByteBajoBeginFD

; movwf PCL

; pPagina2

call Pg2_DameFDValor

pPagina2

;Ya tenemos el valor en el acumulador

sBanco0
;movlw 'i'

movwf LOCAL_0

movlw .1

movwf LOCAL_1

call Pg2_Char2LCD

call Pg2_IncPunteroLCD

sBanco1

incf AARGB0,F

goto Pg2_fSTRLCD_SO_BeginBucle

Pg2_fSTRLCD_SO_Salir

pPagina1

goto xxx_TBx_SO_Salir

;Implementacion de fSTRLCD_SO: 10-05-2003 (End)

Pg2_RellenaLOCAL_5SegunAARGB0

;Veo si es negativo

sBanco1

btfss AARGB0,7

goto Pg2_fINT8sLCD_SO_NoEsNegativo

Pg2_fINT8sLCD_SO_SiEsNegativo

sBanco0

clrf LOCAL_5

goto Pg2_fINT8sLCD_SO_SiNoEsNegativo
Pg2_fINT8sLCD_SO_NoEsNegativo

sBanco0

movlw 0xFF

movwf LOCAL_5

Pg2_fINT8sLCD_SO_SiNoEsNegativo

return

;Implementacion de fINT8sLCD_SO: 09-05-2003 (Begin)

Pg2_fINT8sLCD_SO

btfss bRunPrimitSO ;Primero averiguamos si podemos ejecutar la función

goto Pg2_fINT8sLCD_SO_Salir

call Pg2_PreparaParametrosParafINTxxLCD_SO

;Esta funcion anterior nos dejara en :

;B0:LOCAL_2 Inicio en RAM

;B0:LOCAL_3 Tamaño de RAM a ocupar

;B1:(AARGB0,AARGB1,AARGB2,AARGB3) el numero a mostrar dependiendo del TBytes

;Posicionara el puntero de LCD en la ultima posicion, donde hay que escribir el

;digito menos significativo.

call Pg2_RellenaLOCAL_5SegunAARGB0

sBanco0

movf LOCAL_5,W

movwf LOCAL_6

sBanco0
clrf LOCAL_4 ;Ponemos en LOCAL_4 los digitos que estamos poniendo.

movf LOCAL_3,W ;Si es cero el tamaño nos vamos.

btfsc STATUS,Z

goto Pg2_fINT8sLCD_SO_Salir

Pg2_fINT8sLCD_SO_BeginDivisionesPor10

sBanco0

incf LOCAL_4,F

movf LOCAL_4,W

subwf LOCAL_3,W ;Comprobamos que cabe en el espacio que nos han dejado

btfsc STATUS,Z

goto Pg2_fINT8sLCD_SO_SiCabe

btfss STATUS,C

goto Pg2_fINT8sLCD_SO_NoCabe

Pg2_fINT8sLCD_SO_SiCabe

call Pg2_RellenaLOCAL_5SegunAARGB0

sBanco0

btfss LOCAL_5,0

goto Pg2_fINT8sLCD_SO_Neg

;;goto Pg2_fINT8sLCD_SO_Pos

Pg2_fINT8sLCD_SO_Pos

sBanco1

movlw .10

goto Pg2_fINT8sLCD_SO_PosNeg
Pg2_fINT8sLCD_SO_Neg

sBanco1

movlw 0xF6 ;-10 en hexadecimal

Pg2_fINT8sLCD_SO_PosNeg

movwf BARGB0

call Pg2_SDIV_8x8

sBanco1

movf REMB0,W

call Pg2_fINTxxLCD_SO_ImprimeCaracter

sBanco1

movf AARGB0,W

btfss STATUS,Z

goto Pg2_fINT8sLCD_SO_BeginDivisionesPor10

Pg2_fINT8sLCD_SO_NoCabe

sBanco0

btfss LOCAL_6,7

goto Pg2_fINT8sLCD_SO_NegativoRelleno

;goto Pg2_fINT8sLCD_SO_PositivoRelleno

Pg2_fINT8sLCD_SO_PositivoRelleno

call Pg2_fINTxuLCD_SO_RellenamosParaINT

goto Pg2_fINT8sLCD_SO_Salir

Pg2_fINT8sLCD_SO_NegativoRelleno

call Pg2_fINTxsLCD_SO_RellenamosParaINT
Pg2_fINT8sLCD_SO_Salir

pPagina1

goto xxx_TBx_SO_Salir

;Implementacion de fINT8sLCD_SO: 09-05-2003 (Begin)

;Implementacion de fINT16sLCD_SO: 09-05-2003 (Begin)

Pg2_fINT16sLCD_SO

btfss bRunPrimitSO ;Primero averiguamos si podemos ejecutar la función

goto Pg2_fINT16sLCD_SO_Salir

call Pg2_PreparaParametrosParafINTxxLCD_SO

;Esta funcion anterior nos dejara en :

;B0:LOCAL_2 Inicio en RAM

;B0:LOCAL_3 Tamaño de RAM a ocupar

;B1:(AARGB0,AARGB1,AARGB2,AARGB3) el numero a mostrar dependiendo del TBytes

;Posicionara el puntero de LCD en la ultima posicion, donde hay que escribir el

;digito menos significativo.

;Veo si es negativo

call Pg2_RellenaLOCAL_5SegunAARGB0

; sBanco1

; btfss AARGB0,7

; goto Pg2_fINT16sLCD_SO_NoEsNegativo

; ;goto Pg2_fINT8sLCD_SO_SiEsNegativo

;Pg2_fINT16sLCD_SO_SiEsNegativo

; decf AARGB0,F
; comf AARGB0,F

; sBanco0

; clrf LOCAL_5

; goto Pg2_fINT16sLCD_SO_SiNoEsNegativo

;Pg2_fINT16sLCD_SO_NoEsNegativo

; sBanco0

; movlw 0xFF

; movwf LOCAL_5

;Pg2_fINT16sLCD_SO_SiNoEsNegativo

sBanco0

movf LOCAL_5,W

movwf LOCAL_6

sBanco0

clrf LOCAL_4 ;Ponemos en LOCAL_4 los digitos que estamos poniendo.

movf LOCAL_3,W ;Si es cero el tamaño nos vamos.

btfsc STATUS,Z

goto Pg2_fINT16sLCD_SO_Salir

Pg2_fINT16sLCD_SO_BeginDivisionesPor10

sBanco0

incf LOCAL_4,F

movf LOCAL_4,W

subwf LOCAL_3,W ;Comprobamos que cabe en el espacio que nos han dejado
btfsc STATUS,Z

goto Pg2_fINT16sLCD_SO_SiCabe

btfss STATUS,C

goto Pg2_fINT16sLCD_SO_NoCabe

Pg2_fINT16sLCD_SO_SiCabe

call Pg2_RellenaLOCAL_5SegunAARGB0

sBanco0

btfss LOCAL_5,0

goto Pg2_fINT16sLCD_SO_Neg

;;goto Pg2_fINT8sLCD_SO_Pos

Pg2_fINT16sLCD_SO_Pos

sBanco1

movlw .10

movwf BARGB1

clrf BARGB0

goto Pg2_fINT16sLCD_SO_PosNeg

Pg2_fINT16sLCD_SO_Neg

sBanco1

movlw 0xF6 ;-10 en hexadecimal

movwf BARGB1

movlw 0xFF

movwf BARGB0

Pg2_fINT16sLCD_SO_PosNeg

sBanco1

;movlw .10
; movwf BARGB1

; clrf BARGB0

call Pg2_SDIV_16x16

sBanco1

movf REMB1,W

call Pg2_fINTxxLCD_SO_ImprimeCaracter

sBanco1

movf AARGB0,W

btfss STATUS,Z

goto Pg2_fINT16sLCD_SO_BeginDivisionesPor10

movf AARGB1,W

btfss STATUS,Z

goto Pg2_fINT16sLCD_SO_BeginDivisionesPor10

Pg2_fINT16sLCD_SO_NoCabe

sBanco0

btfss LOCAL_6,7

goto Pg2_fINT16sLCD_SO_NegativoRelleno

Pg2_fINT16sLCD_SO_PositivoRelleno

call Pg2_fINTxuLCD_SO_RellenamosParaINT

goto Pg2_fINT8sLCD_SO_Salir

Pg2_fINT16sLCD_SO_NegativoRelleno

call Pg2_fINTxsLCD_SO_RellenamosParaINT

Pg2_fINT16sLCD_SO_Salir

pPagina1
goto xxx_TBx_SO_Salir

;Implementacion de fINT16sLCD_SO: 09-05-2003 (Begin)

;Implementacion de fINT16uLCD_SO: 09-05-2003 (Begin)

Pg2_fINT16uLCD_SO

btfss bRunPrimitSO ;Primero averiguamos si podemos ejecutar la función

goto Pg2_fINT16uLCD_SO_Salir

call Pg2_PreparaParametrosParafINTxxLCD_SO

;Esta funcion anterior nos dejara en :

;B0:LOCAL_2 Inicio en RAM

;B0:LOCAL_3 Tamaño de RAM a ocupar

;B1:(AARGB0,AARGB1,AARGB2,AARGB3) el numero a mostrar dependiendo del TBytes

;Posicionara el puntero de LCD en la ultima posicion, donde hay que escribir el

;digito menos significativo.

sBanco0

clrf LOCAL_4 ;Ponemos en LOCAL_4 los digitos que estamos poniendo.

movf LOCAL_3,W ;Si es cero el tamaño nos vamos.

btfsc STATUS,Z

goto Pg2_fINT16uLCD_SO_Salir

Pg2_fINT16uLCD_SO_BeginDivisionesPor10

sBanco0

incf LOCAL_4,F
movf LOCAL_4,W

subwf LOCAL_3,W ;Comprobamos que cabe en el espacio que nos han dejado

btfsc STATUS,Z

goto Pg2_fINT16uLCD_SO_SiCabe

btfss STATUS,C

goto Pg2_fINT16uLCD_SO_NoCabe

Pg2_fINT16uLCD_SO_SiCabe

sBanco1

movlw .10

movwf BARGB1

clrf BARGB0

call Pg2_UDIV_16x16

sBanco1

movf REMB1,W

call Pg2_fINTxxLCD_SO_ImprimeCaracter

sBanco1

movf AARGB0,W

btfss STATUS,Z

goto Pg2_fINT16uLCD_SO_BeginDivisionesPor10

movf AARGB1,W

btfss STATUS,Z

goto Pg2_fINT16uLCD_SO_BeginDivisionesPor10

Pg2_fINT16uLCD_SO_NoCabe
call Pg2_fINTxuLCD_SO_RellenamosParaINT

Pg2_fINT16uLCD_SO_Salir

pPagina1

goto xxx_TBx_SO_Salir

;Implementacion de fINT16uLCD_SO: 07-05-2003 (Begin)

;Implementacion de SCL: 04-05-2003 (Begin)

Pg2_fSCL_SO

btfss bRunPrimitSO ;Primero averiguamos si podemos ejecutar la función

goto Pg2_fSCL_SO_Salir

;Tenemos la función de SCL:

;Si llamamos al primer parametro de la funcion y0 (BARGB0,BARGB1)

;Si llamamos al segundo parametro de la funcion y1 (AARGB0,AARGB1)

;Al valor de la entrada analógica x

;entonces el valor del cuarto operando será y=y0+[x*(y1-y0)]/1023

;Resta_16 hace (BARGB0,BARGB1)-(AARGB0,AARGB1) = (BARGB0,BARGB1)

;Por lo que lo primero que hacemos es intercambiar B y A.

;Guardamos primero y0 porque la usaremos mas adelante

sBanco1

movf BARGB1,W

sBanco0

movwf LOCAL_1

sBanco1

movf BARGB0,W

sBanco0
movwf LOCAL_0

;Primero vamos a comprobar si la pendiente es positiva o negativa

;pPagina2

call Pg2_RESTA_16_FOR_COMPARACION ;Si (BARGB0,BARGB1) >= (AARGB0,AARGB1) -->


C=1

;pPagina1

btfss STATUS,C

goto Pg2_fSCL_PendientePositiva

goto Pg2_fSCL_PendienteNegativa

Pg2_fSCL_PendientePositiva

sBanco0

bsf B0_PendienteSCL

call Pg2_IntercambiaAARGByBARGB

;En (BARGB0,BARGB1) tenemos (y1-y0)

goto Pg2_fSCL_PendienteSeguir

Pg2_fSCL_PendienteNegativa

sBanco0

bcf B0_PendienteSCL

;En (BARGB0,BARGB1) tenemos (y0-y1)

Pg2_fSCL_PendienteSeguir

call Pg2_RESTA_16

;Ahora tenemos que coger el valor de x que esta en 0x72

bsf STATUS,IRP ;Direccionamiento indirecto en bancos 2 y 3.

movf 0x72,W

movwf FSR
sBanco1

movf INDF,W

movwf AARGB1

incf FSR,F

movf INDF,W

movwf AARGB0

;En (AARGB0,AARGB1) tenemos x

; Operando 1 (16Bits): (AARGB0,AARGB1)

; Operando 2 (16Bits): (BARGB0,BARGB1)

; Resultado (32Bits): (AARGB0,AARGB1,AARGB2,AARGB3)

;pPagina2

call Pg2_UMUL_16x16

;pPagina1

;Tenemos en (AARGB0,AARGB1,AARGB2,AARGB3) [x*(y1-y0)]

;Tenemos que hacer INT32U/INT16U : (AARGB0,AARGB1,AARGB2,AARGB3) / (BARGB0,BARGB1)

;El cociente lo deja en (AARGB0,AARGB1,AARGB2,AARGB3) y el resto en (REMB0,REMB1)

;Tenemos que hacer INT32U/INT16U : (AARGB0,AARGB1,AARGB2,AARGB3) / (0x03,0xFF)

sBanco1

movlw 0xFF

movwf BARGB1

movlw 0x03

movwf BARGB0

;pPagina2

call Pg2_UDIV_32x16

;pPagina1
;En (AARGB2,AARGB3) tenemos [x*(y1-y0)]/1023

; Operando 1 (16Bits): (AARGB0,AARGB1)

; Operando 2 (16Bits): (BARGB0,BARGB1)

; Resultado (16Bits): (BARGB0,BARGB1)

;Restauramos y0

sBanco0

movf LOCAL_1,W ;Aqui teniamos el byte bajo de y0

sBanco1

movwf BARGB1

sBanco0

movf LOCAL_0,W ;Aqui teniamos el byte alto de y0

sBanco1

movwf BARGB0

movf AARGB3,W

movwf AARGB1

movf AARGB2,W

movwf AARGB0

; (BARGB0,BARGB1) - (AARGB0,AARGB1) = (BARGB0,BARGB1)

; Despues de llamar a esta funcion se puede evaluar el Bit Carry

; si BARGB0>=AARGB0 C=1 (Resultado POSITIVO o CERO)

; si BARGB0< AARGB0 C=0 (Resultado NEGATIVO)

sBanco0

btfss B0_PendienteSCL

goto Pg2_fSCL_SO_Restar
goto Pg2_fSCL_SO_Sumar

Pg2_fSCL_SO_Restar

;pPagina2

call Pg2_RESTA_16

;pPagina1

goto Pg2_fSCL_SO_SumarRestarSalir

Pg2_fSCL_SO_Sumar

;pPagina2

call Pg2_SUMA_16

;pPagina1

Pg2_fSCL_SO_SumarRestarSalir

;Tenemos en (BARGB0,BARGB1) y0+[x*(y1-y0)]/1023 para pendiente positiva

;Tenemos en (BARGB0,BARGB1) y0-[x*(y0-y1)]/1023 para pendiente negativa

;Lo guardamos en 0x73

movf 0x73,W

movwf FSR

incf FSR,F

;Primero comprobamos si es mayor que RD095

;Comprobamos que lo vamos a poner en un RD correcto

pPagina1

call Pg1_EsFSR_unRDValido;Devolvera Z=1(Invalido) Z=0(Valido)

pPagina2

btfsc STATUS,Z ;que podemos evaluar BTFSS STATUS,Z

goto Pg2_fSCL_SO_Salir

bsf STATUS,IRP ;Direccionamiento indirecto a bancos 2 y 3


sBanco1

decf FSR,F

movf BARGB1,W

movwf INDF

incf FSR,F

movf BARGB0,W

movwf INDF

Pg2_fSCL_SO_Salir

pPagina1

goto xxx_TBx_SO_Salir

;Implementacion de SCL: 04-05-2003 (End)

;Implementacion de Pg2_LimpiarTimers: 06-05-2003 (Begin)

Pg2_LimpiarTimers

;Recorremos los temporizadores.

bsf STATUS,IRP ;Direccionamiento indirecto en bancos 2 y 3.

movlw 0x3E ;Byte de control del timer 0

iorlw 0x80 ;Vamos al banco3

movwf FSR

Pg2_LimpiarTimers_Bucle

;Comprobamos si hay que descontar

clrf INDF

incf FSR,F

clrf INDF

movlw 0x6F
iorlw 0x80

subwf FSR,W

btfsc STATUS,Z

goto Pg2_LimpiarTimers_Salir

incf FSR,F

goto Pg2_LimpiarTimers_Bucle

Pg2_LimpiarTimers_Salir

return

;Implementacion de Pg2_LimpiarTimers: 06-05-2003 (End)

Pg2_fTON_TOFF_TUP_TDN_Parametro

;Vemos si tenemos que traer el valor a cargar,en modalidad 0

btfsc bBit1Modalidad ;Si la Modalidad es la adecuada traemos el valor apuntado

;por Reg0x71

goto Pg2_fTON_SO_Modalidad2

sBanco1

bsf STATUS,IRP ;Seleccionamos Banco 2-3 en direccionamiento indirecto

movf 0x71,W

movwf FSR

movf INDF,W

movwf AARGB0

Pg2_fTON_SO_Modalidad2

return

Pg2_PonerBT

;Copiamos la base de tiempos de la instruccion a la zona de control


bsf INDF,TimControl_BaseTiempo_BitBajo

btfss 0x72,0

bcf INDF,TimControl_BaseTiempo_BitBajo

bsf INDF,TimControl_BaseTiempo_BitAlto

btfss 0x72,1

bcf INDF,TimControl_BaseTiempo_BitAlto

return

;Implementacion de Ton: 05-05-2003 (Begin)

Pg2_fTON_SO

call Pg2_fTON_TOFF_TUP_TDN_Parametro

;Primero comprobamos si el puntero que nos pasan en 0x70 es valido o no.

movf 0x70,W

movwf FSR

pPagina1

call Pg1_EsFSR_unRDValido;Devolvera Z=1(Invalido) Z=0(Valido)

pPagina2

btfsc STATUS,Z ;que podemos evaluar BTFSS STATUS,Z

goto Pg2_fTON_SO_Salir

movf FSR,W

iorlw 0x80 ;Para irnos al banco 3.

movwf FSR

bsf STATUS,IRP ;Direccionamiento indirecto en paginas 2 y 3

decf FSR,F ;En INDF tendremos el registro de control del timer

call Pg2_PonerBT
bcf INDF,TimControl_TipoTimer_BitBajo

bcf INDF,TimControl_TipoTimer_BitAlto

btfss bPilaLogica ;Primero averiguamos si podemos ejecutar la función

goto Pg2_fTON_SO_SenalActivacionOFF

goto Pg2_fTON_SO_SenalActivacionON

Pg2_fTON_SO_SenalActivacionON

btfsc INDF,TimControl_YaEnMarcha

goto Pg2_fTON_SO_HayQueActivarSalida_

bsf INDF,TimControl_YaEnMarcha

bsf INDF,TimControl_ActivacionBT

bcf INDF,TimControl_SalidaTimer

goto Pg2_fTON_SO_SenalActivacionONyOFF

Pg2_fTON_SO_HayQueActivarSalida_

;Comprobamos si hay que activar salida

incf FSR,F

sBanco1

movf INDF,W

btfss STATUS,Z

goto Pg2_fTON_SO_Salir

;Activamos salida

decf FSR,F
bsf INDF,TimControl_SalidaTimer

goto Pg2_fTON_SO_Salir

Pg2_fTON_SO_SenalActivacionOFF

bcf INDF,TimControl_YaEnMarcha

bcf INDF,TimControl_SalidaTimer

bcf INDF,TimControl_ActivacionBT

Pg2_fTON_SO_SenalActivacionONyOFF

incf FSR,F

sBanco1

movf AARGB0,W

movwf INDF

goto Pg2_fTON_SO_Salir

;En 0x70 tenemos la direccion en el banco 3 de registro-valor del timer

;Restandole 1 tendremos la direccion en el banco 3 de registro-control del timer

;En 0x72 tendremos directamente el valor de la base de tiempos:

; 00: 1mseg

; 01: 10mseg

; 10: 100mseg

; 11: 1000mseg

Pg2_fTON_SO_Salir

pPagina1

goto xxx_TBx_SO_Salir

;Implementacion de Ton: 05-05-2003 (End)


;Implementacion de Toff: 06-05-2003 (Begin)

Pg2_fTOFF_SO

call Pg2_fTON_TOFF_TUP_TDN_Parametro

;Primero comprobamos si el puntero que nos pasan en 0x70 es valido o no.

movf 0x70,W

movwf FSR

pPagina1

call Pg1_EsFSR_unRDValido;Devolvera Z=1(Invalido) Z=0(Valido)

pPagina2

btfsc STATUS,Z ;que podemos evaluar BTFSS STATUS,Z

goto Pg2_fTOFF_SO_Salir

movf FSR,W

iorlw 0x80 ;Para irnos al banco 3.

movwf FSR

bsf STATUS,IRP ;Direccionamiento indirecto en paginas 2 y 3

decf FSR,F ;En INDF tendremos el registro de control del timer

;Copiamos la base de tiempos de la instruccion a la zona de control

call Pg2_PonerBT

bsf INDF,TimControl_TipoTimer_BitBajo

bcf INDF,TimControl_TipoTimer_BitAlto

btfss bPilaLogica ;Primero averiguamos si podemos ejecutar la función

goto Pg2_fTOFF_SO_SenalActivacionOFF
goto Pg2_fTOFF_SO_SenalActivacionON

Pg2_fTOFF_SO_SenalActivacionOFF

btfss INDF,TimControl_YaEnMarcha

goto Pg2_fTON_SO_HayQueDesactivarSalida_

;goto Pg2_fTOFF_SO_Salir

bcf INDF,TimControl_YaEnMarcha

bsf INDF,TimControl_ActivacionBT

bsf INDF,TimControl_SalidaTimer

goto Pg2_fTOFF_SO_SenalActivacionONyOFF

;ll

Pg2_fTON_SO_HayQueDesactivarSalida_

;Comprobamos si hay que activar salida

incf FSR,F

sBanco1

movf INDF,W

btfss STATUS,Z

goto Pg2_fTON_SO_Salir

;Desactivamos salida

decf FSR,F

bcf INDF,TimControl_SalidaTimer
bcf INDF,TimControl_ActivacionBT

goto Pg2_fTON_SO_Salir

;ll

Pg2_fTOFF_SO_SenalActivacionON

bsf INDF,TimControl_YaEnMarcha

bsf INDF,TimControl_SalidaTimer

bcf INDF,TimControl_ActivacionBT

Pg2_fTOFF_SO_SenalActivacionONyOFF

incf FSR,F

sBanco1

movf AARGB0,W

movwf INDF

goto Pg2_fTOFF_SO_Salir

;En 0x70 tenemos la direccion en el banco 3 de registro-valor del timer

;Restandole 1 tendremos la direccion en el banco 3 de registro-control del timer

;En 0x72 tendremos directamente el valor de la base de tiempos:

; 00: 1mseg

; 01: 10mseg
; 10: 100mseg

; 11: 1000mseg

Pg2_fTOFF_SO_Salir

pPagina1

goto xxx_TBx_SO_Salir

;Implementacion de Toff: 05-05-2003 (End)

;Implementacion de RefLCD: 08-05-2003 (Begin)

Pg2_fREFLCD_SO

pPagina1

call Pg1_DebemosEjecutar_

;Nos devuelve 0xFF en W si debemos ejecutar la


función

;Nos devuelve 0x00 en W si NO debemos


ejecutar la función

pPagina2

andlw 0xFF ;Como retlw no afecta a los bits de STATUS hacemos esto

btfsc STATUS,Z

goto Pg2_fREFLCD_SO_Salir

pPagina1

call Pg1_Refresh_LCD

Pg2_fREFLCD_SO_Salir

pPagina1

goto xxx_TBx_SO_Salir

;Implementacion de REFLCD: 08-05-2003 (End)

;Implementacion de Tup: 06-05-2003 (Begin)


Pg2_fTUP_SO

call Pg2_fTON_TOFF_TUP_TDN_Parametro

;Primero comprobamos si el puntero que nos pasan en 0x70 es valido o no.

movf 0x70,W

movwf FSR

pPagina1

call Pg1_EsFSR_unRDValido;Devolvera Z=1(Invalido) Z=0(Valido)

pPagina2

btfsc STATUS,Z ;que podemos evaluar BTFSS STATUS,Z

goto Pg2_fTUP_SO_Salir

movf FSR,W

iorlw 0x80 ;Para irnos al banco 3.

movwf FSR

bsf STATUS,IRP ;Direccionamiento indirecto en paginas 2 y 3

decf FSR,F ;En INDF tendremos el registro de control del timer

;Copiamos la base de tiempos de la instruccion a la zona de control

call Pg2_PonerBT

bcf INDF,TimControl_TipoTimer_BitBajo

bsf INDF,TimControl_TipoTimer_BitAlto

btfss bPilaLogica ;Primero averiguamos si podemos ejecutar la función

goto Pg2_fTUP_SO_SenalActivacionONyOFF

Pg2_fTUP_SO_SenalActivacionON

btfsc INDF,TimControl_YaEnMarcha

goto Pg2_fTUP_SO_SenalActivacionONyOFF
btfsc INDF,TimControl_SenalActivAnterior

goto Pg2_fTUP_SO_SenalActivacionONyOFF

bsf INDF,TimControl_YaEnMarcha

bsf INDF,TimControl_ActivacionBT

bsf INDF,TimControl_SalidaTimer

incf FSR,F

sBanco1

movf AARGB0,W

movwf INDF

decf FSR,F

Pg2_fTUP_SO_SenalActivacionONyOFF

bsf INDF,TimControl_SenalActivAnterior

btfss bPilaLogica

bcf INDF,TimControl_SenalActivAnterior

goto Pg2_fTUP_SO_Salir

;En 0x70 tenemos la direccion en el banco 3 de registro-valor del timer

;Restandole 1 tendremos la direccion en el banco 3 de registro-control del timer

;En 0x72 tendremos directamente el valor de la base de tiempos:

; 00: 1mseg

; 01: 10mseg

; 10: 100mseg

; 11: 1000mseg
Pg2_fTUP_SO_Salir

pPagina1

goto xxx_TBx_SO_Salir

;Implementacion de Tup: 06-05-2003 (End)

;Implementacion de Tdn: 06-05-2003 (Begin)

Pg2_fTDN_SO

call Pg2_fTON_TOFF_TUP_TDN_Parametro

;Primero comprobamos si el puntero que nos pasan en 0x70 es valido o no.

movf 0x70,W

movwf FSR

pPagina1

call Pg1_EsFSR_unRDValido;Devolvera Z=1(Invalido) Z=0(Valido)

pPagina2

btfsc STATUS,Z ;que podemos evaluar BTFSS STATUS,Z

goto Pg2_fTDN_SO_Salir

movf FSR,W

iorlw 0x80 ;Para irnos al banco 3.

movwf FSR

bsf STATUS,IRP ;Direccionamiento indirecto en paginas 2 y 3

decf FSR,F ;En INDF tendremos el registro de control del timer

;Copiamos la base de tiempos de la instruccion a la zona de control

call Pg2_PonerBT

bsf INDF,TimControl_TipoTimer_BitBajo

bsf INDF,TimControl_TipoTimer_BitAlto
btfsc bPilaLogica ;Primero averiguamos si podemos ejecutar la función

goto Pg2_fTDN_SO_SenalActivacionONyOFF

Pg2_fTDN_SO_SenalActivacionOFF

btfsc INDF,TimControl_YaEnMarcha

goto Pg2_fTDN_SO_SenalActivacionONyOFF

btfss INDF,TimControl_SenalActivAnterior

goto Pg2_fTDN_SO_SenalActivacionONyOFF

bsf INDF,TimControl_YaEnMarcha

bsf INDF,TimControl_ActivacionBT

bsf INDF,TimControl_SalidaTimer

incf FSR,F

sBanco1

movf AARGB0,W

movwf INDF

decf FSR,F

Pg2_fTDN_SO_SenalActivacionONyOFF

bsf INDF,TimControl_SenalActivAnterior

btfss bPilaLogica

bcf INDF,TimControl_SenalActivAnterior

goto Pg2_fTDN_SO_Salir

;En 0x70 tenemos la direccion en el banco 3 de registro-valor del timer


;Restandole 1 tendremos la direccion en el banco 3 de registro-control del timer

;En 0x72 tendremos directamente el valor de la base de tiempos:

; 00: 1mseg

; 01: 10mseg

; 10: 100mseg

; 11: 1000mseg

Pg2_fTDN_SO_Salir

pPagina1

goto xxx_TBx_SO_Salir

;Implementacion de Tdn: 06-05-2003 (End)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Pg2_IntercambiaAARGByBARGB

sBanco1

movf AARGB0,W

movwf TEMPB0

movf BARGB0,W

movwf AARGB0

movf TEMPB0,W

movwf BARGB0

movf AARGB1,W

movwf TEMPB1

movf BARGB1,W

movwf AARGB1
movf TEMPB1,W

movwf BARGB1

movf AARGB2,W

movwf TEMPB2

movf BARGB2,W

movwf AARGB2

movf TEMPB2,W

movwf BARGB2

movf AARGB3,W

movwf TEMPB3

movf BARGB3,W

movwf AARGB3

movf TEMPB3,W

movwf BARGB3

sBanco0

return

;
*************************************************************************************
*******

;
*************************************************************************************
*******

; Suma de operandos de 16 bits, resultado en 16 bits.

; Parametro de entrada:

; Banco de Trabajo: Banco 1.


; Operando 1 (16Bits): (AARGB0,AARGB1)

; Operando 2 (16Bits): (BARGB0,BARGB1)

; Resultado (16Bits): (BARGB0,BARGB1)

Pg2_SUMA_16

sBanco1

movf AARGB1,W

addwf BARGB1,F

movf AARGB0,W

btfsc STATUS,C

incfsz AARGB0,W

addwf BARGB0,F

return

;
*************************************************************************************
*******

;
*************************************************************************************
*******

; Suma de operandos de 32 bits, resultado en 32 bits.

; Parametro de entrada:

; Banco de Trabajo: Banco 1.

; Operando 1 (32Bits): (AARGB0,AARGB1,AARGB2,AARGB3)

; Operando 2 (32Bits): (BARGB0,BARGB1,BARGB2,BARGB3)

; Resultado (32Bits): (BARGB0,BARGB1,BARGB2,BARGB3)

; Despues de llamar a esta funcion se puede evaluar el Bit Carry para


; saber si ha habido carry (overflow)

Pg2_SUMA_32

sBanco1

movf AARGB3,W

addwf BARGB3,F

movf AARGB2,W

btfsc STATUS,C

incfsz AARGB2,W

addwf BARGB2,F

movf AARGB1,W

btfsc STATUS,C

incfsz AARGB1,W

addwf BARGB1,F

movf AARGB0,W

btfsc STATUS,C

incfsz AARGB0,W

addwf BARGB0,F

retlw 0x00

;
*************************************************************************************
*******
;
*************************************************************************************
*******

;
*************************************************************************************
*******

;
*************************************************************************************
*******

;
*************************************************************************************
*******

; Resta de operandos de 16 bits, resultado en 16 bits.

; Banco de Trabajo: Banco 1

; (BARGB0,BARGB1) - (AARGB0,AARGB1) = (BARGB0,BARGB1)

; Despues de llamar a esta funcion se puede evaluar el Bit Carry

; si BARGB0>=AARGB0 C=1 (Resultado POSITIVO o CERO)

; si BARGB0< AARGB0 C=0 (Resultado NEGATIVO)

Pg2_RESTA_16

sBanco1

movf AARGB1,W

subwf BARGB1,F

movf AARGB0,W

btfss STATUS,C

incfsz AARGB0,W

subwf BARGB0,F

return

Pg2_RESTA_16_FOR_COMPARACION

sBanco1
movf AARGB1,W

subwf BARGB1,W

movf AARGB0,W

btfss STATUS,C

incfsz AARGB0,W

subwf BARGB0,W

return

;
*************************************************************************************
*******

;
*************************************************************************************
*******

;
*************************************************************************************
*******

;
*************************************************************************************
*******

;
*************************************************************************************
*******

; Resta de operandos de 32 bits, resultado en 32 bits.

; Banco de Trabajo: Banco 1.

; (BARGB0,BARGB1,BARGB2,BARGB3)-
(AARGB0,AARGB1,AARGB2,AARGB3)=(BARGB0,BARGB1,BARGB2,BARGB3)

; Despues de llamar a esta funcion se puede evaluar el Bit Carry

; si BARGB>=AARGB C=1 (Resultado POSITIVO o CERO)

; si BARGB< AARGB C=0 (Resultado NEGATIVO)


;

Pg2_RESTA_32

sBanco1

movf AARGB3,W

subwf BARGB3,W

movwf BARGB3

movf AARGB2,W

btfss STATUS,C

incfsz AARGB2,W

subwf BARGB2,W

movwf BARGB2

movf AARGB1,W

btfss STATUS,C

incfsz AARGB1,W

subwf BARGB1,W

movwf BARGB1

movf AARGB0,W

btfss STATUS,C

incfsz AARGB0,W

subwf BARGB0,W

movwf BARGB0

retlw 0x00

Pg2_RESTA_32_FOR_COMPARACION
sBanco1

movf AARGB3,W

subwf BARGB3,W

;movwf BARGB3

movf AARGB2,W

btfss STATUS,C

incfsz AARGB2,W

subwf BARGB2,W

;movwf BARGB2

movf AARGB1,W

btfss STATUS,C

incfsz AARGB1,W

subwf BARGB1,W

;movwf BARGB1

movf AARGB0,W

btfss STATUS,C

incfsz AARGB0,W

subwf BARGB0,W

;movwf BARGB0

retlw 0x00

;
*************************************************************************************
*******
;
*************************************************************************************
*******

; Comparación CON SIGNO de 8 bits.

; Parametro de entrada:

; Banco de Trabajo: Banco 1.

; Operando 1 (8Bits): (BARGB0)

; Operando 2 (8Bits): (AARGB0)

; Banco de Trabajo: Banco Común.

; Resultado (Varios Bits): SD_EQ,SD_NEQ,SD_GT,SD_GE,SD_LT,SD_LE

Pg2_COMP_S8

sBanco1

movf AARGB0,W

subwf BARGB0,W

Pg2_Evaluar_SDs

bsf Bx_SD_EQ

btfss STATUS,Z

bcf Bx_SD_EQ

;Para no tener que hacer otra resta en SD_NEQ vamos a guardar STATUS,C

bsf Bx_SD_NEQ

btfss STATUS,C

bcf Bx_SD_NEQ

movf AARGB0,W ;Comprobamos si tiene el mismo signo

xorwf BARGB0,W
andlw 0x80

btfss STATUS,Z

goto COMP_S8_DistintoSigno

COMP_S8_MismoSigno

bsf STATUS,C

btfss Bx_SD_NEQ

bcf STATUS,C

goto Pg2_Evaluar_SDu

COMP_S8_DistintoSigno

bsf STATUS,C

btfsc BARGB0,7

bcf STATUS,C

goto Pg2_Evaluar_SDu

;
*************************************************************************************
*******

;
*************************************************************************************
*******

; Comparación SIN SIGNO de 8 bits.

; Parametro de entrada:

; Banco de Trabajo: Banco 1.

; Operando 1 (8Bits): (BARGB0)

; Operando 2 (8Bits): (AARGB0)

; Banco de Trabajo: Banco Común.

; Resultado (Varios Bits): SD_EQ,SD_NEQ,SD_GT,SD_GE,SD_LT,SD_LE

;
Pg2_COMP_U8

sBanco1

movf AARGB0,W

subwf BARGB0,W

bsf Bx_SD_EQ

btfss STATUS,Z

bcf Bx_SD_EQ

Pg2_Evaluar_SDu

bcf Bx_SD_NEQ

btfss Bx_SD_EQ

bsf Bx_SD_NEQ

btfss STATUS,C

goto COMP_U8_EsMenor

COMP_U8_EsMayorOIgual

bcf Bx_SD_LT

bsf Bx_SD_GE

bcf Bx_SD_GT

btfss Bx_SD_EQ

bsf Bx_SD_GT

bsf Bx_SD_LE

btfss Bx_SD_EQ

bcf Bx_SD_LE

return
COMP_U8_EsMenor

bcf Bx_SD_GE

bcf Bx_SD_GT

bsf Bx_SD_LT

bsf Bx_SD_LE

return

;
*************************************************************************************
*******

;
*************************************************************************************
*******

; Comparación SIN SIGNO de 16 bits.

; Parametro de entrada:

; Banco de Trabajo: Banco 1.

; Operando 1 (16Bits): (BARGB0,BARGB1)

; Operando 2 (16Bits): (AARGB0,AARGB1)

; Banco de Trabajo: Banco Común.

; Resultado (Varios Bits): SD_EQ,SD_NEQ,SD_GT,SD_GE,SD_LT,SD_LE

Pg2_COMP_U16

;Para evaluar SD necesitamos C y Bs_SD_EQ

call Pg2_COMP_U16_S16_Comun

goto Pg2_Evaluar_SDu
;
*************************************************************************************
*******

;
*************************************************************************************
*******

; Comparación CON SIGNO de 16 bits.

; Parametro de entrada:

; Banco de Trabajo: Banco 1.

; Operando 1 (16Bits): (BARGB0,BARGB1)

; Operando 2 (16Bits): (AARGB0,AARGB1)

; Banco de Trabajo: Banco Común.

; Resultado (Varios Bits): SD_EQ,SD_NEQ,SD_GT,SD_GE,SD_LT,SD_LE

Pg2_COMP_S16

call Pg2_COMP_U16_S16_Comun

goto Pg2_Evaluar_SDs

Pg2_COMP_U16_S16_Comun

sBanco1

; (BARGB0,BARGB1) - (AARGB0,AARGB1) = (BARGB0,BARGB1)

call Pg2_RESTA_16_FOR_COMPARACION

;Para no tener que hacer otra resta en SD_NEQ vamos a guardar STATUS,C en Bx_SD_NEQ

bsf Bx_SD_NEQ

btfss STATUS,C

bcf Bx_SD_NEQ
sBanco1

movf BARGB1,W

subwf AARGB1,W

btfss STATUS,Z

goto Pg2_COMP_U16_S16_NoCero

movf BARGB0,W

subwf AARGB0,W

btfss STATUS,Z

goto Pg2_COMP_U16_S16_NoCero

bsf Bx_SD_EQ

goto Pg2_COMP_U16_S16_Seguir

Pg2_COMP_U16_S16_NoCero

bcf Bx_SD_EQ

Pg2_COMP_U16_S16_Seguir

;Restauramos C

bsf STATUS,C

btfss Bx_SD_NEQ

bcf STATUS,C

return

;
*************************************************************************************
*******
;
*************************************************************************************
*******

; Comparación SIN SIGNO de 32 bits.

; Parametro de entrada:

; Banco de Trabajo: Banco 1.

; Operando 1 (32Bits): (BARGB0,BARGB1,BARGB2,BARGB3)

; Operando 2 (32Bits): (AARGB0,AARGB1,AARGB2,AARGB3)

; Banco de Trabajo: Banco Común.

; Resultado (Varios Bits): SD_EQ,SD_NEQ,SD_GT,SD_GE,SD_LT,SD_LE

Pg2_COMP_U32

;sBanco1

;call Pg2_RESTA_32

;bsf Bx_SD_EQ

;btfss STATUS,Z

;bcf Bx_SD_EQ

call Pg2_COMP_U32_S32_Comun

goto Pg2_Evaluar_SDu

;
*************************************************************************************
*******

;
*************************************************************************************
*******

; Comparación CON SIGNO de 32 bits.

; Parametro de entrada:
; Banco de Trabajo: Banco 1.

; Operando 1 (32Bits): (BARGB0,BARGB1,BARGB2,BARGB3)

; Operando 2 (32Bits): (AARGB0,AARGB1,AARGB2,AARGB3)

; Banco de Trabajo: Banco Común.

; Resultado (Varios Bits): SD_EQ,SD_NEQ,SD_GT,SD_GE,SD_LT,SD_LE

Pg2_COMP_S32

;sBanco1

;call Pg2_RESTA_32

call Pg2_COMP_U32_S32_Comun

goto Pg2_Evaluar_SDs

Pg2_COMP_U32_S32_Comun

;sBanco1

; (BARGB0,BARGB1,BARGB2,BARGB3)-(AARGB0,AARGB1,AARGB2,AARGB3)

; =(BARGB0,BARGB1,BARGB2,BARGB3)

call Pg2_RESTA_32_FOR_COMPARACION

;La comprobación de cero no esta bien.

;Para no tener que hacer otra resta en SD_NEQ vamos a guardar STATUS,C en Bx_SD_NEQ

bsf Bx_SD_NEQ

btfss STATUS,C

bcf Bx_SD_NEQ
sBanco1

movf BARGB3,W

subwf AARGB3,W

btfss STATUS,Z

goto Pg2_COMP_U32_S32_NoCero

movf BARGB2,W

subwf AARGB2,W

btfss STATUS,Z

goto Pg2_COMP_U32_S32_NoCero

movf BARGB1,W

subwf AARGB1,W

btfss STATUS,Z

goto Pg2_COMP_U32_S32_NoCero

movf BARGB0,W

subwf AARGB0,W

btfss STATUS,Z

goto Pg2_COMP_U32_S32_NoCero

bsf Bx_SD_EQ

goto Pg2_COMP_U32_S32_Seguir

Pg2_COMP_U32_S32_NoCero

bcf Bx_SD_EQ

Pg2_COMP_U32_S32_Seguir

;Restauramos C

bsf STATUS,C
btfss Bx_SD_NEQ

bcf STATUS,C

return

;
*************************************************************************************
*******

; Multiplicacion de operandos de 8 bits sin signo, resultado en 16 bits.

; Parametro de entrada:

; Banco de Trabajo: Banco 1.

; Operando 1 (8Bits): AARGB0

; Operando 2 (8Bits): BARGB0

; Resultado (16Bits): (AARGB0,AARGB1)

Pg2_UMUL_8x8

sBanco1

CLRF AARGB1

MOVLW 0x08

MOVWF LOOPCOUNT

MOVF AARGB0,W

LOOPUM0808A

RRF BARGB0, F

BTFSC STATUS,C

GOTO LUM0808NAP
DECFSZ LOOPCOUNT, F

GOTO LOOPUM0808A

CLRF AARGB0

RETLW 0x00

LUM0808NAP

BCF STATUS,C

GOTO LUM0808NA

LOOPUM0808

RRF BARGB0, F

BTFSC STATUS,C

ADDWF AARGB0, F

LUM0808NA

RRF AARGB0, F

RRF AARGB1, F

DECFSZ LOOPCOUNT, F

GOTO LOOPUM0808

return

;
*************************************************************************************
*******

;
*************************************************************************************
*******

;
*************************************************************************************
*******

;
*************************************************************************************
*******
;
*************************************************************************************
*******

; Multiplicacion de operandos de 8 bits con signo, resultado en 16 bits.

; Parametro de entrada:

; Banco de Trabajo: Banco 1.

; Operando 1 (8Bits): AARGB0

; Operando 2 (8Bits): BARGB0

; Resultado (16Bits): (AARGB0,AARGB1)

Pg2_SMUL_8x8

;BSF STATUS,RP0

;BCF STATUS,RP1 ;Banco 1

sBanco1

CLRF AARGB1 ; clear partial product

CLRF SIGN

MOVF AARGB0,W

BTFSC STATUS,Z

RETLW 0x00

XORWF BARGB0,W

MOVWF TEMPB3

BTFSC TEMPB3,MSB

COMF SIGN, F

BTFSS BARGB0,MSB

GOTO M0808SOK

COMF BARGB0, F ; make multiplier BARG > 0


INCF BARGB0, F

COMF AARGB0, F

INCF AARGB0, F

BTFSC BARGB0,MSB

GOTO M0808SX

M0808SOK

;Comienzo de macro

MOVLW 0x07

MOVWF LOOPCOUNT

MOVF AARGB0,W

LOOPSM0808A

RRF BARGB0, F

BTFSC STATUS,C

GOTO LSM0808NA

DECFSZ LOOPCOUNT, F

GOTO LOOPSM0808A

CLRF AARGB0

RETLW 0x00

LOOPSM0808

RRF BARGB0, F

BTFSC STATUS,C

ADDWFAARGB0, F

LSM0808NA

RLF SIGN, F
RRF AARGB0, F

RRF AARGB1, F

DECFSZ LOOPCOUNT, F

GOTO LOOPSM0808

RLF SIGN, F

RRF AARGB0, F

RRF AARGB1, F

;Fin de Macro

RETLW 0x00

M0808SX

CLRF AARGB1

RLF SIGN, W

RRF AARGB0, F

RRF AARGB1, F

RETLW 0x00

;
*************************************************************************************
*******

;
*************************************************************************************
*******

;
*************************************************************************************
*******
;
*************************************************************************************
*******

;
*************************************************************************************
*******

; Multiplicacion de operandos de 16 bits sin signo, resultado en 32 bits.

; Parametro de entrada:

; Banco de Trabajo: Banco 1.

; Operando 1 (16Bits): (AARGB0,AARGB1)

; Operando 2 (16Bits): (BARGB0,BARGB1)

; Resultado (32Bits): (AARGB0,AARGB1,AARGB2,AARGB3)

Pg2_UMUL_16x16

sBanco1

CLRF AARGB2 ; clear partial product

CLRF AARGB3

MOVF AARGB0,W

MOVWF TEMPB0

MOVF AARGB1,W

MOVWF TEMPB1

MOVLW 0x08

MOVWF LOOPCOUNT

LOOPUM1616A

RRF BARGB1,F

BTFSC STATUS,C

GOTO ALUM1616NAP
DECFSZ LOOPCOUNT,F

GOTO LOOPUM1616A

MOVWF LOOPCOUNT

LOOPUM1616B

RRF BARGB0,F

BTFSC STATUS,C

GOTO BLUM1616NAP

DECFSZ LOOPCOUNT,F

GOTO LOOPUM1616B

CLRF AARGB0

CLRF AARGB1

RETLW 0x00

BLUM1616NAP

BCF STATUS,C

GOTO BLUM1616NA

ALUM1616NAP

BCF STATUS,C

GOTO ALUM1616NA

ALOOPUM1616

RRF BARGB1,F

BTFSS STATUS,C

GOTO ALUM1616NA

MOVF TEMPB1,W
ADDWF AARGB1,F

MOVF TEMPB0,W

BTFSC STATUS,C

INCFSZ TEMPB0,W

ADDWF AARGB0,F

ALUM1616NA

RRF AARGB0,F

RRF AARGB1,F

RRF AARGB2,F

DECFSZ LOOPCOUNT,F

GOTO ALOOPUM1616

MOVLW 0x08

MOVWF LOOPCOUNT

BLOOPUM1616

RRF BARGB0,F

BTFSS STATUS,C

GOTO BLUM1616NA

MOVF TEMPB1,W

ADDWF AARGB1,F

MOVF TEMPB0,W

BTFSC STATUS,C

INCFSZ TEMPB0,W

ADDWFAARGB0,F

BLUM1616NA

RRF AARGB0,F
RRF AARGB1,F

RRF AARGB2,F

RRF AARGB3,F

DECFSZ LOOPCOUNT,F

GOTO BLOOPUM1616

return

;
*************************************************************************************
*******

;
*************************************************************************************
*******

;
*************************************************************************************
*******

;
*************************************************************************************
*******

;
*************************************************************************************
*******

; Multiplicacion de operandos de 16 bits con signo, resultado en 32 bits.

; Parametro de entrada:

; Banco de Trabajo: Banco 1.

; Operando 1 (16Bits): (AARGB0,AARGB1)

; Operando 2 (16Bits): (BARGB0,BARGB1)

; Resultado (32Bits): (AARGB0,AARGB1,AARGB2,AARGB3)

;
Pg2_SMUL_16x16

sBanco1

;BSF STATUS,RP0

;BCF STATUS,RP1 ;Banco 1

CLRF AARGB2 ; clear partial product

CLRF AARGB3

CLRF SIGN

MOVF AARGB0,W

IORWF AARGB1,W

BTFSC STATUS,Z

RETLW 0x00

MOVF AARGB0,W

XORWF BARGB0,W

MOVWF TEMPB0

BTFSC TEMPB0,MSB

COMF SIGN,F

BTFSS BARGB0,MSB

GOTO M1616SOK

COMF BARGB1,F

COMF BARGB0,F

INCF BARGB1,F

BTFSC STATUS,Z

INCF BARGB0,F

COMF AARGB1,F
COMF AARGB0,F

INCF AARGB1,F

BTFSC STATUS,Z

INCF AARGB0,F

BTFSC BARGB0,MSB

GOTO M1616SX

M1616SOK

MOVF AARGB0,W

MOVWF TEMPB0

MOVF AARGB1,W

MOVWF TEMPB1

;Comienzo de macro

MOVLW 0x8

MOVWF LOOPCOUNT

LOOPSM1616A

RRF BARGB1,F

BTFSC STATUS,C

GOTO ALSM1616NA

DECFSZ LOOPCOUNT,F

GOTO LOOPSM1616A

MOVLW 0x7

MOVWF LOOPCOUNT

LOOPSM1616B
RRF BARGB0,F

BTFSC STATUS,C

GOTO BLSM1616NA

DECFSZ LOOPCOUNT,F

GOTO LOOPSM1616B

CLRF AARGB0

CLRF AARGB1

RETLW 0x00

ALOOPSM1616

RRF BARGB1,F

BTFSS STATUS,C

GOTO ALSM1616NA

MOVF TEMPB1,W

ADDWF AARGB1,F

MOVF TEMPB0,W

BTFSC STATUS,C

INCFSZ TEMPB0,W

ADDWF AARGB0,F

ALSM1616NA

RLF SIGN,W

RRF AARGB0,F

RRF AARGB1,F

RRF AARGB2,F

DECFSZ LOOPCOUNT,F

GOTO ALOOPSM1616
MOVLW 0x7

MOVWF LOOPCOUNT

BLOOPSM1616

RRF BARGB0,F

BTFSS STATUS,C

GOTO BLSM1616NA

MOVF TEMPB1,W

ADDWF AARGB1,F

MOVF TEMPB0,W

BTFSC STATUS,C

INCFSZ TEMPB0,W

ADDWF AARGB0,F

BLSM1616NA

RLF SIGN,W

RRF AARGB0,F

RRF AARGB1,F

RRF AARGB2,F

RRF AARGB3,F

DECFSZ LOOPCOUNT,F

GOTO BLOOPSM1616

RLF SIGN,W

RRF AARGB0,F

RRF AARGB1,F

RRF AARGB2,F

RRF AARGB3,F

;Fin de macro
RETLW 0x00

M1616SX

CLRF AARGB2

CLRF AARGB3

RLF SIGN,W

RRF AARGB0,F

RRF AARGB1,F

RRF AARGB2,F

RETLW 0x00

;
*************************************************************************************
*******

;
*************************************************************************************
*******

; Division de operandos de 8 bits sin signo. AARGB0/BARGB0=AARGB0 + Resto=REMB0

; Parametro de entrada:

; Banco de Trabajo: Banco 1.

; Dividendo (8Bits): (AARGB0)

; Divisor (8Bits): (BARGB0)

; Cociente (8Bits): (AARGB0)

; Resto (8Bits): (REMB0)

Pg2_UDIV_8x8

sBanco1
CLRF REMB0

MOVLW 8

MOVWF LOOPCOUNT

LOOPU0808A

RLF AARGB0,W

RLF REMB0, F

MOVF BARGB0,W

SUBWF REMB0, F

BTFSC STATUS,C

GOTO UOK88A

ADDWF REMB0, F

BCF STATUS,C

UOK88A

RLF AARGB0, F

DECFSZ LOOPCOUNT, F

GOTO LOOPU0808A

RETLW 0x00

;
*************************************************************************************
*******

;
*************************************************************************************
*******

; Division de operandos de 8 bits con signo. AARGB0/BARGB0=AARGB0 + Resto=REMB0

; Parametro de entrada:
; Banco de Trabajo: Banco 1.

; Dividendo (8Bits): (AARGB0)

; Divisor (8Bits): (BARGB0)

; Cociente (8Bits): (AARGB0)

; Resto (8Bits): (REMB0)

Pg2_SDIV_8x8

sBanco1

;FXD0808S

CLRF SIGN

CLRF REMB0 ; clear partial remainder

MOVF AARGB0,W

BTFSC STATUS,Z

RETLW 0x00

XORWF BARGB0,W

MOVWF TEMP

BTFSC TEMP,MSB

COMF SIGN,F

CLRF TEMPB3 ; clear exception flag

BTFSS BARGB0,MSB ; if MSB set, negate BARG

GOTO CA0808S

COMF BARGB0, F

INCF BARGB0, F
CA0808S

BTFSS AARGB0,MSB ; if MSB set, negate AARG

GOTO C0808SX

COMF AARGB0, F

INCF AARGB0, F

C0808SX

MOVF AARGB0,W

IORWF BARGB0,W

MOVWF TEMP

BTFSC TEMP,MSB

GOTO C0808SX1

C0808S

MOVF BARGB0,W

SUBWF REMB0, F

RLF AARGB0, F

RLF AARGB0,W

RLF REMB0, F

MOVF BARGB0,W

ADDWF REMB0, F

RLF AARGB0, F

MOVLW 6

MOVWF LOOPCOUNT

LOOPS0808A
RLF AARGB0,W

RLF REMB0, F

MOVF BARGB0,W

BTFSC AARGB0,LSB

SUBWF REMB0, F

BTFSS AARGB0,LSB

ADDWF REMB0, F

RLF AARGB0, F

DECFSZ LOOPCOUNT, F

GOTO LOOPS0808A

BTFSS AARGB0,LSB

ADDWF REMB0, F

BTFSC TEMPB3,LSB ; test exception flag

GOTO C0808SX4

C0808SOK

BTFSS SIGN,MSB

RETLW 0x00

COMF AARGB0, F

INCF AARGB0, F

COMF REMB0, F

INCF REMB0, F
RETLW 0x00

C0808SX1

BTFSS BARGB0,MSB ; test BARG exception

GOTO C0808SX3

BTFSC AARGB0,MSB ; test AARG exception

GOTO C0808SX2

MOVF AARGB0,W ; quotient = 0, remainder = AARG

MOVWF REMB0

CLRF AARGB0

GOTO C0808SOK

C0808SX2

CLRF AARGB0 ; quotient = 1, remainder = 0

INCF AARGB0,F

RETLW 0x00

C0808SX3

COMF AARGB0,F ; numerator = 0x7F + 1

INCF TEMPB3,F

GOTO C0808S

C0808SX4

INCF REMB0,F ; increment remainder and test for

MOVF BARGB0,W ; overflow

SUBWF REMB0,W

BTFSS STATUS,Z

GOTO C0808SOK

CLRF REMB0 ; if remainder overflow, clear

INCF AARGB0,F ; remainder, increment quotient and


BTFSS AARGB0,MSB ; test for overflow exception

GOTO C0808SOK

BSF FPFLAGS,NAN

RETLW 0xFF

;
*************************************************************************************
*******

;
*************************************************************************************
*******

; Division de operandos de 16 bits sin signo. (A0,A1)/(B1,B0)=(A0,A1) + (R0,R1)

; Parametro de entrada:

; Banco de Trabajo: Banco 1.

; Dividendo (8Bits): (AARGB0,AARGB1)

; Divisor (8Bits): (BARGB0,BARGB1)

; Cociente (8Bits): (AARGB0,AARGB1)

; Resto (8Bits): (REMB0,REMB1)

Pg2_UDIV_16x16

sBanco1

;FXD1616U

CLRF REMB0

CLRF REMB1

MOVLW D'16'

MOVWF LOOPCOUNT
LOOPU1616

RLF AARGB0,W

RLF REMB1, F

RLF REMB0, F

MOVF BARGB1,W

SUBWF REMB1, F

MOVF BARGB0,W

BTFSS STATUS,C

INCFSZ BARGB0,W

SUBWF REMB0, F

BTFSC STATUS,C

GOTO UOK66LL

MOVF BARGB1,W

ADDWF REMB1, F

MOVF BARGB0,W

BTFSC STATUS,C

INCFSZ BARGB0,W

ADDWF REMB0, F

BCF STATUS,C

UOK66LL

RLF AARGB1, F

RLF AARGB0, F

DECFSZ LOOPCOUNT, F

GOTO LOOPU1616
RETLW 0x00

;
*************************************************************************************
*******

;
*************************************************************************************
*******

; Division de operandos de 16 bits con signo. (A0,A1)/(B1,B0)=(A0,A1) + (R0,R1)

; Parametro de entrada:

; Banco de Trabajo: Banco 1.

; Dividendo (8Bits): (AARGB0,AARGB1)

; Divisor (8Bits): (BARGB0,BARGB1)

; Cociente (8Bits): (AARGB0,AARGB1)

; Resto (8Bits): (REMB0,REMB1)

Pg2_SDIV_16x16

sBanco1

;FXD1616S

CLRF SIGN

CLRF REMB0 ; clear partial remainder

CLRF REMB1

MOVF AARGB0,W

IORWF AARGB1,W

BTFSC STATUS,Z

RETLW 0x00
MOVF AARGB0,W

XORWF BARGB0,W

MOVWF TEMP

BTFSC TEMP,MSB

COMF SIGN,F

CLRF TEMPB3 ; clear exception flag

BTFSS BARGB0,MSB ; if MSB set, negate BARG

GOTO CA1616S

COMF BARGB1, F

COMF BARGB0, F

INCF BARGB1, F

BTFSC STATUS,Z

INCF BARGB0, F

CA1616S

BTFSS AARGB0,MSB ; if MSB set, negate AARG

GOTO C1616SX

COMF AARGB1, F

COMF AARGB0, F

INCF AARGB1, F

BTFSC STATUS,Z

INCF AARGB0, F

C1616SX
MOVF AARGB0,W

IORWF BARGB0,W

MOVWF TEMP

BTFSC TEMP,MSB

GOTO C1616SX1

C1616S

RLF AARGB0,W

RLF REMB1, F

RLF REMB0, F

MOVF BARGB1,W

SUBWF REMB1, F

MOVF BARGB0,W

BTFSS STATUS,C

INCFSZ BARGB0,W

SUBWF REMB0, F

RLF AARGB1, F

RLF AARGB0, F

MOVLW D'15'

MOVWF LOOPCOUNT

LOOPS1616

RLF AARGB0,W

RLF REMB1, F

RLF REMB0, F

MOVF BARGB1,W

BTFSS AARGB1,LSB
GOTO SADD66L

SUBWF REMB1, F

MOVF BARGB0,W

BTFSS STATUS,C

INCFSZ BARGB0,W

SUBWF REMB0, F

GOTO SOK66LL

SADD66L

ADDWF REMB1, F

MOVF BARGB0,W

BTFSC STATUS,C

INCFSZ BARGB0,W

ADDWF REMB0, F

SOK66LL

RLF AARGB1, F

RLF AARGB0, F

DECFSZ LOOPCOUNT, F

GOTO LOOPS1616

BTFSC AARGB1,LSB

GOTO SOK66L

MOVF BARGB1,W

ADDWF REMB1, F

MOVF BARGB0,W

BTFSC STATUS,C
INCFSZ BARGB0,W

ADDWF REMB0, F

SOK66L

BTFSC TEMPB3,LSB ; test exception flag

GOTO C1616SX4

C1616SOK

BTFSS SIGN,MSB

RETLW 0x00

COMF AARGB1, F

COMF AARGB0, F

INCF AARGB1, F

BTFSC STATUS,Z

INCF AARGB0, F

COMF REMB1, F

COMF REMB0, F

INCF REMB1, F

BTFSC STATUS,Z

INCF REMB0, F

RETLW 0x00

C1616SX1

BTFSS BARGB0,MSB ; test BARG exception

GOTO C1616SX3

BTFSC AARGB0,MSB ; test AARG exception


GOTO C1616SX2

MOVF AARGB0,W

MOVWF REMB0 ; quotient = 0, remainder = AARG

MOVF AARGB1,W

MOVWF REMB1

CLRF AARGB0

CLRF AARGB1

GOTO C1616SOK

C1616SX2

CLRF AARGB0 ; quotient = 1, remainder = 0

CLRF AARGB1

INCF AARGB1,F

RETLW 0x00

C1616SX3

COMF AARGB0,F ; numerator = 0x7FFF + 1

COMF AARGB1,F

INCF TEMPB3,F

GOTO C1616S

C1616SX4

INCF REMB1,F ; increment remainder and test for

BTFSC STATUS,Z ; overflow

INCF REMB0,F

MOVF BARGB1,W

SUBWF REMB1,W

BTFSS STATUS,Z

GOTO C1616SOK

MOVF BARGB0,W
SUBWF REMB0,W

BTFSS STATUS,Z

GOTO C1616SOK

CLRF REMB0 ; if remainder overflow, clear

CLRF REMB1 ; remainder, increment quotient and

INCF AARGB1,F ; test for overflow exception

BTFSC STATUS,Z

INCF AARGB0,F

BTFSS AARGB0,MSB

GOTO C1616SOK

BSF FPFLAGS,NAN

RETLW 0xFF

;;************************************************************************************
********

;;************************************************************************************
********

;; Division de operandos de 32/16 bits sin signo. (A0,A1,A2,A3)/(B0,B1)=

;;
(A0,A1,A2,A3) + (R0,R1)

;; Parametro de entrada:

;; Banco de Trabajo: Banco 1.

;; Dividendo (32Bits): (AARGB0,AARGB1,AARGB2,AARGB3)

;; Divisor (16Bits): (BARGB0,BARGB1)

;; Cociente (32Bits): (AARGB0,AARGB1,AARGB2,AARGB3)

;; Resto (16Bits): (REMB0,REMB1)

Pg2_UDIV_32x16

sBanco1

;FXD3216U
CLRF REMB0

CLRF REMB1

CLRF TEMP

RLF AARGB0,W

RLF REMB1, F

MOVF BARGB1,W

SUBWF REMB1, F

MOVF BARGB0,W

BTFSS STATUS,C

INCFSZ BARGB0,W

SUBWF REMB0, F

CLRW

BTFSS STATUS,C

MOVLW 1

SUBWF TEMP, F

RLF AARGB0, F

MOVLW 7

MOVWF LOOPCOUNT

LOOPU3216A

RLF AARGB0,W

RLF REMB1, F

RLF REMB0, F

RLF TEMP, F

MOVF BARGB1,W

BTFSS AARGB0,LSB
GOTO UADD26LA

SUBWF REMB1, F

MOVF BARGB0,W

BTFSS STATUS,C

INCFSZ BARGB0,W

SUBWF REMB0, F

CLRW

BTFSS STATUS,C

MOVLW 1

SUBWF TEMP, F

GOTO UOK26LA

UADD26LA

ADDWF REMB1, F

MOVF BARGB0,W

BTFSC STATUS,C

INCFSZ BARGB0,W

ADDWF REMB0, F

CLRW

BTFSC STATUS,C

MOVLW 1

ADDWF TEMP, F

UOK26LA

RLF AARGB0, F

DECFSZ LOOPCOUNT, F

GOTO LOOPU3216A
RLF AARGB1,W

RLF REMB1, F

RLF REMB0, F

RLF TEMP, F

MOVF BARGB1,W

BTFSS AARGB0,LSB

GOTO UADD26L8

SUBWF REMB1, F

MOVF BARGB0,W

BTFSS STATUS,C

INCFSZ BARGB0,W

SUBWF REMB0, F

CLRW

BTFSS STATUS,C

MOVLW 1

SUBWF TEMP, F

GOTO UOK26L8

UADD26L8

ADDWF REMB1, F

MOVF BARGB0,W

BTFSC STATUS,C

INCFSZ BARGB0,W

ADDWF REMB0, F

CLRW

BTFSC STATUS,C

MOVLW 1
ADDWF TEMP, F

UOK26L8

RLF AARGB1, F

MOVLW 7

MOVWF LOOPCOUNT

LOOPU3216B

RLF AARGB1,W

RLF REMB1, F

RLF REMB0, F

RLF TEMP, F

MOVF BARGB1,W

BTFSS AARGB1,LSB

GOTO UADD26LB

SUBWF REMB1, F

MOVF BARGB0,W

BTFSS STATUS,C

INCFSZ BARGB0,W

SUBWF REMB0, F

CLRW

BTFSS STATUS,C

MOVLW 1

SUBWF TEMP, F

GOTO UOK26LB

UADD26LB
ADDWF REMB1, F

MOVF BARGB0,W

BTFSC STATUS,C

INCFSZ BARGB0,W

ADDWF REMB0, F

CLRW

BTFSC STATUS,C

MOVLW 1

ADDWF TEMP, F

UOK26LB

RLF AARGB1, F

DECFSZ LOOPCOUNT, F

GOTO LOOPU3216B

RLF AARGB2,W

RLF REMB1, F

RLF REMB0, F

RLF TEMP, F

MOVF BARGB1,W

BTFSS AARGB1,LSB

GOTO UADD26L16

SUBWF REMB1, F

MOVF BARGB0,W

BTFSS STATUS,C

INCFSZ BARGB0,W

SUBWF REMB0, F
CLRW

BTFSS STATUS,C

MOVLW 1

SUBWF TEMP, F

GOTO UOK26L16

UADD26L16

ADDWF REMB1, F

MOVF BARGB0,W

BTFSC STATUS,C

INCFSZ BARGB0,W

ADDWF REMB0, F

CLRW

BTFSC STATUS,C

MOVLW 1

ADDWF TEMP, F

UOK26L16

RLF AARGB2, F

MOVLW 7

MOVWF LOOPCOUNT

LOOPU3216C

RLF AARGB2,W

RLF REMB1, F

RLF REMB0, F

RLF TEMP, F

MOVF BARGB1,W
BTFSS AARGB2,LSB

GOTO UADD26LC

SUBWF REMB1, F

MOVF BARGB0,W

BTFSS STATUS,C

INCFSZ BARGB0,W

SUBWF REMB0, F

CLRW

BTFSS STATUS,C

MOVLW 1

SUBWF TEMP, F

GOTO UOK26LC

UADD26LC

ADDWF REMB1, F

MOVF BARGB0,W

BTFSC STATUS,C

INCFSZ BARGB0,W

ADDWF REMB0, F

CLRW

BTFSC STATUS,C

MOVLW 1

ADDWF TEMP, F

UOK26LC

RLF AARGB2, F

DECFSZ LOOPCOUNT, F
GOTO LOOPU3216C

RLF AARGB3,W

RLF REMB1, F

RLF REMB0, F

RLF TEMP, F

MOVF BARGB1,W

BTFSS AARGB2,LSB

GOTO UADD26L24

SUBWF REMB1, F

MOVF BARGB0,W

BTFSS STATUS,C

INCFSZ BARGB0,W

SUBWF REMB0, F

CLRW

BTFSS STATUS,C

MOVLW 1

SUBWF TEMP, F

GOTO UOK26L24

UADD26L24

ADDWF REMB1, F

MOVF BARGB0,W

BTFSC STATUS,C

INCFSZ BARGB0,W

ADDWF REMB0, F

CLRW

BTFSC STATUS,C
MOVLW 1

ADDWF TEMP, F

UOK26L24

RLF AARGB3, F

MOVLW 7

MOVWF LOOPCOUNT

LOOPU3216D

RLF AARGB3,W

RLF REMB1, F

RLF REMB0, F

RLF TEMP, F

MOVF BARGB1,W

BTFSS AARGB3,LSB

GOTO UADD26LD

SUBWF REMB1, F

MOVF BARGB0,W

BTFSS STATUS,C

INCFSZ BARGB0,W

SUBWF REMB0, F

CLRW

BTFSS STATUS,C

MOVLW 1

SUBWF TEMP, F

GOTO UOK26LD

UADD26LD
ADDWF REMB1, F

MOVF BARGB0,W

BTFSC STATUS,C

INCFSZ BARGB0,W

ADDWF REMB0, F

CLRW

BTFSC STATUS,C

MOVLW 1

ADDWF TEMP, F

UOK26LD

RLF AARGB3, F

DECFSZ LOOPCOUNT, F

GOTO LOOPU3216D

BTFSC AARGB3,LSB

GOTO UOK26L

MOVF BARGB1,W

ADDWF REMB1, F

MOVF BARGB0,W

BTFSC STATUS,C

INCFSZ BARGB0,W

ADDWF REMB0, F

UOK26L

RETLW 0x00
;;Estamos aproximadamente al final de la pagina 2 de codigo FLASH

ORG 0x1730 ;Comienzo de Zona de Flash Data hasta 0x17F7 200 posiciones.

Pg2_FLASH_DATA_Inicio

dt "www.MICROLADDER.com Indytel Sistemas SL."

dt "Sistema Operativo ML_CHIP1 "

dt " "

dt " "

dt " "

;Cada posición es un retlw del valor que hayamos puesto como caracter.

;;Estamos aproximadamente al final de la pagina 2 de codigo FLASH

ORG 0x17F8 ;Esto es necesario porque la escritura en FLASH esta alineada en

;4 palabras.

nop

ORG 0x17F9

Pg2_Byte_ConfiguracionIO_1

retlw 0x01 ;No hay entradas analogicas

Pg2_Byte_ConfiguracionIO_2

retlw 0x00 ;No hay controladores especiales, i2c,lcd,...

Pg2_Byte_ConfiguracionIO_3

retlw 0xFF ;Todas Entradas Digitales

Pg2_Byte_ConfiguracionIO_4

retlw 0xFF ;Todas Entradas Digitales

Pg2_Byte_ConfiguracionIO_5

retlw 0xFF ;Todas Entradas Digitales

Pg2_Byte_ConfiguracionIO_6

retlw 0xFF ;Todas Entradas Digitales

Pg2_Byte_ConfiguracionIO_7

retlw 0xFF ;Todas Entradas Digitales


;Ya estamos en pagina 3

ORG 0x1800

Pg3_ProgramaLadder

retlw 0x7F

EndMemoriaFlash

ORG 0x1F10 ;Ponemos esto para que si no se termina de grabar bien

;el programa FLASH no pete en RUN

retlw 0x7F

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Pg3_WriteED

sBanco0

movf BUFFER_RX_3,W ;Tamaño de datos

btfsc STATUS,Z ;Si es cero salimos

goto Pg3_WriteED_end

; Parametro de entrada:

; B0:LOCAL_0 direccion EEPROM donde escribir

; B0:LOCAL_1 Valor a Escribir

movf 0x2E,W ;Direccion donde escribir

movwf LOCAL_0

movlw 0x2F
movwf FSR

bcf STATUS,IRP ;Selecciona el banco 0 en direccionamiento indirecto

swapf INDF,W

movwf LOCAL_1

incf FSR,F

movf INDF,W

andlw 0x0F

iorwf LOCAL_1,F

pPagina0

call Pg0_EscribirEnEEPROM

pPagina3

Pg3_WriteED_end

;Mandamos el ACK de Linea Bloque ON-LINE

clrf BUFFER_RX_3 ;Tamaño de datos : 0

movlw .19 ;Cargamos el comando .19

movwf BUFFER_RX_2

pPagina0

call mandar_trama_a_maestro

pPagina3

return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Pg3_ReadED

sBanco0

; Parametro de entrada:

; B0:LOCAL_0 direccion EEPROM donde escribir

; B0:LOCAL_1 Valor a Escribir

movf 0x2E,W ;Direccion a leer

movwf LOCAL_0

; Parametro de entrada:

; B0:LOCAL_0 direccion EEPROM donde leer.

; W: Devuelve el valor en el acumulador.

pPagina0

call Pg0_LeerDeEEPROM

pPagina3

sBanco0

movwf LOCAL_1 ;Aqui tenemos el valor devuelto

swapf LOCAL_1,W

andlw 0x0F

movwf 0x2F

movf LOCAL_1,W

andlw 0x0F

movwf 0x30

Pg3_ReadED_end

;Mandamos el ACK de Linea Bloque ON-LINE

movlw .3

movwf BUFFER_RX_3 ;Tamaño de datos : 3 (Direccion leida y datos (2 nibbles)


;movlw .20 ;Cargamos el comando .19

;movwf BUFFER_RX_2

pPagina0

call mandar_trama_a_maestro

pPagina3

return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Pg3_PonerCPUaSTOP

sBanco3

clrf B3_ByteIO_P1_p8

clrf B3_ByteIO_P9_p16

clrf B3_ByteIO_P17_p24

clrf B3_ByteIO_P25_p32

clrf B3_ByteIO_P33_p40

;bsf PCLATH,3

pPagina1

call Pg1_EntradasSalidas

pPagina3

;bcf PCLATH,3

sBanco0

bcf B0_bPLConRUN;Bit de CPU en RUN.

return
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Pg3_LimpiarZonaLCD

;Vamos a limpiar el Banco1 la zona del LCD

bcf STATUS,IRP ;Direccionamiento indirecto Bancos 0-1

movlw 0x27

iorlw 0x80

movwf FSR

Pg3_LimpiezaZonaLCD

movlw ' '

movwf INDF

incf FSR,F ;Incrementamos FSR

movlw 0x4E

addlw .1

iorlw 0x80

subwf FSR,W ;Le restamos FSR y lo dejamos en W

btfss STATUS,Z ;Comprobamos si es cero la resta

goto Pg3_LimpiezaZonaLCD

bcf STATUS,IRP

return

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

Pg3_RespondeTramaVersion

;ping-pong
sBanco0

;Ponemos el MLCHIP y version

movlw .2

movwf BUFFER_RX_3 ;Tamaño de datos utiles: 2

movlw .1

movwf 0x2E ;MLCHIP1

movwf 0x2F ;Version 1

pPagina0

call mandar_trama_a_maestro

pPagina3

return

org 0x1FFF

nop

end ;Fin del programa fuente

También podría gustarte