Tablas indexado de 8 bits.

Iniciado por Meta, 28 Agosto 2010, 06:52 AM

0 Miembros y 1 Visitante están viendo este tema.

Meta

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.
Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/

Tokes

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.

Tokes

#2
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.

Código (asm) [Seleccionar]
; 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.

Meta

#3
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.
Tutoriales Electrónica y PIC: http://electronica-pic.blogspot.com/

Tokes

#4
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:

Código (asm) [Seleccionar]
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