TODOPIC

Simuladores, editores de PCB, etc => Simuladores de circuitos => Proteus ISIS => Mensaje iniciado por: elias111 en 27 de Mayo de 2005, 13:28:00

Título: ERROR EN SIMULACION DE PROTEUS
Publicado por: elias111 en 27 de Mayo de 2005, 13:28:00
estos son mis archivos en asm,donde simulo una entrada por el canal RA0, Y lo visualizo en un LCD
   RB  -> LCD DATA
;   RA0 -> ENTRADA AL CONVERSOR A/D
;   RA1   -> LCD RS
;   RA2   -> LCD RW
;   RA3   -> LCD E

   List P=16F876A
   Include "P16F876A.INC"

LCD_VAR      equ   0x23
DELAY_VAR   equ   0x25
DIGITAL      equ   0x2A
DIVIDENDO   equ   0x2B
DIVISOR      equ   0x2C
COCIENTE   equ   0x2D
RESIDUO      equ   0x2E
DIV_CONTA   equ   0x2F
W_TEMP      equ   0x30
STATUS_TEMP   equ   0x31
PCLATH_TEMP   equ   0x32
UNIDADES   equ   0x33
DECIMOS      equ   0x34

#Define   BANCO_H   bsf   STATUS,RP1
#Define   BANCO_L   bcf   STATUS,RP1
#Define   BANCO1   bsf   STATUS,RP0
#Define   BANCO0   bcf   STATUS,RP0

   errorlevel   -302

#Define   PAG0   clrf   PCLATH
#Define   PAG1   bsf      PCLATH,0
#Define   PAG2   bsf      PCLATH,1

#Define   LCD_DATA   PORTB
#Define   LCD_CTRL   PORTA

   __config      (_CP_OFF & _DEBUG_OFF & _WRT_OFF & _CPD_OFF & _LVP_OFF & _BODEN_ON & _PWRTE_ON & _WDT_OFF & _XT_OSC)
;++++++++++++++++++++++++++++
         org      0x0000
          goto   INICIO
         org      0x0005
;************************************************************************************************
;               PROGRAMA PRINCIPAL
;************************************************************************************************
INICIO      BANCO_L
         BANCO1
         movlw   0x0E
         movwf   ADCON1
         movlw   B"000001"
         movwf   TRISA
         movlw   B"11010111"
         movwf   OPTION_REG
         BANCO0
         movlw   0x41
         movwf   ADCON0
         call   LCD_UP
         call   LCD_INI
         call   LCD_CLEAR
         movlw   MENS_CONV
         PAG1
         call   LCD_MENSAJE         ;Visualiza "Mueva El Potenciometro"
         PAG0
         movlw   .2
         call   DELAY_S
         call   LCD_CLEAR
         movlw   0x40
         call   LCD_SETDDADDRESS
         movlw   MENS_VOLT
         PAG1
         call   LCD_MENSAJE         ;Visualiza "VOLTAJE RA0: 0,0"
         PAG0
CONVIERTE                bsf   ADCON0,2
         movlw   .30
         call   DELAY_US
         btfsc   ADCON0,2
         goto   $-1
         movf   ADRESH,W
         movwf   DIGITAL
         call   BINTOASCII
         movlw   0x4D
         call   LCD_SETDDADDRESS   ;Reposiciona cursor del LCD
         movf   UNIDADES,0
         call   LCD_WRITEDATO
         movlw   ","      
         call   LCD_WRITEDATO
         movf   DECIMOS,0
         call   LCD_WRITEDATO
         goto   CONVIERTE
;
;-------------------------------------------------------------------------
BINTOASCII            movf   DIGITAL,0
         movwf   DIVIDENDO
         movlw   .51
         movwf   DIVISOR
         call   DIV
         movf   COCIENTE,0
         PAG2
         call   LCD_TABNUM
         PAG0
         movwf   UNIDADES
         movf   RESIDUO,0
         movwf   DIVIDENDO
         movlw   .5
         movwf   DIVISOR
         call   DIV
         movf   RESIDUO,0
         sublw   .2
         btfsc   STATUS,C
         goto   $+9
         movlw   .9
         xorwf   COCIENTE,0
         btfss   STATUS,Z
         goto   $+4
         clrf   COCIENTE
         incf   UNIDADES,1
         goto   $+2
         incf   COCIENTE,1
         movf   COCIENTE,0
         PAG2
         call   LCD_TABNUM
         PAG0
         movwf   DECIMOS
         return
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;            SUBRUTINAS INTERNAS DEL ADC
;************************************************************************************************
;DIV:   Divide el número DIVIDENDO entre DIVISOR, dando como resultados los números COCIENTE y
;   RESIDUO.
DIV         movf   DIVIDENDO,0
         movwf   RESIDUO
         clrf   COCIENTE
         clrf   DIV_CONTA
         incf   DIV_CONTA,1
ROTAMAS      bcf      STATUS,C
         rlf   DIVISOR,1
         btfsc   STATUS,C
         goto   DIV_ATAJO
         incf   DIV_CONTA,1
         movf   DIVISOR,0
         subwf   RESIDUO,0
         btfsc   STATUS,C      ;¿Se rotó demasiado?
         goto   ROTAMAS         ;No, todoavía no se pasa
DESROTAR   bcf      STATUS,C
         rlf      COCIENTE,1
         decf   DIV_CONTA,1
         bcf      STATUS,C
DIV_ATAJO   rrf      DIVISOR,1
         movf   DIVISOR,0
         subwf   RESIDUO,0
         btfss   STATUS,C
         goto   DIV_TERMINA
         movwf   RESIDUO
         bsf      COCIENTE,0
DIV_TERMINA   decfsz   DIV_CONTA,0
         goto   DESROTAR
         return
;
;************************************************************************************************
;                  TABLAS
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
         org      0x100
MENS_CONV   equ   $
         dt   "Mueva El Potenciometro",0x00
MENS_VOLT   equ   $
         dt   "VOLTAJE RA0: 0,0",0x00
;
;-------------------------------------------------------------------------
         org      0x200
   Include "LCD8.INC"
         org      0x300
   Include "DELAY.INC"
   END

a qui estan los archivos por incluir:
 RETARDOS DE TIEMPO
;************************************************************************************************
;****************************************************************************************
;               DELAY.INC
;
;            ;
; Se tendrá las siguientes rutinas:
;   -   DELAY_US
;   -   DELAY_MS
;   -   DELAY_S
;Estas rutinas controlan los tiempos de retardo en microsegundos,
;milisegundos y en segundos. La cantidad microsegundos, de milisegundos
;o segundos toma del acumulador.
;NOTA: ESTOS TIEMPOS RESULTAN DEL USO DE UN RELOJ DE 4MHz (ciclo de
;instrucción de 1MHz).
;Guarda el registro OPTION en uno temporalal entrar para cargarlo al salir.
;DELAY_VAR EQU dir_inicio_del_bloque


; BLOQUE DE ETIQUETAS

   CBLOCK      DELAY_VAR   ;Inicio de las variables. La primera dirección libre disponible
      DELAY_TEMP_1
      DELAY_TEMP_2
      OPTION_TEMP
   ENDC


;RUTINA DELAY_uS: Se trata de un rutina que implementa un retardo
;o temporización en uS. Utiliza la variable DELAY_TEMP_1 que se va
;decrementando hasta alcanzar el tiempo del acumulador dado en uS.

DELAY_US   movwf    DELAY_TEMP_1
      bcf   STATUS,C
      rrf   DELAY_TEMP_1,1
      bcf   STATUS,C
      rrf   DELAY_TEMP_1,1
DELAY_U1   nop
      decfsz   DELAY_TEMP_1,F
      goto   DELAY_U1
      return


;RUTINA DELAY_uS: Esta rutina implementa un retardo o temporización
;en uS. Utiliza la variable DELAY_TEMP_1 que se va decrementando
;hasta alcanzar el tiempo del acumulador dado en mS.

DELAY_MS   movwf    DELAY_TEMP_1
      BANCO1
      movf   OPTION_REG,W
      movwf   OPTION_TEMP
      movlw   B"11010001"
      movwf   OPTION_REG
      BANCO0
DELAY_M1   clrwdt
      clrf    TMR0
      bcf   INTCON,T0IF
DELAY_M2    btfss   INTCON,T0IF
      goto   DELAY_M2
      decfsz   DELAY_TEMP_1,F
      goto   DELAY_M1
      BANCO1
      movf   OPTION_TEMP,W
      movwf   OPTION_REG
      BANCO0
      return


;RUTINA DELAY_S: Se trata de un rutina que implementa un retardo
;o temporización en S. Utiliza las variables DELAY_TEMP_1 y DELAY_TEMP_2
;que se van decrementando hasta alcanzar el tiempo del acumulador dado en S.

DELAY_S      movwf    DELAY_TEMP_1
      BANCO1
      movf   OPTION_REG,W
      movwf   OPTION_TEMP
      movlw   B"11010011"
      movwf   OPTION_REG
      BANCO0
DELAY_1      clrf   DELAY_TEMP_2
DELAY_2      clrwdt
      bcf   INTCON,T0IF
      clrf    TMR0
DELAY_3    btfss   INTCON,T0IF
      goto   DELAY_3
      decfsz   DELAY_TEMP_2,F
      goto   DELAY_2
      decfsz   DELAY_TEMP_1,F
      goto   DELAY_1
      BANCO1
      movf   OPTION_TEMP,W
      movwf   OPTION_REG
      BANCO0
      return

   LCD HITACHI HD44780A 2 X 16 o 1 X 16 8 bits de datos
;************************************************************************************************
;****************************************************************************************
;               LCD8.INC
;
;            ;
;Presenta un conjuntos de rutinas que permiten realizar las tareas de control del mòdulo
;de visualización LCD. Con la llamada a LCD_UP se configura para su uso y con la rutina LCD_INI
;se inicializa el LCD. Y la rutina MENSAJE visualiza un mensaje dado en una tabla.
;Las demás rutinas son las de principal uso de control. NOTA: Definir con "Define" los puertos
;LCD_DATA y LCD_CTRL, y en caso de tener cuatro bancos poner RP1 a 0 antes de LCD_UP si es necesario.
;
;Este fichero se debe incluir en los futuros programas fuente mediante la directiva INCLUDE.
;
;LCD_UP:      Configura los puertos A y B, y el INTCON para el uso del LCD.
;
;LCD_INI:    Inicializa el LCD. Espera 15ms (riso a 4.5V), configura # de bits de datos y # de
;      lineas activas.
;
;LCD_MENSAJE:      Esta rutina saca al LCD el mensaje cuyo inicio esta indicado en el acumulador. Se
;      aconseja para cada mensaje el siguiente formato:
;         MENS   equ   $   ó   MENS   equ   $
;         retlw   "O"         dt   "OK",0x00
;         retlw   "K"
;         retlw   0x00
;      Y debe hacer "movlw   MENS" antes de la llamada "call MENSAJE"
;
;LCD_CLEAR:   Borra el display y retorna el cursor a la posicion 0.
;
;LCD_HOME:   Retorna el cursor a la posicion 0.
;
;LCD_ENTRYMODE:   Configura el modo de ingreso al display.
;      El modo de funcionamiento deseado deberá cargarse en los 2 bits menores de W:
;            x x x x x x b1 b0
;      b0 :   0 = no desplazamiento del display   1 = desplazamiento
;      b1 :   0 = autodecremento del cursor      1 = autoincremento
;      b2-7 : sin importancia
;
;LCD_DISPCURSCONT:   Enciende o apaga el display, cursor y parpadeo.
;      El modo de control deseado deberá cargarse en los 3 bits menores de W:
;            x x x x x b2 b1 b0
;      b0 :   0 = no parpadeo del cursor      1 = parpadeo
;      b1 :   0 = apagar cursor         1 = encender cursor
;      b2 :   0 = apagar display         1 = encender display (los datos siguen en DDRAM)
;      b3-7 : sin importancia
;
;LCD_DISPCURSSHIFT:   Mueve el cursor o el display.
;      El modo de control deseado deberá cargarse en los 2 bits terceros de W:
;            x x x x b3 b2 x x
;      b2 :   0 = mueve al a izquierda      1 = a la derecha
;      b3 :   0 = mueve cursor         1 = mueve display
;      b0,1,4-7 : sin importancia
;
;LCD_SETCGADDRESS:   Fija la dirección de la CGRAM. La dirección de la CGRAM puede ser
;      leída/escrita después de este comando
;      La dirección deseada deberá estar en el registro W:
;            x x b5 b4 b3 b2 b1 b0
;      b0-5 : dirección de la CGRAM
;      b6-7 : sin importancia
;
;LCD_SETDDADDRESS:   Fija la dirección de la DDRAM. La dirección de la DDRAM puede ser
;      leída/escrita después de este comando
;      La dirección deseada deberá estar en el registro W:
;            x b6 b5 b4 b3 b2 b1 b0
;      b0-6 : dirección de la DDRAM
;      b7 : sin importancia
;
;LCD_READAC:   Obtiene en W el valor de AC.
;
;LCD_WRITEDATO:   Escritura de datos de W en la DDRAM o CGRAM
;      W = DATO
;      LCD_DATA <== W
;
;LCD_READDATO:   Lectura de datos de la DDRAM o CGRAM y lo pasa a W
;      LCD_DATA = DATO
;      W <== LCD_DATA
;
;LCD_TABNUM:   Convierte el número HEXADECIMAL que este en W a su equivalente ASCII.
;      OjO: No olvidar chequear el PCLATH por tratarse de asignación al PC por istrucción.
;
#define   ENABLE      bsf   LCD_CTRL,3   ;Activa E
#define   DISABLE      bcf   LCD_CTRL,3   ;Desactiva
#define   LEER      bsf   LCD_CTRL,2   ;Pone LCD en Modo RD
#define   ESCRIBIR      bcf   LCD_CTRL,2   ;Pone LCD en Modo WR
#define   DATO      bsf   LCD_CTRL,1   ;Desactiva RS (modo comando)
#define   COMANDO      bcf   LCD_CTRL,1   ;Activa RS (modo dato)
       cblock    LCD_VAR
              LCD_TEMP1      ;Registro temporal de posicion de la tabla
              LCD_TEMP2      ;Registro temporal del caracter ASCII
       endc
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;                 SUBRUTINAS DEL LCD
;************************************************************************************************
LCD_UP      BANCO1
      clrf   LCD_DATA      ;RB <0-7> salidas digitales
      movlw   B"11110001"
      andwf   LCD_CTRL,F   ;RA0=RS RA1=R/W RA2=E salidas digitales
      BANCO0
      bcf   INTCON,GIE   ;Desactivar interrupciones
      COMANDO         ;RS=0
      ESCRIBIR         ;R/W=0
      DISABLE         ;E=0
      return
;
;-------------------------------------------------------------------------
LCD_INI      movlw   0x0F
      call   DELAY_MS      ;Espera un poco más de 15ms
      movlw   B"00111000"   ;Datos de 8 bits, 2 lineas y caracteres de 5x7
      call   LCD_COMAND
      movlw   0x05
      call   DELAY_MS      ;5ms > 4.1ms.(Especificacion de Fabricante)
      movlw   B"00111000"   ;Datos de 8 bits, 2 lineas y caracteres de 5x8
      call   LCD_COMAND
      movlw   .110
      call   DELAY_US      ;110us > 100us.(Especificacion de Fabricante)
      movlw   B"00111000"   ;Datos de 8 bits, 2 lineas y caracteres de 5x8
      call   LCD_COMAND
      movlw   B"00001000"   ;b3 y b2 puedn ser cambiados para otra configuración
      call   LCD_FUNCIONSET   ;después de este punto no podran ser cambiados N ni F
      movlw   B"00000100"   ;Cursor apagado y Display prendido
      goto   LCD_DISPCURSCONT
;
;-------------------------------------------------------------------------
LCD_MENSAJE   movwf   LCD_TEMP1      ;Salva posicion de la tabla
M_E_N_S      movf   LCD_TEMP1,0   ;Recupera posicion de la tabla
      call   LCD_TABLA      ;Busca caracter de salida
      movwf   LCD_TEMP2      ;Guarda el caracter
      movf   LCD_TEMP2,1
      btfsc   STATUS,Z      ;¿Hay más caracteres?
      return         ;No, fue el último
      call   LCD_WRITEDATO   ;Visualiza en el LCD el caracter
      incf   LCD_TEMP1,1   ;Siguiente caracter
      goto   M_E_N_S      ;Repite con siguiente caracter
LCD_TABLA      movwf   PCL      ;Desplazamiento sobre la tabla
;
;-------------------------------------------------------------------------
LCD_CLEAR      movlw   B"00000001"   ;Borra LCD y cursor a Home
      goto   LCD_COMAND
;
;-------------------------------------------------------------------------
LCD_HOME      movlw   B"00000010"   ;Cursor a Home
      goto   LCD_COMAND
;
;-------------------------------------------------------------------------
LCD_ENTRYMODE   andlw   0x03      ;Nos quedamos con b1-b0
      iorlw   0x04      ;Incorporamos el bit de función
      goto   LCD_COMAND
;
;-------------------------------------------------------------------------
LCD_DISPCURSCONT   andlw   0x07      ;Nos quedamos con b2-b1-b0
      iorlw   0x08      ;Incorporamos el bit de función
      goto   LCD_COMAND
;
;-------------------------------------------------------------------------
LCD_DISPCURSSHIFT   andlw   0x0C      ;Nos quedamos con b3-b2
      iorlw   0x10      ;Incorporamos el bit de función
      goto   LCD_COMAND
;
;-------------------------------------------------------------------------
LCD_SETCGADDRESS   andlw   0x3F      ;Nos quedamos con b5-b4-b3-b2-b1-b0
      iorlw   0x40      ;Incorporamos el bit de función
      goto   LCD_COMAND
;
;-------------------------------------------------------------------------
LCD_SETDDADDRESS   iorlw   0x80      ;Incorporamos el bit de función
      goto   LCD_COMAND
;
;-------------------------------------------------------------------------
LCD_READAC   call   LCD_BUSY
      LEER
      BANCO1
      comf   LCD_DATA,1   ;Puerto B como entrada
      BANCO0
      ENABLE
      nop
      movf   LCD_DATA,0
      andlw   0x7F      ;Valor de la dirección de la DDRAM o CGRAM
      DISABLE
      BANCO1
      clrf   LCD_DATA
      BANCO0
      ESCRIBIR
      return
;
;-------------------------------------------------------------------------
LCD_WRITEDATO   movwf   LCD_DATA      ;Valor a escribir en la DDRAM o CGRAM
      call   LCD_BUSY
      DATO
      goto   LCD_E      ;Genera pulso de E
;
;-------------------------------------------------------------------------
LCD_READDATO   call   LCD_BUSY
      DATO
      LEER
      BANCO1
      comf   LCD_DATA,1   ;Puerto B como entrada
      BANCO0
      ENABLE
      nop
      movf   LCD_DATA,0   ;Valor leido de la DDRAM o CGRAM
      DISABLE
      BANCO1
      clrf   LCD_DATA
      BANCO0
      ESCRIBIR
      COMANDO
      return
;
;-------------------------------------------------------------------------
LCD_TABNUM   addwf   PCL,1
      dt   "0123456789ABCDEF"
;
;
;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
;            SUBRUTINAS INTERNAS DEL LCD
;************************************************************************************************
;LCD_BUSY:   Lectura del Flag Busy y la direccion.
LCD_BUSY      LEER
      BANCO1
      comf   LCD_DATA,1   ;Puerto B como entrada
      BANCO0
      ENABLE
      nop
      btfsc   LCD_DATA,7   ;Chequea bit de Busy
      goto   $-1
      DISABLE
      BANCO1
      clrf   LCD_DATA      ;Puerto B como salida
      BANCO0
      ESCRIBIR
      return
;
;-------------------------------------------------------------------------
;LCD_E:      Pulso de Enable
LCD_E      ENABLE
      nop
      DISABLE         ;Desactiva E
      COMANDO
      return
;
;-------------------------------------------------------------------------
;LCD_COMAND:   Escritura de comandos del LCD
;      W = Codigo de comando para el LCD
;      W ==> LCD_DATA
LCD_COMAND   movwf   LCD_DATA      ;Codigo de comando.
      call   LCD_BUSY
      goto   LCD_E      ;Genera pulso de E
;
;-------------------------------------------------------------------------
;LCD_FUNCIONSET:   Configura ela fuente del caracter y número de lineas. No se cambia DL
;      El modo de control deseado deberá cargarse en los 2 bits terceros de W:
;            x x x x b3 b2 x x
;      b2 :   0 = caracter de 5x7         1 = de 5x10
;      b3 :   0 = display de 1 linea      1 = de 2 lineas
;      b0,1,4-7 : sin importancia
LCD_FUNCIONSET   andlw   0x0C      ;Nos quedamos con b3-b2 (DL no se cambia)
      iorlw   0x30      ;Incorporamos el bit de función y 8 bits
      goto   LCD_COMAND

Título: Re: ERROR EN SIMULACION DE PROTEUS
Publicado por: aamoros79 en 11 de Julio de 2006, 04:20:19
que significa el "$" que pones en los goto?

'  goto   $-1'
Título: Re: ERROR EN SIMULACION DE PROTEUS
Publicado por: Veguepic en 11 de Julio de 2006, 11:08:35
Hola aamoros79:

Segun entiendo el $ en el goto afecta al contador del programa, en este caso le esta restando una unidad, lo que quiere decir es que lo esta regresando a la posicion anterior. Por ejemplo:

      btfsc   LCD_DATA,7   ;Chequea bit de Busy
      goto   $-1

En este caso repite el chequeo del bit de Busy. Creo que otra forma serria:

BUSY
      btfsc   LCD_DATA,7   ;Chequea bit de Busy
      goto   BUSY

Hola Elias111:

Te sugiero pongas mas datos de tu problema y a ser posible algun diagrama, pues entenderas que leer semejante codigo puede tomar tiempo y entender como esta conectado el pic mas.

Un Saludo.
Título: Re: ERROR EN SIMULACION DE PROTEUS
Publicado por: vszener en 11 de Julio de 2006, 11:47:33
Yo sugeriria que pongas el problema en PROTEUS que te aparece, asi nos podemos hacer una idea de que es lo que esta fallando...


Suerte!!! :wink:
Título: Re: ERROR EN SIMULACION DE PROTEUS
Publicado por: Chaly29 en 11 de Julio de 2006, 17:57:08
Hola elias111, yo te diría que las tablas las pongas al principio del programa, en la posición ORG 0x0005, para que no tengas problemas con ellas.

Un saludo.

Atte. CARLOS.