Hola:
Como pueden ver el código de abajo. Se utiliza 3 bits de entrada para una tabla de la verdad. 8 Configuraciones en total. Está muy bien para hacer un decoder. Viendo que quiero hacer uno de 8 bits, 8 entradas para la tabla de la verdad, obtiene 256 Configuraciones. Tardaría años en configurarlas todas. No quiero usar TTL decoder a parte, sólo con PIC.
¿Existe una manera de hacer esta tabla sin tardar demasiado tiempo en hacer 256 configuraciones?
El ejemplo de abajo son de 8 configuraciones y no me parece mucho, pero 256 es la eternidad.
; Controla el nivel de un depósito de líquido. Utiliza (entre paréntesis las líneas del
; microcontrolador a la que se han conectado):
; - Tres sondas detectoras: SV, Sonda de Vacío (RA0); SLL, Sonda de LLenado (RA1);
; SR, Sonda de Rebose (RA2).
; - Dos bombas de agua: B1 (RB5), B2 (RB6).
; - Cinco indicadores: Vacio (RB0), Llenandose (RB1), Lleno (RB2), Rebose (RB3),
; Alarma (RB4).
;
; Su funcionamiento:
; - Cuando ninguna de las sondas está mojada se entiende que el depósito está vacío y
; se accionarán las dos bombas. El indicador "Vacio" se iluminará .
; - Cuando el nivel del líquido toque la sonda de vacío "SV" seguirá llenándose el
; depósito con las dos bombas. El indicador "Llenandose" se ilumina.
; - Cuando el nivel del líquido toca la sonda de llenado "SLL", para la bomba B2, quedando
; B1 activada en modo mantenimiento. El indicador "Lleno" se ilumina.
; - Si el nivel del líquido moja la sonda de rebose "SR" se apaga también la bomba B1,
; quedando las dos bombas fuera de servicio. El indicador "Rebose" se enciende.
; - Cuando se produce un fallo o mal funcionamiento en las sondas de entrada (por
; ejemplo que se active la sonda de rebose y no active la de vacío) se paran
; las dos bombas. El indicador "Alarma" se ilumina.
;
; Según el enunciado del problema, teniendo en cuenta las conexiones citadas y poniendo la
; salida no utilizada (RB7) siempre a cero, la tabla de verdad resultante es:
;
; RA2.. RA0 | RB7 ... ... RB0
; ------------|--------------------------------
; 0 0 0 | 0 1 1 0 0 0 0 1 (Configuración 0. Estado "Vacio").
; 0 0 1 | 0 1 1 0 0 0 1 0 (Configuración 1. Estado "Llenandose").
; 0 1 0 | 0 0 0 1 0 0 0 0 (Configuración 2. Estado "Alarma").
; 0 1 1 | 0 0 1 0 0 1 0 0 (Configuración 3. Estado "Lleno").
; 1 0 0 | 0 0 0 1 0 0 0 0 (Configuración 4. Estado "Alarma").
; 1 0 1 | 0 0 0 1 0 0 0 0 (Configuración 5. Estado "Alarma").
; 1 1 0 | 0 0 0 1 0 0 0 0 (Configuración 6. Estado "Alarma").
; 1 1 1 | 0 0 0 0 1 0 0 0 (Configuración 7. Estado "Rebose").
;
; ZONA DE DATOS **********************************************************************
LIST P=16F84A
INCLUDE <P16F84A.INC>
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
; ZONA DE CÓDIGOS ********************************************************************
ORG 0 ; El programa comienza en la dirección 0.
Inicio
clrf PORTB ; Debe estar a cero cuando el puerto se configure como salida.
bsf STATUS,RP0 ; Acceso al Banco 1.
clrf TRISB ; Las líneas del Puerto B se configuran como salida.
movlw b'00011111' ; Las 5 líneas del Puerto A se configuran como entrada.
movwf TRISA
bcf STATUS,RP0 ; Acceso al Banco 0.
Principal
movf PORTA,W ; Lee los sensores.
andlw b'00000111' ; Máscara para quedarse con el valor de los sensores.
addwf PCL,F ; Salta a la configuración adecuada.
goto Configuracion0
goto Configuracion1
goto Configuracion2
goto Configuracion3
goto Configuracion4
goto Configuracion5
goto Configuracion6
goto Configuracion7
Configuracion0
movlw b'01100001' ; Estado "Vacio" (configuración 0).
goto ActivaSalida
Configuracion1
movlw b'01100010' ; Estado "Llenándose" (configuración 1).
goto ActivaSalida
Configuracion2
movlw b'00010000' ; Estado "Alarma" (configuración 2).
goto ActivaSalida
Configuracion3
movlw b'00100100' ; Estado "Lleno" (configuración 3).
goto ActivaSalida
Configuracion4
movlw b'00010000' ; Estado "Alarma" (configuración 4).
goto ActivaSalida
Configuracion5
movlw b'00010000' ; Estado "Alarma" (configuración 5).
goto ActivaSalida
Configuracion6
movlw b'00010000' ; Estado "Alarma" (configuración 6).
goto ActivaSalida
Configuracion7
movlw b'00001000' ; Estado "Rebose" (configuración 7).
ActivaSalida
movwf PORTB ; Visualiza por el puerto de salida.
goto Principal
END
Un cordial saludo.
Hola, Meta:
Pues dependiendo de lo que se tenga que hacer será la implementación de la lógica. Si todas las 256 combinaciones son significativas, entonces habrá que implementar la tabla completa. Pero si no todas son significativas (condiciones no importa) entonces se puede hacer testeando bits individualmente.
Puedes explicar, si quieres, lo que deseas hacer con las 8 entradas, y tal vez se te pueda ayudar más.
Saludos.
Mira, aquí te dejo un código que utiliza una macro. En ese códgo sólo se toman en cuenta los valores de entrada que son válidos; los valores de entrada que no sean válidos conducirán a una alarma.
; Decodificador
; Autor: TKS
LIST P=16F84A
INCLUDE <P16F84A.INC>
__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC
CONSTANT E1=B'000', E2=B'001', E3=B'011', E4=B'111'
CONSTANT S1=B'01100001', S2=B'01100010', S3=B'00100100', S4=B'00001000'
CONSTANT ENTRADAS_VALIDAS=4
LEE_ACTIVA MACRO ENTRADA, SALIDA
LOCAL NO_ES
MOVF PORTA,W
ANDLW B'00000111'
XORLW ENTRADA
BTFSS STATUS,Z
GOTO NO_ES
MOVLW SALIDA
MOVWF PORTB
GOTO CICLO
NO_ES
ENDM
ORG 0
CLRF PORTB
BSF STATUS,RP0
MOVLW 0xFF
MOVWF TRISA
CLRF TRISB
BCF STATUS,RP0
CICLO
VARIABLE I
I=0
WHILE I<ENTRADAS_VALIDAS
LEE_ACTIVA E#V(I+1), S#V(I+1)
I+=1
ENDW
MOVLW B'00010000'
MOVWF PORTB
GOTO CICLO
END
Los valores de entrada válidos se declaran:
CONSTANT E1=B'000', E2=...
Los valores de salida válidos se declaran:
CONSTANT S1=B'01100001', S2=...
La cantidad de combinaciones de entrada válidas se declara:
CONSTANT ENTRADAS_VALIDAS=4
La macro llamada LEE_ACTIVA contiene un código que lee el valor del PORTA y lo compara con un valor válido de entrada, especificado en el argumento ENTRADA. Si el PORTA es igual al valor ENTRADA, se envía al PORTB el correspondiente valor de salida, especificado en el argumento SALIDA, y posteriormente, regresa a la etiquet CICLO.
El bucle WHILE lo que hace es generar tantas veces el código de la macro como sea necesario, en este caso, 4 veces, ya que sólo hay 4 valores de entrada válidos.
Cada vez que se ejcute la macro, si el valor de PORTA coincide con el valor de entrada especificado, cargará un valor en PORTB y regresará a CICLO. Si el valor de PORTA no coincide con el valor de entrada especificado, brincará más adelante.
Por lo tanto, si el código llega a la parte:
MOVLW B'00010000'
MOVWF PORTB
GOTO CICLO
quiere decir que el PORTA no coincide con ningún valor de entrada válido, por eso activa la alarma.
Ahora, para el caso de las 8 entradas y las 256 combinaciones, supongamos que sólo 100 combinaciones són válidas. En ese caso sólo se declaran las 100 combinaciones de entrada y las 100 combinaciones de salida al principio del programa, además de declarar:
CONSTANT ENTRADAS_VALIDAS=d'100'
Lo demás se queda igual. Eso es todo por el momento. Saludos.
Hola:
Muchas gracias por la explicación. No se me había ocurrido crear usar macros.
Te me has delantado ya que te iba a poner esta explicación de lo que quiero decite.
Hola:
Ese es el problema, no liar la parda cmabiando los contadores. En el primer ejemplo que puse, me pareció mucho poner los 256 configuraciones, sólo llegué a 53 y me cansé. A parte que no voy a utilizar las 256 combinaciones que hay usando los 8 pines de un puerto del PIC.
Con los ejemplos que he puesto. ¿Entiendes a lo que quiero llegar?
Configuración0 Configuración1 Configuración2 Configuración3 Configuración4 Configuración5 Configuración6 Configuración7 Configuración8 Configuración9 Configuración10 Configuración11 Configuración12 Configuración13 Configuración14 Configuración15 Configuración16 Configuración17 Configuración18 Configuración19 Configuración20 Configuración21 Configuración22 Configuración23 Configuración24 Configuración25 Configuración26 Configuración27 Configuración28 Configuración29 Configuración30 Configuración31 Configuración32 Configuración33 Configuración34 Configuración35 Configuración36 Configuración37 Configuración38 Configuración39 Configuración40 Configuración41 Configuración42 Configuración43 Configuración44 Configuración45 Configuración46 Configuración47 Configuración48 Configuración49 Configuración50 Configuración51 Configuración52 Configuración53
Como muestra el primer ejemplo.
movf PORTA,W ; Lee los sensores.
andlw b'00000111' ; Máscara para quedarse con el valor de los sensores.
addwf PCL,F ; Salta a la configuración adecuada.
goto Configuracion0
goto Configuracion1
goto Configuracion2
goto Configuracion3
goto Configuracion4
goto Configuracion5
goto Configuracion6
goto Configuracion7
Configuracion0
movlw b'01100001' ; Estado "Vacio" (configuración 0).
goto ActivaSalida
Configuracion1
movlw b'01100010' ; Estado "Llenándose" (configuración 1).
goto ActivaSalida
Configuracion2
movlw b'00010000' ; Estado "Alarma" (configuración 2).
goto ActivaSalida
Configuracion3
movlw b'00100100' ; Estado "Lleno" (configuración 3).
goto ActivaSalida
Configuracion4
movlw b'00010000' ; Estado "Alarma" (configuración 4).
goto ActivaSalida
Configuracion5
movlw b'00010000' ; Estado "Alarma" (configuración 5).
goto ActivaSalida
Configuracion6
movlw b'00010000' ; Estado "Alarma" (configuración 6).
goto ActivaSalida
Configuracion7
movlw b'00001000' ; Estado "Rebose" (configuración 7).
ActivaSalida
movwf PORTB ; Visualiza por el puerto de salida.
goto Principal
END
No sólo desea activar salidas 1 y 0. También quiero añadirle más códigos.
Configuracion0
movlw b'01100001' ; Estado "Vacio" (configuración 0).
goto ActivaSalida
Configuracion1
movlw b'01100010' ; Estado "Llenándose" (configuración 1).
goto ActivaSalida
Configuracion2
movlw b'00010000' ; Estado "Alarma" (configuración 2).
goto ActivaSalida
Configuracion3
movlw b'00100100' ; Estado "Lleno" (configuración 3).
goto ActivaSalida
Configuracion4
movlw b'00010000' ; Estado "Alarma" (configuración 4).
goto ActivaSalida
Configuracion5
movlw b'00010000' ; Estado "Alarma" (configuración 5).
goto ActivaSalida
Configuracion6
movlw b'00010000' ; Estado "Alarma" (configuración 6).
goto ActivaSalida
Configuracion7
movlw b'00001000' ; Estado "Rebose" (configuración 7).
ActivaSalida
movwf PORTB ; Visualiza por el puerto de salida.
goto Principal
Quiero insertarle más códigos como el ejemplo de abajo.
Citar
Configuracion0
call LCD_LineaEnBlanco
call LCD_Linea1
movlw Mensaje3_1
call LCD_Mensaje
call LCD_Linea2
movlw Mensaje3_2
call LCD_Mensaje
movlw b'01100001' ; Estado "Vacio" (configuración 0).
goto ActivaSalida
Configuracion1
call LCD_LineaEnBlanco
call LCD_Linea1
movlw Mensaje78_1
call LCD_Mensaje
call LCD_Linea2
movlw Mensaje5_msn
call LCD_Mensaje
movlw b'01100010' ; Estado "Llenándose" (configuración 1).
goto ActivaSalida
Configuracion2
call LCD_LineaEnBlanco
call LCD_Linea1
movlw Mensaje4_1
call LCD_Mensaje
call LCD_LineaEnBlanco
call LCD_Linea2
movlw Mensaje4_2
call LCD_Mensaje
call LCD_LineaEnBlanco
call LCD_Linea3
movlw Mensaje3_1
call LCD_Mensaje
call LCD_LineaEnBlanco
call LCD_Linea4
movlw Mensaje3_2
call LCD_Mensaje
movlw b'00010000' ; Estado "Alarma" (configuración 2).
goto ActivaSalida
Configuracion3
movlw b'00100100' ; Estado "Lleno" (configuración 3).
goto ActivaSalida
Configuracion4
movlw b'00010000' ; Estado "Alarma" (configuración 4).
goto ActivaSalida
Configuracion5
movlw b'00010000' ; Estado "Alarma" (configuración 5).
goto ActivaSalida
Configuracion6
movlw b'00010000' ; Estado "Alarma" (configuración 6).
goto ActivaSalida
Configuracion7
movlw b'00001000' ; Estado "Rebose" (configuración 7).
ActivaSalida
movwf PORTB ; Visualiza por el puerto de salida.
goto Principal
Lo azul es donde inyecté más códigos para ejecutar. Esta es la idea si usas sólo 8 Configuraciones, no es cuestión usar esa técnica si son 256 configuraciones, me da algo si lo hago, aunque estaba a punto de hacerlo, pero me entró depresión.
Por eso quiero buscar la mejor forma de usar un buen decoder solo usando las entradas que reconozca e ignora las que no conozcas y que se pueda poner más códigos en las configuraciones, no sólo una línea de código.
Saludo.
Mi estimado Meta:
Para borrar una línea del LCD primero tienes que posicionar el cursor al principio de esa línea, luego invocas a LCD_LineaEnBlanco y luego debes volverte a posicionar al principio de esa línea. Para que no sea tan tedioso puedes hacer subrutinas que borren las líneas. Ejemplo:
LCD_Linea1EnBlanco
call LCD_Linea1
call LCD_LineaEnBlanco
call LCD_Linea1
return
LCD_Linea2EnBlanco
call LCD_Linea2
call LCD_LineaEnBlanco
call LCD_Linea2
return
LCD_Linea3EnBlanco
call LCD_Linea3
call LCD_LineaEnBlanco
call LCD_Linea3
return