Autor Tema: AYUDA, MULTIPLICACIÓN EN EL PUERTO A CON EL PUERTO B Y MOSTRARLO EN EL PUERTO B  (Leído 3731 veces)

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

Desconectado JuanMendoza04

  • PIC10
  • *
  • Mensajes: 3
Tengo éste ejercicio pero no se como empezar.

Multiplicar el valor introducido mediante 3 interruptores conectados a la línea RA1-RA3 del puerto A con el introducido por 3 interruptores conectados a las lineas RB0-RB2 del puerto B, el resultado de la multiplicación debe visualizarse en RB3-RB7 del puerto B

Tengo este codigo no se que me falta o si esta mal.

LIST P=16F84A ;Indica el modelo de PIC que se usa
              ;Es un directiva del ensamblador
RADIX HEX     ;Los valores se representan en hexadesimal
        
PUERTAA EQU 0x05 ; Define la posicion del PUERTAA
PUERTAB EQU 0x06 ; Define la posicion del PUERTA
ESTADO    EQU   0x03 ;EL ESTADO
ENTRADA1 EQU 0x0C ; Define la posicion del entrada1
ENTRADA2 EQU 0x0D ; Define la posicion del entrada2
TEMPSALIDA EQU 0x10

org 0   

  bsf ESTADO,5   ;pone a 1 a el bit 5 de estado
        ;para direccionar el banco 1
        ;de la memoria de datos
  movlw  0X0E
  movwf PUERTAA        
  movlw 0X07  ;w entradas Y SALIDAS
  movwf PUERTAB   ;w trisa (las lineas de pb salida)
 bcf   ESTADO,5 ;pone a0 el bit 5 de estado
        ;pasando a aceder el banco 0
        
inicio  movf PUERTAA        ;W<- PUESTAA. Se introduce el
          ;valor binariode los interruptores   
        movwf   ENTRADA1 ; Define la posicion del entrada 1
   rrf     ENTRADA1,1
        movf   PUERTAB      ;W<- PUERTAB. Se introduce el
                          ;valor binariode los interruptores   
        movwf   ENTRADA2   ; Define la posicion del entrada 2
   movlw   0x00
bucle1    ; entrada2 - 1 entrada
   addwf   ENTRADA1               ; se suma las entradas
   movwf   TEMPSALIDA
   decfsz  ENTRADA2,1
   goto bucle1
   rlf     TEMPSALIDA,1
   rlf     TEMPSALIDA,1
   rlf     TEMPSALIDA,1
   movfw   TEMPSALIDA
   movwf   PUERTAB
   
    goto inicio ; bucle infinito
END           ;Directiva que indica el final
          ;del programa

« Última modificación: 22 de Abril de 2016, 13:25:03 por JuanMendoza04 »

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Bueno veo que te has complicado un poco, pero si estas usando MPLAB o tenes el archivo .inc ya tiene definido muchas cosas, como los PORTA, TRISA, cada uno de los bits de los registros, por ejemplo STATUS,RP0 , W y  F entre otras.

Asi que eso por una parte, por la otra multiplicar se puede hacer de 2 formas distintas en binario. La primera es la que nos enseñan siempre. y es la de sumar tantas veces como sea la multiplicacion, la otra es rotar y sumar cuando se encuentre un 1. Dejo ambos codigos.

Pero intenta crearlos vos mismo, tus problemas fueron:
- no limpiaste bien los datos de entrada, observa que le hago una AND yo antes de guardarlos en ENTRADAx.
- Si te fijas en tu bucle, cargas W con 0 al entrar, y luego tu bucle suma 0 a ENTRADA1 ( ADD W F , sumar W con F ), lo unico que hace es Mover Entrada1 a Tempsalida una cantidad de veces dada por Entrada2. Pero se resumen en que Tempsalida va a tener siempre el valor de Entrada1.

Para mostrar los datos esta correcto, Tus principales fallas fueron las anteriores, que eran limpiar los datos bien (por que no sabes que hay en los otros bits, tenes que asegurarte que sean 0 ) y Crear una funcion que las sume correctamente.


Sumas consecutivas
Código: ASM
  1. LIST P=16F84A           ;Indica el modelo de PIC que se usa
  2.                                 ;Es un directiva del ensamblador
  3.         RADIX HEX               ;Los valores se representan en hexadecimal
  4.  
  5.         include "p16f84a.inc"
  6.  
  7.         CBLOCK
  8.         ENTRADA1
  9.         ENTRADA2
  10.         TEMPSALIDA
  11.         ENDC
  12.  
  13.         org     0x00            ;Vector de Reset
  14.         GOTO    Configuracion
  15.         org     0x04            ;Vector de interrupcion
  16.         RETURN
  17.  
  18. Configuracion:
  19.  
  20.         BANKSEL TRISA           ; Banco 1 , esto luego el compilador lo reemplaza por los BSF/BCF a STATUS,RP0
  21.  
  22.         movlw   0X0E
  23.         movwf   TRISA
  24.         movlw   0X07            ;w entradas Y SALIDAS
  25.         movwf   TRISB           ;w trisa (las lineas de pb salida)
  26.  
  27.         BANKSEL PORTA           ; Banco 0
  28.  
  29. Inicio:  
  30.         RRF     PORTA, W        ; De RA3-RA1 a RA2-RA0, quedando el valor xxxx xaaa
  31.         ANDLW   b'00000111'     ; Me aseguro que quede 0000 0aaa
  32.         MOVWF   ENTRADA1
  33.         movf    PORTB           ; Este va directo, asi que queda xxxx xbbb
  34.         ANDLW   b'00000111'     ; Me aseguro que quede 0000 0bbb
  35.         movwf   ENTRADA2        ; Ya tengo los datos, es hora de trabajarlos!
  36.  
  37.         INCF    ENTRADA2, F     ; Incremento F entrada 2 en 1, esto me va a permitir que si es 0 , al restar el primero no sume nada
  38.         CLRF    TEMPSALIDA      ; Limpio mi registro donde se realiza la suma
  39.         MOVF    ENTRADA1, W     ; W = Entrada1
  40. bucle  
  41.         DECF    ENTRADA2, F     ; Entrada - 1
  42.         BTFSS   STATUS, Z       ; Es 0 ?
  43.         GOTO    MostrarResultado; Si es 0: Muestro el resultado, por que termino
  44.         ADDWF   TEMPSALIDA, F   ; No es 0: Le sumo 1 Entrada1 a TempSalida y procedo a decrementar
  45.         GOTO    bucle           ; Vuelvo hasta que quede en 0
  46.  
  47. MostrarResultado                ; Resultado en 000c cccc , debo llevarlo a cccc c000
  48.         RLF     TEMPSALIDA, F
  49.         RLF     TEMPSALIDA, F
  50.         RLF     TEMPSALIDA, W   ; Este ultimo que lo rote y que lo ponga en W, me ahorro una instruccion
  51.         MOVWF   PORTB           ; Muevo al puerto
  52.         GOTO    Inicio
  53.  
  54. END           ;Directiva que indica el final del programa

Como son 3 bits no me complique haciendo loops:

Código: C
  1. LIST P=16F84A           ;Indica el modelo de PIC que se usa
  2.                                 ;Es un directiva del ensamblador
  3.         RADIX HEX               ;Los valores se representan en hexadecimal
  4.  
  5.         include "p16f84a.inc"
  6.  
  7.         CBLOCK
  8.         ENTRADA1
  9.         ENTRADA2
  10.         TEMPSALIDA
  11.         ENDC
  12.  
  13.         org     0x00            ;Vector de Reset
  14.         GOTO    Configuracion
  15.         org     0x04            ;Vector de interrupcion
  16.         RETURN
  17.  
  18. Configuracion:
  19.  
  20.         BANKSEL TRISA           ; Banco 1 , esto luego el compilador lo reemplaza por los BSF/BCF a STATUS,RP0
  21.  
  22.         movlw   0X0E
  23.         movwf   TRISA
  24.         movlw   0X07            ;w entradas Y SALIDAS
  25.         movwf   TRISB           ;w trisa (las lineas de pb salida)
  26.  
  27.         BANKSEL PORTA           ; Banco 0
  28.  
  29. Inicio:  
  30.         RRF     PORTA, W        ; De RA3-RA1 a RA2-RA0, quedando el valor xxxx xaaa
  31.         ANDLW   b'00000111'     ; Me aseguro que quede 0000 0aaa
  32.         MOVWF   ENTRADA1
  33.         movf    PORTB           ; Este va directo, asi que queda xxxx xbbb
  34.         ANDLW   b'00000111'     ; Me aseguro que quede 0000 0bbb
  35.         movwf   ENTRADA2        ; Ya tengo los datos, es hora de trabajarlos!
  36.  
  37.         CLRF    TEMPSALIDA      ; Limpio mi registro donde se realiza la suma
  38.         BCF     STATUS, C       ; Preparo el flag para cuando necesite rotar, ya que el carry esta en la rotacion y necesito que sea 0
  39.  
  40.         BTFSC   ENTRADA1, 0     ; Comienza la multiplicacion!
  41.         CALL    Sumar
  42.         RLF     ENTRADA2, F
  43.         BTFSC   ENTRADA1, 1
  44.         CALL    Sumar
  45.         RLF     ENTRADA2, F
  46.         BTFSC   ENTRADA1, 2
  47.         CALL    Sumar
  48. MostrarResultado                ; Resultado en 000c cccc , debo llevarlo a cccc c000
  49.         RLF     TEMPSALIDA, F
  50.         RLF     TEMPSALIDA, F
  51.         RLF     TEMPSALIDA, W   ; Este ultimo que lo rote y que lo ponga en W, me ahorro una instruccion
  52.         MOVWF   PORTB           ; Muevo al puerto
  53.         GOTO    Inicio
  54. Sumar
  55.         MOVF    ENTRADA2, W
  56.         ADDWF   TEMPSALIDA
  57.         BCF     STATUS,C        ; Borro el carry para la rotacion de Entrada2
  58.         RETURN
  59.  
  60. END           ;Directiva que indica el final del programa

Este segundo metodo se explica asi... Si por ejemplo tenes estos 2 registros:

0000 0101 = ENTRADA1
0000 0010 = ENTRADA2
Y los multiplicas
Es lo mismo que sumar:

0000 0010 + 0000 1000 = 0000 1010

El primer termino es debido a este 1: 0000 0101, el segundo termino debido a este 1: 0000 0101
Observa que los terminos son ENTRADA2 desplazado la misma cantidad de bits que donde hay un 1.

Espero que entiendas las 2 formas de "multiplicacion" que pueden existir en binario, lo demas sobre las instrucciones esta explicado en los codigos, podras ver en ambos codigos como podes separarlos en partes..

- La primera es la limpieza de los datos
- La segunda es la multiplicacion
- La tercera es mostrarlo

Si comparas ambos codigos solo cambio la segunda.

¿ Una es mejor que la otra ? Si.. Las sumas consecutivas o restas consecutivas dependen mucho de los valores manejados, en este caso de 3 bits, el maximo es un valor 7, es decir que el loop va a tener que ser realizado 7 veces como minimo, es decir sumar, restar uno de los indices,etc.

Mientras que el segundo metodo, tiene una pequeña variacion tal ves en el largo, pero si crearamos un Loop para este, solo se haria un loop por cada bit, al ser 3 bits solo se haria 3 veces.
En caso que te preguntes como seria con un loop

Código: ASM
  1. LIST P=16F84A           ;Indica el modelo de PIC que se usa
  2.                                 ;Es un directiva del ensamblador
  3.         RADIX HEX               ;Los valores se representan en hexadecimal
  4.  
  5.         include "p16f84a.inc"
  6.  
  7.         CBLOCK
  8.         ENTRADA1
  9.         ENTRADA2
  10.         TEMPSALIDA
  11.         CONTADOR
  12.         ENDC
  13.  
  14.         org     0x00            ;Vector de Reset
  15.         GOTO    Configuracion
  16.         org     0x04            ;Vector de interrupcion
  17.         RETURN
  18.  
  19. Configuracion:
  20.  
  21.         BANKSEL TRISA           ; Banco 1 , esto luego el compilador lo reemplaza por los BSF/BCF a STATUS,RP0
  22.  
  23.         movlw   0X0E
  24.         movwf   TRISA
  25.         movlw   0X07            ;w entradas Y SALIDAS
  26.         movwf   TRISB           ;w trisa (las lineas de pb salida)
  27.  
  28.         BANKSEL PORTA           ; Banco 0
  29.  
  30. Inicio:  
  31.         RRF     PORTA, W        ; De RA3-RA1 a RA2-RA0, quedando el valor xxxx xaaa
  32.         ANDLW   b'00000111'     ; Me aseguro que quede 0000 0aaa
  33.         MOVWF   ENTRADA1
  34.         movf    PORTB           ; Este va directo, asi que queda xxxx xbbb
  35.         ANDLW   b'00000111'     ; Me aseguro que quede 0000 0bbb
  36.         movwf   ENTRADA2        ; Si llego aca ninguno es cero. Y ya tengo los datos, es hora de trabajarlos!
  37.  
  38.         CLRF    TEMPSALIDA      ; Limpio mi registro donde se realiza la suma
  39.         MOVLW   0x03
  40.         MOVWF   CONTADOR
  41.  
  42. Multiplicar:
  43.         RRF     ENTRADA1, F
  44.         BTFSS   STATUS,C
  45.         CALL    Sumar
  46.         BCF     STATUS,C        ; Borro el carry para la rotacion de Entrada2
  47.         RLF     ENTRADA2, F
  48.         DECFSZ  CONTADOR, F
  49.         GOTO    Multiplicar
  50.  
  51. MostrarResultado                ; Resultado en 000c cccc , debo llevarlo a cccc c000
  52.         RLF     TEMPSALIDA, F
  53.         RLF     TEMPSALIDA, F
  54.         RLF     TEMPSALIDA, W   ; Este ultimo que lo rote y que lo ponga en W, me ahorro una instruccion
  55.         MOVWF   PORTB           ; Muevo al puerto
  56.         GOTO    Inicio
  57. Sumar
  58.         MOVF    ENTRADA2, W
  59.         ADDWF   TEMPSALIDA
  60.         RETURN
« Última modificación: 22 de Abril de 2016, 14:48:39 por KILLERJC »

Desconectado JuanMendoza04

  • PIC10
  • *
  • Mensajes: 3
EXCELENTE HA SIDO MUY UTIL, PERO TENGO UNA DUDA.

EN EL PUERTO A, EL PIC16F84A SOLO TIENE 5, ES DECIR DE A0 - A4

y en este paso pusiste
 b'00000111'
pero el puerto A de este micro tiene nada mas 5 pines no 8...

no afecta?

Inicio: 
        RRF     PORTA, W        ; De RA3-RA1 a RA2-RA0, quedando el valor xxxx xaaa
        ANDLW   b'00000111'     ; Me aseguro que quede 0000 0aaa
        MOVWF   ENTRADA1
        movf    PORTB           ; Este va directo, asi que queda xxxx xbbb
        ANDLW   b'00000111'     ; Me aseguro que quede 0000 0bbb
        movwf   ENTRADA2        ; Ya tengo los datos, es hora de trabajarlos!

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Los registros internos son todos de 8 bits, por mas que tengas 5 bits, si observas el datasheet, en la parte de I/O Ports. Y observas el registro PORTA, vas a notar que tiene esos bits que no se usan con un guion "-" y abajo dice:

Citar
- = unimplemented, read as '0'. Shaded cells are unimplemented, read as '0'.

Es decir se leen como 0., si escribis ahi por ejemplo al poner :

MOVLW 0xFF
MOVWF PORTA

Solo vas a afectar a los bits que se usan nomas ( PORTA si lo lees va a ser 0001 1111 si es una salida ). No va a ocurrir nada mas.

Bueno siguiendo con el tema...

        RRF     PORTA, W        ; De RA3-RA1 a RA2-RA0, quedando el valor xxxx xaaa
        ANDLW   b'00000111'     ; Me aseguro que quede 0000 0aaa
        MOVWF   ENTRADA1

Como ves yo puse xxxx xaaa que seria lo leido y rotado.. en realidad paso a paso me quedaria asi:

Valor inicial de PORTA = 000x aaax    , "a" dato que me interesa, "x" dato que NO me interesa, y los "0" de no implementados
Luego del RRF, ya que roto y el carry esta en medio, W = c000 xaaa

los "0" por que no estan implementados, la "c" que es el carry, las "a" que seria lo que me interesa, y la "x" que es el valor de RA4 que es la unica que quedo (por que RA0 quedo en el bit de carry) y que no lo quiero para calcular, tambien necesito que este en 0, por que si esta en 1 seria otro numero. Como ves todo adentro es de 8 bits, asi que eso es lo que tendria en W.

Al hacerle la AND con 0000 0111 a eso que tengo en W:

c000 xaaa
0000 0111
------------
0000 0aaa

Me queda solamente las "a" o que seria el dato de las entradas que me interesan!

Desconectado JuanMendoza04

  • PIC10
  • *
  • Mensajes: 3
Ha quedado comprendido gracias, muy buen aporte