Autor Tema: Conteo binario visualizado a LCD  (Leído 2121 veces)

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

Desconectado Dhanjel

  • PIC10
  • *
  • Mensajes: 5
Conteo binario visualizado a LCD
« en: 29 de Agosto de 2011, 16:37:27 »
Buenos días foristas , soy nuevo en el foro y quiero pedirles un favor.

Tengo que implementar un contador de 8 bits, que visualice en formato binario a LCD 2x16. Como hasta ahora comienzo, decidí hacer primero un contador con longitud de un nibble, osea, de "0000" hasta "1111" (código ascii) para ver en lcd y luego implementar una subrutina que aproveche esto para que visualice un nibble y luego el otro y ver así el byte,pero como 1's y 0's.

Uso un PIC16F84A, y el contador lo incrementa un pulsador en RB0. Cargo el valor del contador en W y llamo una tabla con los caracteres ascii (Mensajes_BIN ), y también uso otro registro llamado "puntero" que me cuenta si los caracteres visualizados a LCD son 4, si son menos, es porque no ha salido el último caracter 1/0 a LCD y vuelvo a la rutina de tabla para sacarlo.


Mi  problema es que uso la técnica de DT"0000" DT"0001"..., donde el "contador"  es puntero del mensaje (o nibble) y el "puntero" es el puntero dentro del mensaje, que indica ala posición del caracter para sacar a LCD(1-4).

La cosa es que el conteo en Proteus cuenta bien al principio y se estropea;
Inicializa en "0000", incremento a  "0001", "0010" y luego cuanta mal, pero  no es rebote, ya hice varios retardos y nada funciona, y al grabar el PIC sin darle pulso, cuenta como loco, lo cual es raro porque el incremento del contador y el puntero los controlo, pero hay algo de lo que no me he dado cuenta y que no puedo resolver.

Hasta me copié una rutina del libro "PIC16F84A Desarrollo de proyectos" llamada "LCD_MENS.INC", pero el asunto es que
en esta, se carga la etiqueta del mensaje (caracteres ascii) , pero en mi caso, yo cargo el valor del contador y lo uso como puntero para cada etiqueta en la tabla de mensajes  y el puntero, para controlar el fin del mensaje, verificando que envió los 4 caracteres.

Este es el código que hice:

list p=16F84A ; list directive to define processor
#include <p16F84A.inc> ; processor specific variable definitions

__CONFIG _CP_OFF & _WDT_OFF & _PWRTE_ON & _XT_OSC

;********************************************************************************************************************************
        ORG 0X00
       GOTO INICIO

      contador EQU  0x0C 
      puntero  EQU  0x0D

      CBLOCK  0x0E
      ENDC     
;*********************************************************************************************************************************
Mensajes_BIN  ADDWF PCL,1

BIN_0000
 DT "0000"
;BIN_0001
 DT "0001"
;BIN_0010
 DT "0010"
;BIN_0011
 DT "0011"
;BIN_0100
 DT "0100"
;BIN_0101
 DT "0101"
;BIN_0110
 DT "0110"
;BIN_0111
 DT "0111"
;BIN_1000
 DT "1000"
;BIN_1001
 DT "1001"
;BIN_1010
 DT "1010"
;BIN_1011
 DT "1011"
;BIN_1100
 DT "1100"
;BIN_1101
 DT "1101"
;BIN_1110
 DT "1110"
;BIN_1111
 DT "1111"
FinMensajes_BIN
;*******************************************************************************************************************************

INICIO
          call  LCD_Inicializa
          clrf  contador         ;este registro comienza en 0 ,es el puntero para acceder a los valores binarios del nibble
          clrf  puntero          ;este registro comienza en 0, cuenta el # de caracteres del valor binario, que deben ser 4
           
          movlw '0'              ;el conteo esta iniciado desde "0000"
          call  LCD_Caracter
          movlw '0'
          call  LCD_Caracter
          movlw '0'
          call  LCD_Caracter
          movlw '0'
          call  LCD_Caracter

Principal
       
          btfss PORTB,0           ;si se oprime pulsador en RB0
          goto  Principal         ;
suelta    btfsc PORTB,0           ;revisa que se halla soltado
          goto  suelta            ;elimina rebote, 50ms
          call  Retardo_100ms
          call  LCD_Borra         ;borra el caracter actual en lcd para visualizar otro valor, al que incrementa
          incf  contador,1        ;aumenta contador para que busque un nibble distinto cada vez
envia     
          movf  contador,0        ;cargo el contador para que sea puntero de las tablas
          addwf puntero,0         ;sumo el valor puntero que indica la posición del caracter
          addlw BIN_0000          ;se carga la dirección BI_0000 como punto de partida
          addlw  .1                    ;hasta donde los valores de puntero,contador+1 lo determinen para acceder al valor 0001 en el                   

                                          ;primer incremento
          call  Mensajes_BIN
          call  LCD_Caracter      ;rutina lcd que muestra caracteres scii en la pantalla lcd
          incf  puntero
prueba                            ;cuando sale un caracter, registra cada vez hasta que llegue al cuarto
          movlw 0x04              ;puntero=4?
          xorwf puntero,0         ;acaba de escribir los 4 caracteres y si faltan, entonces sigue hasta el último
          btfss STATUS,Z          ;ya acabó?
          goto  envia             ;no, apunta al siguiente caracter
          clrf  puntero           ;si, puntero se borra y esperamos pulso para volver a incrementar
          goto  Principal
         
include<LCD_4BIT.INC>
include<RETARDOS.INC>
 
end

   
ahora que lo veo (de nuevo) me parece corto, ¿hay algún otro control que deba hacer?, es como si después del segundo incremento se saltara como loco, ya intenté varias cosas por ejemplo puse contador y punteo fuera del bloque de las variables, ya que las subrutinas lcd y retardos, inician con sus propias variables y el CBLOCK,ENDC así que los dejé por fuera, antes eran
CBLOCK 0x0c
contador
puntero
ENDC

 y los dejé así:

 contador EQU  0x0C 
 puntero  EQU  0x0D

      CBLOCK  0x0E
      ENDC

También borré el registro INTCON para evitar interrupciones.     

Igual no sirve el conteo completo , por lo que intuyo es software y no el rebote, pero no  he siquiera intuido que sea, además no es siquiera ordenado, como un contador hexa a LCD que implementé  igual, pero si deja ver un incremento ordenado (ascendente y consecutivo).

Gracias por su ayuda.
         
           

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re: Conteo binario visualizado a LCD
« Respuesta #1 en: 01 de Septiembre de 2011, 21:39:24 »
Espero no mandarme alto fail en lo que digo xD..

Código: [Seleccionar]
CBLOCK 0x0c
contador
puntero
ENDC

Es lo mismo que poner

Código: [Seleccionar]
contador EQU  0x0C
puntero  EQU  0x0D

Solo que especificas el primero y luego vas agregando ahi los que deseas xD.

Otra cosa que veo mal es el retardo. no me parece lo mejor

Código: [Seleccionar]
Principal
       
          btfss PORTB,0           ;si se oprime pulsador en RB0
          goto  Principal         ;
suelta    btfsc PORTB,0           ;revisa que se halla soltado
          goto  suelta            ;elimina rebote, 50ms
          call  Retardo_100ms

Por que el rebote significa varios 0 y 1 seguidos, con lo cual ahi en la primera entras, con el mismo rebote, y esperas 100ms, si lo tuviste presionado mas tiempo entraste de vuelta.. ( Explicacion: En el primer rebote, el porbt,0 vale 1, y luego pasa a 0 por el rebote mismo, entones ya te tomo 1 entrada, y si seguis presionado luego de los 100ms sigue en 1, con lo cual al soltar entraste de vuelta al programa)
Por lo cual pienso que el retardo de 100ms , deberia estar entre la bandera "suelta" y el goto Principal.

Por el tema del LCD no tengo idea como funciona los archivos que incluiste. Y por ultimo el tema de la tabla lo veo re complejo.. yo siempre use el RETLW para hacerlas, por ejemplo uso la variable contador nomas y luego que cada ves que haya un boton presionado se incremente en 1 y llamas a la tabla con un CALL y volves.. Dejandote en W el valor a mostrar

o sea :

Código: [Seleccionar]
CLRW
ADDWF contador,W
ADDWF PCL,F
RETLW 00h
.
.
.
RETLW 0Fh

O yo me estoy mandando cualquiera xD,, aunque sino mal recuerdo asi lo hacia :S , es que hace tanto tiempo que no hago una tabla :S. De ultima simulalo en MPLAB primero siempre,, podes omitir lo del LCD (comentarlo) y ver si reacciona el programa como deberia, si entra cuando debe o no a una subrutina, y luego ya comprobado eso, pasarias a ver si esta correcto el envio de datos al LCD por parte de ese archivo


 

anything