; ___________ ; C2 -> PA,2 -|1 \__/ 18|- PA,1 <- C1 ; NC -|2 17|- PA,0 <- C0 ; NC -|3 16F84A 16|- RC ; MCLR/ -|4 15|- RC ; GND -|5 14|- Vcc ; A -> PB,0 -|6 13|- PB,7 -> Y2 ; B -> PB,1 -|7 12|- PB,6 -> Y1 ; C -> PB,2 -|8 11|- PB,5 -> Y0 ; D -> PB,3 -|9________10|- NC ; ;Según el estado de las entradas de control C2,C1,C0, en las salidas ;Y2, Y1, Y0 aparecerá el estado que corresponderá a una función ;predefinida para las variables de entrada D, C, B, A: ;C2 C1 C0 Función lógica en Y0 ;0 0 0 Y=A+B+C+D OR ;0 0 1 Y=A*B*C*D AND ;0 1 0 Y=/[A+B+C+D] NOR ;0 1 1 Y=/[A*B*C*D] NAND ;1 0 0 Y=A(+)B(+)C(+)D OR-Exclusiva ;1 0 1 Y=/[A(+)B(+)C(+)D] NOR-Exclusiva ;C2 C1 C0 Suma binaria en Y2 Y1 Y0 de DC y BA ;1 1 0 Y2.Y1.Y0 = DC + BA (Ejemplo: 11 + 11 = 110) ;C2 C1 C0 Contador cíclico programable ;1 1 1 'Y0'= 1 si se alcanza un número de pulsos en la entrada 'D' ;igual al valor numérico en 'CBA' multiplicado por 10. ;(la combinación '000' en 'CBA' pone 'Y0' a 1 permanentemente.) ;Ejemplo: 'CBA' = 101 (binario) = 5 (decimal); 'Y' = 1 cuando se ;introduzca el pulso 50 en 'D'. ;Cada vez que se termine una operacion y se quiera ejecutar otra ;primero colocamos los interruptores C2,C1,C0,A,B,C,D en la posicion ;deseada y despues pulsamos el pulsador de reset. RADIX Dec ; Si no se especifica el trato del numero LIST P=PIC16F84A ; Pic a usar #INCLUDE ; Lista de etiquetas de microchip ; Fuses, configuran opciones externas de hardware para la programacion __CONFIG _CP_OFF & _PWRTE_ON & _WDT_OFF & _RC_OSC ; Lista de variables para el uso del programa VarA EQU 0x0C ; Variable A son de 8bit y solo usamos 1 VarB EQU 0x0D ; Variable B VarC EQU 0x0E ; Variable C VarD EQU 0x0F ; Variable D RESULTADO EQU 0x10 ; Guardaremos aqui el resultado de las operaciones VarBA EQU 0x11 ; Variable BA VarDC EQU 0x12 ; Variable DC VarCBA EQU 0x13 ; Variable CBA MULT EQU 0x14 ; Variable del multiplicador CONTADOR EQU 0x15 ; Define una funcion a una palabra #Define Y0 PORTB,5 ; Salidas #Define Y1 PORTB,6 ; #Define Y2 PORTB,7 ; #Define IA PORTB,0 ; Entradas, nomenclatura de Input A #Define IB PORTB,1 ; se usa asi porque B o C ya son #Define IC PORTB,2 ; registros del PIC y dan conflicto #Define ID PORTB,3 ; C0, C1 y C2 no se leen una a una, sino el registro completo ; Por lo que no hace falta definirlas ; Vector de inicio, aqui realmente empezaria la ejecucion del programa ORG 0 ; Vector de Reset goto INICIO ;--------------Confuguracion del PIC----------------------------------------- INICIO bsf STATUS,RP0 ; Accedemos al banco 1 para configurar movlw b'10000000' ; Configuracion de OPTION_REG movwf OPTION_REG ; movlw b'00111' ; movwf TRISA movlw b'00001111' movwf TRISB bcf STATUS,RP0 ; Volvemos al banco 0 clrf PORTB ; A 0 todas las salidas clrf PORTA ; Programa ;---------- Paso de bits a bytes ---------------------------------- ; Las operaciones logicas ANDLW, IORLW etc, trabajan con bytes por ; lo que para la operacion con un solo bit hemos de tomar bit a bit ; Se hace siempre antes de las operaciones y solo sirve para las 5 ; primeras funciones. btfss IA ; Si bit0 de PB=0, bit0 de VarA=0 bcf VarA,0 btfsc IA ; Si bit0 de PB=1, bit0 de VarA=1 bsf VarA,0 btfss IB ; Si bit1 de PB=0, bit0 de VarB=0 bcf VarB,0 btfsc IB ; Si bit1 de PB=1, bit0 de VarB=1 bsf VarB,0 btfss IC ; Si bit2 de PB=0, bit0 de VarC=0 bcf VarC,0 btfsc IC ; Si bit2 de PB=1, bit0 de VarC=1 bsf VarC,0 btfss ID ; Si bit3 de PB=0, bit0 de VarC=0 bcf VarD,0 btfsc ID ; Si bit3 de PB=1, bit0 de VarC=1 bsf VarD,0 movf PORTA,W ; PCL es el contador de programa, si le addwf PCL,F ; sumo hace un salto igual al numero sumado goto OR ; 0 0 0 Y=A+B+C+D goto AND ; 0 0 1 Y=A*B*C*D goto NOR ; 0 1 0 Y=/[A+B+C+D] goto NAND ; 0 1 1 Y=/[A*B*C*D] goto OREX ; 1 0 0 Y=A(+)B(+)C(+)D goto NOREX ; 1 0 1 Y=/[A(+)B(+)C(+)D] goto SUMABIN ; 1 1 0 AB + CD en Y0 Y1 Y2 goto CONT ; 1 1 1 Contador ciclico ; --------- OPERACION OR ------------------------------------------ ; Y=A+B+C+D OR movf VarA,W ; Contenido de VarA al acumulador iorwf VarB,W ; or de W y VarB con resultado en W iorwf VarC,W ; or de W y VarC iorwf VarD,W movwf RESULTADO ; El resultado final guardado en btfss RESULTADO,0 ; RESULTADO bcf Y0 ; Comprobamos el bit0 que es el que btfsc RESULTADO,0 ; contiene el resultado de la operacion bsf Y0 ; para despues pasarlo a la salida Y0 goto $ ;Nota: $ equivale a la direccion actual del PC ; --------- OPERACION AND ----------------------------------------- ; Y=A*B*C*D AND movf VarA,W andwf VarB,W andwf VarC,W andwf VarD,W movwf RESULTADO ; El resultado final guardado en btfss RESULTADO,0 ; RESULTADO. bcf Y0 ; Comprobamos el bit0 que es el que btfsc RESULTADO,0 ; contiene el resultado de la operacion bsf Y0 ; para despues pasarlo a la salida Y0 goto $ ; --------- OPERACION NOR ------------------------------------------ ; Y=/[A+B+C+D] NOR movf VarA,W ; Contenido de VarA al acumulador iorwf VarB,W ; or de W y VarB con resultado en W iorwf VarC,W ; or de W y VarC iorwf VarD,W movwf RESULTADO ; El resultado final guardado en btfss RESULTADO,0 ; RESULTADO bsf Y0 ; Comprobamos el bit0 que es el que btfsc RESULTADO,0 ; contiene el resultado de la operacion bcf Y0 ; para despues pasarlo a la salida Y0 ; de forma invertida. goto $ ; --------- OPERACION NAND ----------------------------------------- ; Y=/[A*B*C*D] NAND movf VarA,W andwf VarB,W andwf VarC,W andwf VarD,W movwf RESULTADO ; El resultado final guardado en btfss RESULTADO,0 ; RESULTADO. bsf Y0 ; Comprobamos el bit0 que es el que btfsc RESULTADO,0 ; contiene el resultado de la operacion bcf Y0 ; para despues pasarlo a la salida Y0 ; de forma invertida goto $ ; --------- OPERACION OR EXCLUSIVA -------------------------------- ; Y=A(+)B(+)C(+)D OREX movf VarA,W xorwf VarB,W xorwf VarC,W xorwf VarD,W movwf RESULTADO ; Copiamos W a RESULTADO btfss RESULTADO,0 ; RESULTADO. bcf Y0 ; Comprobamos el bit0 que es el que btfsc RESULTADO,0 ; contiene el resultado de la operacion bsf Y0 ; para despues pasarlo a la salida Y0 goto $ ; --------- OPERACION OR EXCLUSIVA -------------------------------- ; Y=/[A(+)B(+)C(+)D] NOREX movf VarA,W xorwf VarB,W xorwf VarC,W xorwf VarD,W movwf RESULTADO btfss RESULTADO,0 ; RESULTADO. bsf Y0 ; Comprobamos el bit0 que es el que btfsc RESULTADO,0 ; contiene el resultado de la operacion bcf Y0 ; para despues pasarlo a la salida Y0 ; invertido goto $ ; --------- SUMA BINARIA DE AB + DC ------------------------------- ; AB + DC con resultado en Y0 Y1 Y2 ; Pasamos los bit de entrada a dos registros independientes VarBA ; y VarDC para poder sumarlos SUMABIN btfss IA ; Si bit0 de PB=0, bit0 de VarBA=0 bcf VarBA,0 btfsc IA ; Si bit0 de PB=1, bit0 de VarBA=1 bsf VarBA,0 btfss IB ; Si bit1 de PB=0, bit1 de VarBA=0 bcf VarBA,1 btfsc IB ; Si bit1 de PB=1, bit1 de VarBA=1 bsf VarBA,1 btfss IC ; Si bit2 de PB=0, bit0 de VarDC=0 bcf VarDC,0 btfsc IC ; Si bit2 de PB=1, bit0 de VarDC=1 bsf VarDC,0 btfss ID ; Si bit3 de PB=0, bit1 de VarDC=0 bcf VarDC,1 btfsc ID ; Si bit3 de PB=1, bit1 de VarDC=1 bsf VarDC,1 movf VarBA,W ; Pasamos el contenido de VarAB al addwf VarDC,W ; acumulador y lo sumamos con VarDC, ; el resultado de la operacion en W. movwf RESULTADO ; Acumulador a RESULTADO. rlf RESULTADO,F ; rotamos el registro 5 bit a la rlf RESULTADO,F ; izquierda guardando el resultado rlf RESULTADO,F ; en el mismo registro, es para colocar rlf RESULTADO,F ; los bits en posicion de salida de PB. rlf RESULTADO,W ; movwf PORTB ; Resultado a la salidas Y0,Y1,Y2 goto $ ; --------- CONTADOR CICLICO -------------------------------------- ; Pasamos las entradas a 3 bits de menor peso de la variable VarCBA CONT clrf VarCBA btfss IA ; Si bit0 de PB=0, bit0 de VarCBA=0 bcf VarCBA,0 btfsc IA ; Si bit0 de PB=1, bit0 de VarCBA=1 bsf VarCBA,0 btfss IB ; Si bit1 de PB=0, bit1 de VarCBA=0 bcf VarCBA,1 btfsc IB ; Si bit1 de PB=1, bit1 de VarCBA=1 bsf VarCBA,1 btfss IC ; Si bit2 de PB=0, bit2 de VarCBA=0 bcf VarCBA,2 btfsc IC ; Si bit2 de PB=1, bit2 de VarCBA=1 bsf VarCBA,2 ; Multiplicacion por 10 ; La multiplicacion se hace sumando MULT veces el numero leido en VarCBA movlw d'9' ; Cargamos un contador con 10 en dec (mult *10) movwf MULT ; que sera el numero a multiplicar. movf VarCBA,W ; Copiamos VarCBA al acumulador. btfsc STATUS,Z ; Verificamos si es=000 CBA goto ContFIN ; si es 000 Y0=1. addwf VarCBA,F ; Sumamos W al VarCBA y guardamos en VarCBA. decfsz MULT,F ; Resta 1 a MULT y si el contenido de MULT goto $-2 ; es=0 sale del bucle ; $-2 retrocede 2 intrucciones ; Ahora vamos capturando los pulsos en la entrada D ; Incremento del contador a nivel alto INICcont clrf CONTADOR NEXT btfss ID ; Esperamos a que se pulse D (D=1) goto $-1 incf CONTADOR,F ; Incremento 1 el contador y guardamos ; el resultado en contador. movf VarCBA,W ; Una comparacion de 2 numeros se hace con subwf CONTADOR,W ; una resta y verificacion si=0 el resultado. btfsc STATUS,Z ; Verificacion si el resultado de goto ContFIN ; CONTADOR-VarCBA=0, si lo es, goto ContFIN btfsc ID ; Esperamos a que se deje de pulsar goto $-1 ; y comprobamos si vuelve a pulsarse goto NEXT ContFIN bsf Y0 ; Y0=1 goto $ END