uControl
Septiembre 09, 2010, 02:36:53 *
Bienvenido(a), Visitante. Por favor, ingresa o regístrate.

Ingresar con nombre de usuario, contraseña y duración de la sesión
 
   Inicio   Ayuda Buscar Ingresar Registrarse  
Páginas: 1   Ir Abajo
  Imprimir  
Autor Tema: Rutina para encoder  (Leído 395 veces)
0 Usuarios y 1 Visitante están viendo este tema.
Ivan
PIC12F
**
Desconectado Desconectado

Sexo: Masculino
Mensajes: 248


« : Marzo 09, 2010, 09:00:32 »

Esta rutina es para el manejo de un encoder rotativo, lo saque de la fuente de valdorre y lo modifique para mi proyecto. La salida es a travez de la variable "encoder" y esta hecha en gran parte en asm, la primer parte es en basic porque la division y la multiplicacion no me andaba en asm ¿? .


Los bits de la variable son:

encoder.7 = giro a la derecha
encoder.6 = giro a la izquierda
encoder.5 = error (error en secuencia de giro, puede ser por lentitud de programa)
encoder.4 = cero (el encoder esta en reposo)


Código:
sub procedure leo_encoder

temp=portd and %00110000    'filtramos los bits 4 y 5 del portD y lo guardamos en temp
temp=temp/16                      'rotamos temp 4 lugares a la derecha (00110000 --> 00000011)
encoder=encoder*4               'rotamos encoder 2 lugares a la izquierda (000000XX --> 0000XX00)

asm

   movf _temp,w
   iorwf _encoder,w               'hacemos un OR entre temp y encoder(00000011->0000XX00=>0000XX11)
   andlw 15                         
   movwf _encoder               'borramos los 4 bits de mayor peso de encoder

   MOVF    _encoder,W       ' leemos la variable encoder
   ADDWF   PCL,F            ' saltamos tantas instrucciones como diga la variable encoder
   goto    cero                '(0000-0 en decimal) 00 -> 00  igual
   GOTO    DEC_COUNT    '(0001-1 en decimal) 00 -> 01 -1
   GOTO    INC_COUNT     '(0010-2 en decimal) 00 -> 10 +1
   goto    ERR_COUNT      '(0011-3 en decimal) 00 -> 11 error
   GOTO    INC_COUNT     '(0100-4 en decimal) 01 -> 00 +1
   goto    fin                   '(0101-5 en decimal) 01 -> 01 igual
   goto    ERR_COUNT       '(0110-6 en decimal) 01 -> 10 error
   GOTO    DEC_COUNT     '(0111-7 en decimal) 01 -> 11 -1
   GOTO    DEC_COUNT     '(1000-8 en decimal) 10 -> 00 -1
   goto    ERR_COUNT       '(1001-9 en decimal) 10 -> 01 error
   goto    fin                   '(1010-10 en decimal) 10 -> 10 igual
   GOTO    INC_COUNT     '(1011-11 en decimal) 10 -> 11 +1
   goto    ERR_COUNT      '(1100-12 en decimal) 11 -> 00 error
   GOTO    INC_COUNT     '(1101-13 en decimal) 11 -> 01 +1
   GOTO    DEC_COUNT    '(1110-14 en decimal) 11 -> 10 -1
   goto    fin                  '(1111-15 en decimal) 11 -> 11 igual

INC_COUNT:
    bsf   _encoder,7
    goto fin

DEC_COUNT:
    bsf   _encoder,6
    goto fin

ERR_COUNT:
    bsf   _encoder,5
    goto fin

CERO:
    bsf   _encoder,4
    goto fin
   
fin:
end asm

end sub

El encoder esta conectado en los pines RD5 y RD4, por eso se hace un AND con el valor 00110000 en esta linea..

temp=portd and %00110000

luego se acomoda para ubicarlo en el byte con...

temp=temp/16                        

esto hace que 00110000 pase a 00000011

si se quiere cambiar de pines el encoder, por ejemplo a RB6 y RB7 tendrian que hacer...

temp=portb and %11000000

y cambiar ...

temp=temp/16  

por...

temp=temp/64
 
 
« Última modificación: Marzo 09, 2010, 11:34:24 por Ivan » En línea
Leon Pic
Moderator
PIC24F
*****
Desconectado Desconectado

Sexo: Masculino
Mensajes: 2394


Cumulonimbus


WWW
« Respuesta #1 : Marzo 09, 2010, 10:13:38 »

Muy buen aporte Ivan. Gracias por compartirlo con todos.
Por lo que veo, con solo modificar la primera parte, se puede hacer totalmente en asm pero agregando rutina de división que hay en este foro.

Lo que no estoy seguro es como se utiliza la rutina. Me imagino que se llama por medio de la siguiente línea: sub procedure leo_encoder y en la variable encoder se obtiene el resultado una vez que finalice la rutina, ¿es verdad lo que digo?
En línea

Jesús dijo, yo soy el Camino, la PAZ y la VIDA, nadie llega al PADRE si no es por mi.
Ivan
PIC12F
**
Desconectado Desconectado

Sexo: Masculino
Mensajes: 248


« Respuesta #2 : Marzo 09, 2010, 10:27:52 »

Yo la rutina la uso en Mikrobasic, la llamada a la rutina se hace mediante el nombre, solo hay escribir "leo_encoder". Si se usa otro programa con poner una etiqueta al principio y un "return" al final creo que andaria.
las primeras tres lineas estan en basic porque las instrucciones en asm para rotar los bytes no me daban el resultado(usando la instruccion rrl y otra que no me acuerdo se puede hacer, solo que no a mi no me andaba Huh?)

Me olvide de aclarar una cosa, en la variable encoder, los bits 3 y 2 son el antiguo entado del encoder y los bits 1 y 0 tienen el estado actual.
« Última modificación: Marzo 09, 2010, 10:30:40 por Ivan » En línea
Ivan
PIC12F
**
Desconectado Desconectado

Sexo: Masculino
Mensajes: 248


« Respuesta #3 : Marzo 09, 2010, 11:42:06 »

alguien tiene por ahi las lineas de codigo para dividir por 16 y multiplicar por 4 en asm ? ? ?
En línea
Leon Pic
Moderator
PIC24F
*****
Desconectado Desconectado

Sexo: Masculino
Mensajes: 2394


Cumulonimbus


WWW
« Respuesta #4 : Marzo 09, 2010, 11:55:36 »

mmmmm me parece que están en Rutinas para compartir.
En línea

Jesús dijo, yo soy el Camino, la PAZ y la VIDA, nadie llega al PADRE si no es por mi.
Ivan
PIC12F
**
Desconectado Desconectado

Sexo: Masculino
Mensajes: 248


« Respuesta #5 : Marzo 09, 2010, 12:11:24 »

lo que no pude hacer "andar" son las instrucciones para rotar el byte en asm, por eso no hice toda la rutina en asm.
En línea
HJ
Administradores
PIC18F
*****
Desconectado Desconectado

Sexo: Masculino
Mensajes: 1787



« Respuesta #6 : Marzo 09, 2010, 02:59:23 »

alguien tiene por ahi las lineas de codigo para dividir por 16 y multiplicar por 4 en asm ? ? ?

Para multiplicar por 4, debes rotar el registro 2 veces a la izquierda poniendo a cero el CARRY antes de cada rotación.

Para dividir por 16, debes rotar el registro 4 veces a la derecha poniendo a cero el CARRY antes de cada rotación.

En ambos casos debes guardar la rotación en el mismo registro
Saludos
« Última modificación: Marzo 09, 2010, 03:01:16 por HJ » En línea
Ivan
PIC12F
**
Desconectado Desconectado

Sexo: Masculino
Mensajes: 248


« Respuesta #7 : Marzo 12, 2010, 03:19:50 »

Esta es la rutina terminada y probada, las instrucciones de division y multiplicacion en asm me tiraban error en mikrobasic con el uso de la libreria del lcd .  Angry  Cry  cabezaso a la pared


   movf portd,f            ;Movemos al reg. F el valor del portd
   andlw 48                ;Filtramos los bits 4 y 5 del reg. w
                               ;Antes (XXTTXXXX) despues (00TT0000)
   movwf _temp           ;Movemos al reg. temp el valor del reg. w
   rrf _temp,1              ;Rotamos el reg. temp a la izquierda (000TT000)
   rrf _temp,1              ;Rotamos el reg. temp a la izquierda (0000TT00)
   rrf _temp,1              ;Rotamos el reg. temp a la izquierda (00000TT0)
   rrf _temp,1              ;Rotamos el reg. temp a la izquierda (000000TT)

   BCF   STATUS,C       ;Ponemos a 0 al bit CARRY del registro STATUS

;La x en el reg. encoder son los bits del resultado de la ejecucion previa de
;esta rutina; se modifican en cada ejecucion.

   rlf _encoder,1           ;Rotamos el reg. encoder a la derecha (xxxxxEE0)
   rlf _encoder,1           ;Rotamos el reg. encoder a la derecha (xxxxEE00)

   movf _temp,w           ;Movemos el reg. temp a w
   iorwf _encoder,w       ;Hacemos la operacion OR entre los reg. encoder y w y
                                 ;lo guarda en este ultimo.
                                 ;     encoder     (XXXXEE00)
                                 ;         w         (000000TT)
                                 ;resultado en w (XXXXEETT)
                       
   andlw 15                  ;Filtramos con la operacion AND los bits que queremos borrar
                                 ;del registro w, en este caso, los primeros 4 bits
                                 ;      w      (XXXXEETT)
                                 ; valor 15   (00001111) <-15 en binario
                                 ;resultado  (0000EETT)

   movwf _encoder        ;Movemos el resultado al reg. encoder

   ;En este momento, el reg. encoder tiene un valor que esta formado por el
   ;valor antiguo y el valor nuevo de los pines del encoder. De esta manera se
   ;forma un numero que oscila entre 0000 (0 en decimal) y 1111(15 en decimal)

   MOVF    _encoder,W    ; Pasamos a w el valor del reg. encoder
   ADDWF   PCL,F           ; Sumamos al contador de programa el valor de w
   GOTO    CERO             ; (0000=00) pasa de 00 -> 00 = igual
   GOTO    DEC_COUNT    ; (0001=01) pasa de 00 -> 01 = -1
   GOTO    INC_COUNT     ; (0001=02) pasa de 00 -> 10 = +1
   GOTO    ERR_COUNT     ; (0011=03) pasa de 00 -> 11 = error
   GOTO    INC_COUNT     ; (0100=04) pasa de 01 -> 00 = +1
   GOTO    FIN                ; (0101=05) pasa de 01 -> 01 = igual
   GOTO    ERR_COUNT     ; (0110=06) pasa de 01 -> 10 = error
   GOTO    DEC_COUNT    ; (0111=07) pasa de 01 -> 11 = -1
   GOTO    DEC_COUNT    ; (1000=08) pasa de 10 -> 00 = -1
   GOTO    ERR_COUNT     ; (1001=09) pasa de 10 -> 01 = error
   GOTO    FIN                ; (1010=10) pasa de 10 -> 10 = igual
   GOTO    INC_COUNT     ; (1011=11) pasa de 10 -> 11 = +1
   GOTO    ERR_COUNT     ; (1100=12) pasa de 11 -> 00 = error
   GOTO    INC_COUNT     ; (1101=13) pasa de 11 -> 01 = +1
   GOTO    DEC_COUNT    ; (1110=14) pasa de 11 -> 10 = -1
   GOTO    FIN                ; (1111=15) pasa de 11 -> 11 = igual

INC_COUNT:    ;Viene a esta etiqueta si se detecto la secuencia +1
    bsf   _encoder,7    ;Ponemos a 1 el bit 7 del reg. encoder
    goto fin                ;Vamos a la etiqueta fin

DEC_COUNT:    ;Viene a esta etiqueta si se detecto la secuencia -1
    bsf   _encoder,6     ;Ponemos a 1 el bit 6 del reg. encoder
    goto fin                ;Vamos a la etiqueta fin

ERR_COUNT:    ;Viene a esta etiqueta si se detecto la secuencia error
    bsf   _encoder,5    ;Ponemos a 1 el bit 5 del reg. encoder
    goto fin                ;Vamos a la etiqueta fin

CERO:             ;Viene a esta etiqueta si se detecto la secuencia 00->00
    bsf   _encoder,4     ;Ponemos a 1 el bit 4 del reg. encoder
    goto fin                 ;Vamos a la etiqueta fin

fin:

Edito: hay una copia en la seccion Rutinas para compartir.
« Última modificación: Marzo 12, 2010, 03:32:20 por Ivan » En línea
Leon Pic
Moderator
PIC24F
*****
Desconectado Desconectado

Sexo: Masculino
Mensajes: 2394


Cumulonimbus


WWW
« Respuesta #8 : Marzo 12, 2010, 03:22:24 »

¿Qué error te da?
Puede ser conflicto por posiciones de variables usadas simultáneamente.
En línea

Jesús dijo, yo soy el Camino, la PAZ y la VIDA, nadie llega al PADRE si no es por mi.
Ivan
PIC12F
**
Desconectado Desconectado

Sexo: Masculino
Mensajes: 248


« Respuesta #9 : Marzo 12, 2010, 03:29:36 »

ni idea, creo que puede ser por el tamaño de la pagina. el error no me lo daba el MKB sino que, en la rutina de manejo del encoder, no me daba los valores o se colgaba....
« Última modificación: Marzo 12, 2010, 03:31:16 por Ivan » En línea
Páginas: 1   Ir Arriba
  Imprimir  
 
Ir a:  

Impulsado por MySQL Impulsado por PHP Powered by SMF 1.1.9 | SMF © 2006-2009, Simple Machines LLC XHTML 1.0 válido! CSS válido!

Página creada en 0.35 segundos con 26 consultas. (Pretty URLs adds 0.015s, 2q)