Autor Tema: Problema con instrucción SUBWF  (Leído 6710 veces)

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

Desconectado CHALAMAN

  • PIC10
  • *
  • Mensajes: 5
Problema con instrucción SUBWF
« en: 20 de Febrero de 2009, 04:57:55 »
Hola Todos,
Estoy muy extrañado con el resultado de mi codigo, ya verán por que... La sección de código con problemas debería imprimir en una pantalla LCD los caracteres de una tabla -mediante un barrido- pero se queda en un lazo infinito debido a que la instruccion <subwf Var1,W> modifica el valor de Var1, provocando resultados indeseados: el contador nunca alcanza el valor necesario para escapar del loop.

Este es el código:

Código: [Seleccionar]
[color=blue]LCD_EscTabla ;como parametro de entrada se tiene el offset que queremos en "W"
clrf    ContCaracter ;primer caracter

LCD_OtroChar
movf LCD_Offset,w ;el offset es cargado en W

call    LCD_Tabla ;va a la tabla y devuelve en W el caracter de acuerdo al offset
call    LCD_Caracter    ;Imprime el caracter

;aqui la cosa se puso rara, asi que imprimi el valor ASCII del contador para ver su comportamiento

movlw D'48'
addwf ContCaracter,w          ;W=ASCII(ContCaracter)  recuerden que ContCaracter es un numero entre 0 y 7
call LCD_Caracter             ;visualicé 0, valor inicial del contador: OK

incf    ContCaracter,f                 ;incremento el contador


;vuelvo a imprimir el valor ASCII del contador para ver su comportamiento

movlw D'48'
addwf ContCaracter,w          ;W=ASCII(ContCaracter)  recuerden que ContCaracter es un numero entre 0 y 7
call LCD_Caracter            ;visualicé 1, valor inicial del contador + 1: hasta ahora todo bien...

movlw   D'8' ;cantidad de caracteres
subwf   ContCaracter,w              ;resto el contador con el maximo de caracteres, con el fin de evaluar el bit Z (cero) y saber si ya terminé de imprimir 8 caracteres

;vuelvo a imprimir el valor ASCII del contador para ver su comportamiento

movlw D'48'
addwf ContCaracter,w          ;W=ASCII(ContCaracter)  recuerden que ContCaracter es un numero entre 0 y 7
call LCD_Caracter             ;visualicé 0, y hasta ahora no me la creo!!! el contador debería seguir siendo 1, pero fue modificado!!!

btfss   STATUS,Z ;comparo el contador con 8
goto    LCD_OtroChar                 ; si contador es 8, entonces sale del lazo. Esto nunca sucede porque aqui ContCaracter siempre es cero, a pesar de que en las simulaciones con MPLAB SIM, el programa funciona correctamente.

return
;Si el primer caracter es "J" en el LCD se visualiza:
;    J010J010J010J010
;    J010J010J010J010
;El 1er "0" es el valor inicial del contador, el 1 es el valor inicial del contador luego de un incremento, y el 2do "0" es el valor del contador antes de ser comparado. El programa se queda en un lazo infinito[/color]

Ojalá puedan ayudarme a resolver este misterio...

Muchas Gracias,
Carlos.

Desconectado pibe

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 635
Re: Problema con instrucción SUBWF
« Respuesta #1 en: 20 de Febrero de 2009, 07:42:02 »
He visto que la peña acostumbra a usar el xorwf en lugar del subwf , al parecer debido a errores como el que comentas.

Pero espera espera!
Toy viendo que haces la resta, pero luego te olvidas de testear el STATUS y pasas directamente a otra línea donde le vuelves a cargar W con otro valor
Mi jefe mirando el prototipo que estoy creando: "Y eso va a funcionar?"

Desconectado CHALAMAN

  • PIC10
  • *
  • Mensajes: 5
Re: Problema con instrucción SUBWF
« Respuesta #2 en: 20 de Febrero de 2009, 12:46:13 »
Sí, tienes razón, pero el programa original no tiene las líneas donde se imprime los valores del contador, por lo tanto se hace la comparación justo despues del "subwf". En el programa original se visualiza el LCD lleno de "J" (primer caracter de la tabla)

Agregué esas líneas para visualizar que pasaba con el contador dentro del loop y me encontré con esta extrañeza. Nota que en el codigo posteado, para cuando testeo el STATUS, el valor del contador ya varió de 1 a cero, debido a la instrucción subwf...
Originalmente sucedía esto:


                                                 ;hasta aquí ContCaracter vale 0
       incf    ContCaracter,f           ;ahora vale 1
       movlw   D'8'      ;
       subwf   ContCaracter,w       ;aqui vuelve a ser 0!!! esto es raro porque especifiqué d=w
       btfss   STATUS,Z      ;evaluo si ContCaracter=8
       goto    LCD_OtroChar         ;ContCaracter siempre vale 0 al llegar aca y nunca escapa de este loop


En el MPLAB SIM el programa funciona como debería, es decir  subwf ContCaracter,w no modifica el contador y obtengo los 8 caracteres que necesito...

Desconectado sander

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 627
Re: Problema con instrucción SUBWF
« Respuesta #3 en: 20 de Febrero de 2009, 19:27:44 »
En el MPLAB SIM funciona?, entonces en donde no funciona, armaste el circuito ?, cuales son tus bits de configuracion?, que PIC estas usando?
Saludos
« Última modificación: 20 de Febrero de 2009, 19:33:18 por sander »
La electrónica es el arte de manipular señales eléctricas que transportan información
Jan Davidse

Visita mi blog
Visita mi canal de youtube

Desconectado CHALAMAN

  • PIC10
  • *
  • Mensajes: 5
Re: Problema con instrucción SUBWF
« Respuesta #4 en: 21 de Febrero de 2009, 13:57:55 »
Sí funciona en el MPLAB SIM. Donde no funciona es en mi circuito. Estoy utilizando un LCD de 2x16 caracteres con un PIC16F877A, 4MHZ, sin WDT...  El hecho es que mi programa funciona correctamente cuando imprimo caracter por caracter (<movlw A'x' >  <call LCD_EscribeCaracter>). Por eso dudo (corrijanme si me equivoco) que sea problema de configuración o hardware. Pero luego le aumenté tablas mediante directivas <dt "abcdefg..."> y fue ahi que encontre problemas. También deshabilité las interrupciones... Por eso asumo, que el problema esta en la rutina LCD_EscTabla, que reemplaza a una serie de <movlw A'x' >  <call LCD_EscribeCaracter>). Fui "acorralando" la zona del código con problemas, haciendo modificaciones temporales para visualizar diferentes variables en el LCD, agregar retardos, etc... y encontré lo mencionado en mi primer post: El valor del contador es modificado dentro del loop cuando no debería serlo.

También probé lo sugerido por pibe de utilizar xorwf en vez de la resta, pero sucede lo mismo que con subwf!

También probé los siguiente:

                                           ;hasta aquí ContCaracter vale 0
       incf    ContCaracter,f           ;ahora vale 1

       movf     ContCaracter
       movwf   ContCaracter_Temp    ;    áún modificando ContCaracter_Temp, ContCaracter debería llegar eventualmente a D'8'

       movlw   D'8'      ;
       subwf   ContCaracter_Temp,w       ;aqui vuelve a ser 0!!! esto es raro porque especifiqué d=w

       btfss   STATUS,Z      ;evaluo si ContCaracter=8
       goto    LCD_OtroChar         ;ContCaracter siempre vale 0 al llegar aca y nunca escapa de este loop


Lo que tampoco resultó.

Para el código de lectura de tablas me basé en la AN556 de Microchip "Implementing table reads" http://www.microchip.com/1010/suppdoc/appnote/all/an556/index.htm

Pienso que si hubiera un problema en los saltos imprimiría cualquier cosa en el LCD, o más probablemente no imprimiría nada, pero imprime el primer caracter infinitas veces, y con el codigo de mi primer post, imprime 4 caracteres infinitamente.

La verdad estoy atascado y no tengo idea de que puede estar mal...  :'(

Desconectado pablomanieri

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 639
Re: Problema con instrucción SUBWF
« Respuesta #5 en: 21 de Febrero de 2009, 15:15:16 »
Tienes un problema al tratar de cargar el valor de Contcaracter en el registro W con  la sentencia
movf ContCaracter. Al no especificar donde lo quieres cargar el MPLAB te lo carga por defecto en el mismo registro. por eso el valor de ContaCaracter_Temp nunca adquiere el valor de ContCaracter.
Debes especificar que lo guarde en W, haciendo

movf ContCaracter,0
o
movf ContCaracter,w



Desconectado pablomanieri

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 639
Re: Problema con instrucción SUBWF
« Respuesta #6 en: 21 de Febrero de 2009, 15:19:21 »
Hice una simulación en MPLAB y me tiró el siguiente warning justo en la línea donde se debería cargar el valor de Contcaracter al registro W, como te dije en el post anterior, debes modificar esa línea:

Message[305] D:\ELECTRONICA\ASM\SERVO TIEMPOS\PRUEBALCD.ASM 11 : Using default destination of 1 (file).

Los warning están para algo, no para dejarlos pasar sin prestarles atención :D, debes darle casi la misma importancia que a los errores en el programa

Desconectado CHALAMAN

  • PIC10
  • *
  • Mensajes: 5
Re: Problema con instrucción SUBWF
« Respuesta #7 en: 23 de Febrero de 2009, 13:01:19 »
Estimado pablomanieri, disculpa por la omisión pero en el código que utilicé sí especificaba el destino. Por algún motivo, se me pasó y no lo coloqué en el post. Te aseguro que no es un caso de PEBKAC, realmente no se que puede estar pasando, por eso decidí pedirle ayuda a Uds. los gurús de todopic ;) Voy a preparar un código "resumido" para poder postearlo completo. No lo he hecho aún porque es demasiado largo y no quisiera hacerles perder mucho su tiempo :(

Muchas gracias por sus ideas!

Carlos

Desconectado pablomanieri

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 639
Re: Problema con instrucción SUBWF
« Respuesta #8 en: 23 de Febrero de 2009, 14:07:50 »
Bueno, vamos a ver cuando postees el código, debes tener cuidado que si no estás en el banco correcto cuando tratas de escribir en algún registro no lo escribe.

Desconectado todopic

  • Administrador
  • DsPIC30
  • *******
  • Mensajes: 3495
    • http://www.todopicelectronica.com.ar
Re: Problema con instrucción SUBWF
« Respuesta #9 en: 23 de Febrero de 2009, 21:37:32 »
Hola, creo que la tabla está en un cambio de pagina.... para asegurarte, coloca la tabla al comienzo del programa....  luego nos comentas ok?

Norberto
Firmat - Santa Fe - Argentina

www.TodoPic.net

Solo se tiran piedras, al arbol que tiene frutos...

Desconectado CHALAMAN

  • PIC10
  • *
  • Mensajes: 5
Re: Problema con instrucción SUBWF
« Respuesta #10 en: 26 de Febrero de 2009, 15:26:48 »
Hola Todos,

Resulta que reescribiendo el código para Uds., encontré el problema: DESORDEN. Para mi programa principal tengo muchas librerías, cada una con muchas revisiones y en alguna de ellas había un conflicto de memoria como indirectamente sugería Norberto, lo que ocasionaba este comportamiento. Me sirve de lección, pues no acostumbro (o acostumbraba :D) a hacer un historial de revisiones y modificaciones como me sugiriera alguna vez un blogger amigo mío...

Me alegra que existan foros como este, donde la gente se interese por resolver dudas de los que estamos aprendiendo!

Particularmente, debo decir que el manejo de LCD con 4 bits se me hizo toda una pesadilla, pues la información en la red me pareció difícil de ubicar. Aunque el punto de inflexión fue cuando aprendí que los bits de datos que no se utilizan en modo 4 bits van sin conexión y no a tierra como decía en todos lados...

De todos modos aquí les dejo el código y esquemático que utilicé para manejar un LCD de 2x16 caracteres "estándar" con 4 bits, 16F877A 4MHz, incluyendo la lectura de tablas de las que les comenté.

Si lo van a utilizar en otros programas, sería bueno que tengan cuidado con la pila que es de 8 bits y no te indica cuando hay overflow. Ya me pasó pues mi programa es muy largo y utiliza muchas subrutinas, librerías y muchos "call - return".

Espero que a alguien le sirva.

Saludos y gracias a todos,

Carlos.