Haz una pregunta
  Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos
Foros Registrarse ¿Olvidaste tu contraseña?

Temas similares

20/02/2009 #1


PIC16F877A - Lazo infinito debido a comportamiento de la instruccion subwf
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:
;subrutina LCD_EscTabla

LCD_EscTabla	                ;como parametro de entrada se tiene el offset que queremos en "W"
               ;
               ;  otro código...
               ;

              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 imprimí el valor ASCII del contador para ver su comportamiento

	movlw	D'48'
	addwf	ContCaracter,w          ;W=ASCII(ContCaracter)  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) 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'		   ;8 = cantidad de caracteres de la tabla
	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)  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.
	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
Un detalle: este no es el programa original. El original era identico excepto que no imprimía los valores del contador. Digo esto porque en el codigo de arriba, cuando el PC llega a la instrucción "btfss" W contiene un valor no deseado. En el original 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) pues se queda escribiendo eternamente el 1er caracter (contador=0)

Agregué codigo para visualizar que pasaba con el contador dentro del loop y me encontré con esta extrañeza. Noten que en el codigo de arriba, 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:


Código:
       ;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. especifiqué d=w (tambien probé con d=0)
       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...

Ojalá puedan ayudarme a resolver este misterio :s

Muchas Gracias,
Carlos.
20/02/2009 #2
Moderador

Avatar de Chico3001

<subwf Var1,W> decrementa Var1 en una unidad y el resultado lo guarda en w, pero no modifica en ningun modo Var1, es decir que si Var1=5 y aplicas subwf Var1,W tendras Var1=5 y W=4

Lo que tienes que hacer es <subwf Var1,F> y despues probar la bandera Z, asi estas actualizando Var1 y debe comenzar a decrementarse...
23/02/2009 #3


Tienes razón Chico3001, pero ese es justamente el problema: por algún motivo luego de esta instrucción <subwf Var1,W> el valor de Var1 SI se modifica. No debería pero pasa...
Respuesta
¿Tienes una mejor respuesta a este tema? ¿Quieres hacerle una pregunta a nuestra comunidad y sus expertos? Registrate

Foros de Electrónica » Diseño digital » Microcontroladores y sistemas embebidos

Powered by vBulletin® Version 3.8.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO ©2011, Crawlability, Inc.