Autor Tema: Juego de LEDs  (Leído 2141 veces)

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

Desconectado Miquel_S

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1251
Juego de LEDs
« en: 18 de Octubre de 2013, 11:57:49 »
Hola, alguien seria tan amable de explicarme cual es la diferencia de hacer correr los leds en estos dos programas, o sea hacerlo de una forma u otra, el primero sacado del libro y el segundo de cosecha propia.
Código: ASM
  1. RESET     ORG     0x0000            ; processor reset vector
  2.           PAGESEL START
  3.           GOTO    START             ; go to beginning of program
  4.  
  5. ;------------------------------------------------------------------------------
  6. ; MAIN PROGRAM
  7. ;------------------------------------------------------------------------------
  8.  
  9. START  
  10.                         clrf            CONTADOR
  11.                         banksel TRISB
  12.                         clrf            TRISB                                           ;Value used to
  13.                                                                                                 ;initialize data direction
  14.                                                                                                 ;Set RB<7:0> as outputs
  15.                         banksel         PORTB                                   ;Select bank of PORTB
  16.                         movlw           b'10000000'                             ;Encendemos Led en PB7
  17.                         movwf           DATO                                    ;Guardamos el código en un Registro
  18. SEGUIR1         movf                    DATO,W                                  ;Transferimos la información del registro DATO
  19.                         movwf           PORTB                                   ;al Puerto B
  20.                         incf            CONTADOR                                ;Incrementamos CONTADOR
  21.                         call            Retardo_200ms                   ;LLamamos a subrutina
  22.                         movf            CONTADOR,W                              ;Preguntamos si CONTADOR=8
  23.                         xorlw           0x08
  24.                         btfsc           STATUS,Z
  25.                         goto            SEGUIR2
  26. SEGUIR4         bcf                     STATUS,C                                ;Si CONTADOR <> 8 ponemos el Cy=0
  27.                         rrf                     DATO,F                                  ;y rotamos hacia la derecha el registro DATO
  28.                         goto            SEGUIR1                                 ;Seguimos hacia la derecha
  29. SEGUIR2         clrf            CONTADOR                                ;Si CONTADOR=8 ponemos el CONTADOR=0, Cy=0
  30. SEGUIR3         bcf                     STATUS,C                                ;y rotamos hacia la izquuierda el registro DATO
  31.                         rlf                     DATO,F
  32.                         movf            DATO,W                                  ;Transferimos la informacion del registro DATO
  33.                         movwf           PORTB                                   ;al PuertoB
  34.                         call            Retardo_200ms                   ;LLamamos a subrutina de retardo
  35.                         incf            CONTADOR                                ;Preguntamos si CONTADOR=7
  36.                         movf            CONTADOR,W
  37.                         xorlw           0x07
  38.                         btfss           STATUS,Z
  39.                         goto            SEGUIR3                                 ;Seguimos hacia la izquierda
  40.                         movlw           0x01                                    ;Ponemos el CONTADOR=1 y volvemos hacia la izquierda
  41.                         movwf           CONTADOR
  42.                         goto            SEGUIR4
  43.  
  44.                         #INCLUDE <Retardo_200ms.inc>
  45.  
  46.                 END
Código: ASM
  1. RESET     ORG     0x0000            ; processor reset vector
  2.           PAGESEL START
  3.           GOTO    START             ; go to beginning of program
  4.  
  5. ;------------------------------------------------------------------------------
  6. ; MAIN PROGRAM
  7. ;------------------------------------------------------------------------------
  8.  
  9. START
  10.                         banksel                 PORTB
  11.                         clrf                    PORTB
  12.                         banksel                 ANSEL
  13.                         movlw                   0x00
  14.                         movwf                   ANSEL
  15.                         clrf                    TRISB
  16.                         banksel                 PORTB
  17.  
  18. EMPEZAR         movlw                   b'00000001'
  19.                         movwf                   PORTB
  20.                         call                    Retardo_200ms
  21.                         bcf                             STATUS,C
  22.                         rlf                             PORTB,F
  23.                         call                    Retardo_200ms
  24.                         btfss                   STATUS,C
  25.                         goto                    $-3
  26.  
  27.                         movlw                   b'10000000'
  28.                         movwf                   PORTB
  29.                         call                    Retardo_200ms
  30.                         bcf                             STATUS,C
  31.                         rrf                             PORTB,F
  32.                         call                    Retardo_200ms
  33.                         btfss                   STATUS,C
  34.                         goto                    $-3
  35.                         goto                    EMPEZAR
  36.  
  37.                         #INCLUDE <Retardo_200ms.inc>
  38.  
  39.                         END

Gracias.
« Última modificación: 18 de Octubre de 2013, 12:09:38 por Miquel_S »
Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las mismas cosas.

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Juego de LEDs
« Respuesta #1 en: 18 de Octubre de 2013, 14:55:01 »
Hola,

La primera que sale a simple vista es que inicias el barrido (efecto auto fantástico?) en el sentido opuesto al código del libro, segundo: por lo que entiendo tu código no funciona idéntico al otro ya que el LED se apaga en los extremos, mientras que en código original se mantiene siempre encendido y por último pese a que el código tal cual está seguramente funcione hay un error potencial:

Código: ASM
  1. EMPEZAR movlw   b'00000001'
  2.         movwf   PORTB
  3.         call    Retardo_200ms
  4.         bcf     STATUS,C
  5.         rlf     PORTB,F
  6.         call    Retardo_200ms
  7.         btfss   STATUS,C
  8.         goto    $-3

El estado de STATUS, C puede resultar desconocido, debido a que la subrutina Retardo_200ms puede ejecutar alguna instrucción que lo modifique (incluso puede que no lo modifique todas las veces que se ejecuta), lo que haría que la condición se  evalúe de manera errónea. Entiendo que seguramente Retardo_200ms no contenga ninguna instrucción que pueda afectar el estado de SATUS,C pero deberías tener en cuenta que el código deja abierta la puerta a que si luego el código se modifica, o se agregan más líneas de código entre la ejecución de la rotación y el checkeo de STATUS,C pueden aparecer bugs indeseables. A esto debemos agregarle que en caso de existir interrupciones, es imperioso que se tenga en cuenta el correcto guardado y recuperado de los registros clave (entre ellos el STATUS) sino estaríamos nuevamente ante la posibilidad de que nos "ensucie" el STATUS,C y se modifique el comportamiento del algoritmo.

Mi optimización sería:

Código: ASM
  1. EMPEZAR                 movlw                   b'00000001'
  2.                         movwf                   PORTB
  3.                         call                    Retardo_200ms
  4.                         bcf                     STATUS,C
  5.                         rlf                     PORTB,F
  6.                         btfss                   STATUS,C
  7.                         goto                    $-4
  8.  
  9.                         rrf                     PORTB,F
  10.                         call                    Retardo_200ms
  11.                         bcf                     STATUS,C
  12.                         rrf                     PORTB,F
  13.                         btfss                   STATUS,C
  14.                         goto                    $-4
  15.                         goto                    EMPEZAR

Agrego una más drástica (funciona de la manera original siempre y cuando PORTB = 0x00 al comenzar a ejecutarse el trozo de código debajo):

Código: ASM
  1. bsf                     STATUS,C
  2. EMPEZAR
  3.                         rlf                     PORTB,F
  4.                         call                    Retardo_200ms
  5.                         bcf                     STATUS,C
  6.                         rlf                     PORTB,F
  7.                         btfss                   STATUS,C
  8.                         goto                    $-4
  9.  
  10.                         rrf                     PORTB,F
  11.                         call                    Retardo_200ms
  12.                         bcf                     STATUS,C
  13.                         rrf                     PORTB,F
  14.                         btfss                   STATUS,C
  15.                         goto                    $-4
  16.                         goto                    EMPEZAR


Saludos.
« Última modificación: 18 de Octubre de 2013, 15:06:26 por BrunoF »
"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado Miquel_S

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1251
Re: Juego de LEDs
« Respuesta #2 en: 18 de Octubre de 2013, 16:27:55 »
Gracias BrunoF por la explicacion, entiendo que la manera correcta seria con el codigo copiado del libro, pero aunque entiendo el codigo y se como funciona el XORLW o OR EXCLUSIVA, no termino de entender que funcion tiene en este caso, ya que dicha instruccion lo que hace es poner el bit 3 del registro CONTADOR una vez leido y guardado en WREG a 1 y no se como influye en la ejecucion del programa.

Gracias de nuevo.
Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las mismas cosas.

Desconectado BrunoF

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3865
Re: Juego de LEDs
« Respuesta #3 en: 18 de Octubre de 2013, 16:37:48 »
Hola.

El ejemplo del libro no es la única solución posible. Hay infinitas soluciones viables al mísmo problema.

La XOR sirve en este caso para comparar si ambos valores son iguales. La única manera que STATUS,Z se ponga en alto luego de una XOR es si el resultado de la mísma es cero, y para que eso suceda, ambos valores sometidos a la operación lógica XOR deben ser idénticos (puedes verificarlo si lo deseas). Entonces, la XOR lo único que está haciendo aquí es comparar, por eso lo que sirve en este caso, es sólo el bit STATUS,Z que contiene luego de la XOR el resultado (si ambos valores coinciden o no), es por ello que el valor resultante de la XOR (almacenado en W) se descarta, porque no se utiliza en este caso. Sólo sirve el flag STATUS,Z.

Es una operación bastante recurrente en el código ASM. También podrías utilizar SUBLW, etc. para realizar la comparación.

Saludos.

"All of the books in the world contain no more information than is broadcast as video in a single large American city in a single year. Not all bits have equal value."  -- Carl Sagan

Sólo responderé a mensajes personales, por asuntos personales. El resto de las consultas DEBEN ser escritas en el foro público. Gracias.

Desconectado Miquel_S

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1251
Re: Juego de LEDs
« Respuesta #4 en: 18 de Octubre de 2013, 18:57:05 »
Se agradece la explicación amigo BrunoF.

Muchas GRACIAS.
Todos somos muy ignorantes. Lo que ocurre es que no todos ignoramos las mismas cosas.