Author Topic: Microchip assembly language  (Read 7577 times)

0 Members and 1 Guest are viewing this topic.

Offline jcaser1948Topic starter

  • Contributor
  • Posts: 10
  • Country: es
Microchip assembly language
« on: July 27, 2016, 02:54:41 pm »
This code snippet worked perfectly with an older verssion of MPlab, but the new microchip assambler compiler  does not accept it anymore.
The offending part is equ   $    what can I do to substitute this statement with an equivalent one whitout rewriting everything?
Tabla_Mensajes   movwf   PCL      ;Calcula el desplazamiento sobre la tabla

Mens_0      equ   $      ;equ Mens_0 apunta al primer carácter del mensaje 0
      retlw   'H'
      retlw   'o'
      retlw   'l'
      retlw   'a'
      retlw   0x00      ;Ultimo carácter del mensaje 0

Mens_1      equ   $      ;equ Mens_1 apunta al primer carácter del mensaje 1
      retlw   'A'
      retlw   'd'
      retlw   'i'
      retlw   'o'
      retlw   's'
      retlw   0x00      ;Ultimo carácter del mensaje 1
Help would be appreciated, since I an new to the PICS

 

Offline Andy Watson

  • Super Contributor
  • ***
  • Posts: 2085
Re: Microchip assembly language
« Reply #1 on: July 27, 2016, 03:20:08 pm »
Why do you need the equ $ statement? Mens_0 and Mens_1 should be sufficient labels to identify the start address of the tables.
 
The following users thanked this post: jcaser1948

Offline StillTrying

  • Super Contributor
  • ***
  • Posts: 2850
  • Country: se
  • Country: Broken Britain
Re: Microchip assembly language
« Reply #2 on: July 27, 2016, 03:21:20 pm »
Bit of a guess;

Mens_0      equ   $   % .256  ;equ Mens_0
.  That took much longer than I thought it would.
 

Online mikerj

  • Super Contributor
  • ***
  • Posts: 3240
  • Country: gb
Re: Microchip assembly language
« Reply #3 on: July 27, 2016, 03:26:01 pm »
Why do you need the equ $ statement? Mens_0 and Mens_1 should be sufficient labels to identify the start address of the tables.

^^^ This.  The assembler knows this is a label for an address, you don't need to add the equ $.
 

Offline StillTrying

  • Super Contributor
  • ***
  • Posts: 2850
  • Country: se
  • Country: Broken Britain
Re: Microchip assembly language
« Reply #4 on: July 27, 2016, 03:33:57 pm »
^^^ This.  The assembler knows this is a label for an address, you don't need to add the equ $.

I'm thinking you need to force it to just have the lower byte of the address.
.  That took much longer than I thought it would.
 
The following users thanked this post: jcaser1948

Offline Andy Watson

  • Super Contributor
  • ***
  • Posts: 2085
Re: Microchip assembly language
« Reply #5 on: July 27, 2016, 04:01:04 pm »
^^^ This.  The assembler knows this is a label for an address, you don't need to add the equ $.

I'm thinking you need to force it to just have the lower byte of the address.
In that case it should be resolved with the LOW() or HIGH() macros when mens_0 is used:
e.g.  movlw LOW(mens_0)

 

Offline jcaser1948Topic starter

  • Contributor
  • Posts: 10
  • Country: es
Re: Microchip assembly language
« Reply #6 on: July 27, 2016, 06:17:08 pm »
Why do you need the equ $ statement? Mens_0 and Mens_1 should be sufficient labels to identify the start address of the tables.
It compiles I have to test if it works as intended. Thanks
 

Offline jcaser1948Topic starter

  • Contributor
  • Posts: 10
  • Country: es
Re: Microchip assembly language
« Reply #7 on: July 27, 2016, 06:20:04 pm »
Why do you need the equ $ statement? Mens_0 and Mens_1 should be sufficient labels to identify the start address of the tables.

^^^ This.  The assembler knows this is a label for an address, you don't need to add the equ $.
It does not compile Operand is too complex
Thanks nevertheless
 

Offline jcaser1948Topic starter

  • Contributor
  • Posts: 10
  • Country: es
Re: Microchip assembly language
« Reply #8 on: July 27, 2016, 06:22:35 pm »
^^^ This.  The assembler knows this is a label for an address, you don't need to add the equ $.

I'm thinking you need to force it to just have the lower byte of the address.
In that case it should be resolved with the LOW() or HIGH() macros when mens_0 is used:
e.g.  movlw LOW(mens_0)
Yes, Ithink this is the case
Thaks
 

Offline Bruce Abbott

  • Frequent Contributor
  • **
  • Posts: 627
  • Country: nz
    • Bruce Abbott's R/C Models and Electronics
Re: Microchip assembly language
« Reply #9 on: July 27, 2016, 07:07:24 pm »
Just use normal address labels, like this:-

Code: [Select]
Tabla_Mensajes:
      movwf   PCL      ;Calcula el desplazamiento sobre la tabla
Mens_0:                ;equ Mens_0 apunta al primer carácter del mensaje 0
      retlw   'H'
      retlw   'o'
      retlw   'l'
      retlw   'a'
      retlw   0x00      ;Ultimo carácter del mensaje 0

Mens_1:                 ;equ Mens_1 apunta al primer carácter del mensaje 1
      retlw   'A'
      retlw   'd'
      retlw   'i'
      retlw   'o'
      retlw   's'
      retlw   0x00      ;Ultimo carácter del mensaje 1
      .
      .
      movlw   Mens_0
      call    Tabla_Mensajes
      .
 

Online mikerj

  • Super Contributor
  • ***
  • Posts: 3240
  • Country: gb
Re: Microchip assembly language
« Reply #10 on: July 28, 2016, 08:08:35 am »
Why do you need the equ $ statement? Mens_0 and Mens_1 should be sufficient labels to identify the start address of the tables.

^^^ This.  The assembler knows this is a label for an address, you don't need to add the equ $.
It does not compile Operand is too complex
Thanks nevertheless

You just said it did compile in your previous post?
 

Offline jcaser1948Topic starter

  • Contributor
  • Posts: 10
  • Country: es
Re: Microchip assembly language
« Reply #11 on: July 29, 2016, 11:01:26 am »
Here is the complete program

;   EJERCICIO 18 : LCD con varios mensajes
;      -----------------------------------
;

      List   p=16F870   ;Tipo de procesador
      include   "P16F870.INC"   ;Definiciones de registros internos
                          
Lcd_var      equ   0x20      ;Variables (2) de las rutinas de manejo del LCD
Delay_Cont   equ   0x21      ;Variable para la temporización
Temporal_1   equ   0x22      ;Variable temporal
Temporal_2   equ   0x23      ;Variable temporal

      org   0x00      ;Vector de Reset
      goto   Inicio
      org   0x05      ;Salva vector de interrupción

      include   "lcd_cxx.inc"   ;Incluye las rutinas de manejo del LCD

;******************************************************************************************
;Según el valor contenido en el registro W, se devuelve el carácter a visualizar

Tabla_Mensajes   movwf   PCL      ;Calcula el desplazamiento sobre la tabla

Mens_0      equ   $  ;equ Mens_0 apunta al primer carácter del mensaje 0
      
      retlw   'H'
      retlw   'o'
      retlw   'l'
      retlw   'a'
      retlw   0x00      ;Ultimo carácter del mensaje 0
      
Mens_1       equ    $ ; Mens_1 apunta al primer carácter del mensaje 1
      
       retlw   'A'
      retlw   'd'
      retlw   'i'
      retlw   'o'
      retlw   's'
      retlw   0x00      ;Ultimo carácter del mensaje 1
      

;*********************************************************************************
;Delay_var: Esta rutina de propósito general realiza una temporización variable
;entre 50 mS y 12.8". Se emplea un preescaler de 256 y al TMR0 se le carga con 195.
;La velocidad de trabajo es de 4Mhz y por tanto el TMR0 se incrementa cada uS. De
;esta forma, el TMR0 debe contar 195 eventos que, con un preescaler de 256 hace una
;intervalo total de 50000 uS/50 mS (195 * 256). El valor 195 hay que expresarlo
;en Hex. (c3) y como el TMR0 es ascendente habrá que cargar su complemento (3C hex.)
;Dicho intervalo de 50 mS se repite tantes veces como indique la variable "Delay_cont",
;es por ello que el delay mínimo es de 50 mS ("Delay_cont=1) y el máxima de 12.8"
;(Delay_cont=255).

Delay_var:   bcf   INTCON,T0IF   ;Desconecta el flag de rebosamiento
      movlw   0x3c      ;Complemento hex. de 195
      movwf   TMR0      ;carga el TMR0
Intervalo   clrwdt         ;Refrescar el WDT
      btfss   INTCON,T0IF   ;Rebasamiento del TMR0 ??
      goto   Intervalo   ;Todavía no      
      decfsz   Delay_Cont,F   ;Decrementa contador de intervalos
      goto   Delay_var   ;Repite el intervalo de 50 mS
      return   

;*************************************************************************************
;Mensaje: Esta rutina visualiza en el LCD el mensaje cuyo inicio está  indicado en
;el acumulador. El fin de un mensaje se determina mediante el código 0x00

Mensaje         movwf   Temporal_1      ;Salva posición de la tabla
Mensaje_1       movf    Temporal_1,W    ;Recupera posición de la tabla
                call    Tabla_Mensajes  ;Busca caracter de salida
                movwf   Temporal_2      ;Guarda el caracter
                movf    Temporal_2,F
                btfss   STATUS,Z        ;Mira si es el último
                goto    No_es_ultimo
                return
No_es_ultimo    call    LCD_DATO        ;Visualiza en el LCD
                incf    Temporal_1,F    ;Siguiente caracter
                goto    Mensaje_1

;**********************************************************************************
;
Inicio           clrf    PORTB      ;Borra los latch de salida
      bsf   STATUS,RP0   ;Selecciona banco 1
      clrf   TRISB      ;Puerta B se configura como salida
      movlw   b'00011000'      
      movwf   TRISA      ;RA0-RA2 salidas, RA3-RA4 entradas
      movlw   b'00000110'      
      movwf   ADCON1      ;Configuramos como salidas digitales      
      movlw   b'00000111'
      movwf   OPTION_REG   ;Preescaler de 256 para el TMR0
      bcf   STATUS,RP0   ;Selecciona banco 0   
      
      call   LCD_INI      ;Secuencia de inicio del LCD
      movlw   b'00001100'
      call   LCD_REG      ;Envía instrucción: LCD ON, Cursor OFF y blink OFF

Loop      movlw   b'00000001'
      call   LCD_REG      ;Borra LCD y Home (colocar cursor en 1ª posición)
      movlw   Mens_0
      call   Mensaje      ;Visualiza el mensaje 0
      movlw   .20
      movwf   Delay_Cont
      call   Delay_var   ;Temporiza 2 segundos
      movlw   b'00000001'
      call   LCD_REG      ;Borra LCD y Home (colocar cursor en 1ª posición)
      movlw   Mens_1
      call   Mensaje      ;Visualiza el mensaje 1
      movlw   .20
      movwf   Delay_Cont
      call   Delay_var   ;Temporiza 2 segundos
      goto   Loop

      END         ;Fin del programa fuente

And here the include
;                               LCD_CXX.INC
;                  
;
;El conjunto de rutinas que se presentan a continuación permiten realizar las tareas básicas
;de control del módulo de visualización LCD. Este fichero se debe incluir en los futuros
;programas fuente mediante la directiva INCLUDE

                                       
#define ENABLE       bsf PORTA,2        ;Activa señal E
#define DISABLE      bcf PORTA,2        ;Desactiva señal E
#define LEER         bsf PORTA,1        ;Pone LCD en Modo RD
#define ESCRIBIR     bcf PORTA,1        ;Pone LCD en Modo WR
#define OFF_COMANDO  bcf PORTA,0        ;Desactiva RS (modo comando)
#define ON_COMANDO   bsf PORTA,0        ;Activa RS (modo dato

      CBLOCK   Lcd_var      ;Inicio de las variables. Será la primera                  
      Lcd_Temp_1      ;direccón libre disponible
      Lcd_Temp_2
      ENDC                                 

;*************************************************************************
;UP_LCD: Configuración PIC para el LCD.
;
UP_LCD          bsf     STATUS,RP0      ;Banco 1
                clrf    PORTB           ;RB <0-7> salidas digitales
                movlw   b'00011000'
      movwf   PORTA           ;RA0-RA2 salidas, RA3-RA4 entradas
                bcf     STATUS,RP0      ;Banco 0
                OFF_COMANDO             ;RS=0
                DISABLE                 ;E=0
                return
;
;**************************************************************************
;LCD_BUSY: Lectura del Flag Busy y la dirección.
;
LCD_BUSY        LEER                    ;Pone el LCD en Modo RD
                bsf     STATUS,RP0           
                movlw   H'FF'
                movwf   PORTB           ;Puerta B como entrada
                bcf     STATUS,RP0      ;Selecciona el banco 0
                ENABLE                  ;Activa el LCD
                nop
LCD_BUSY_1   btfsc   PORTB,7         ;Chequea bit de Busy
                goto    LCD_BUSY_1      ;
                DISABLE                 ;Desactiva LCD
                bsf     STATUS,RP0                               
                clrf    PORTB           ;Puerta B salida
                bcf     STATUS,RP0                             
                ESCRIBIR                ;Pone LCD en modo WR
                return

;**************************************************************************
;LCD_E: Pulso de Enable
;
LCD_E           ENABLE                  ;Activa E
                nop
                DISABLE                 ;Desactiva E
                return
;
;**************************************************************************
;LCD_DATO: Escritura de datos en DDRAM o CGRAM. Envía el dato presente en el W
;
LCD_DATO        OFF_COMANDO             ;Desactiva RS (modo comando)
                movwf   PORTB           ;Valor ASCII a sacar por portb
                call    LCD_BUSY        ;Espera a que se libere el LCD
                ON_COMANDO              ;Activa RS (modo dato).
                goto    LCD_E           ;Genera pulso de E

;**************************************************************************
;LCD_REG: Escritura de comandos en el LCD. Envía el comando presente en el W

LCD_REG         OFF_COMANDO             ;Desactiva RS (modo comando)
                movwf   PORTB           ;Código de comando.
                call    LCD_BUSY        ;LCD libre?.
                goto    LCD_E           ;SI.Genera pulso de E.

;***************************************************************************
;LCD_INI: inicialización del LCD enviando el comando "Function Set" 3 veces consecutivas
;con un intervalo de unos 5 mS. El LCD queda borrado y el cursor en la primera posición

LCD_INI      movlw   b'00111000'
      call   LCD_REG      ;Código de instrucción
      call   LCD_DELAY   ;Temporiza
      movlw   b'00111000'
      call   LCD_REG      ;Código de instrucción
      call   LCD_DELAY   ;Temporiza
      movlw   b'00111000'
      call   LCD_REG      ;Código de instrucción
      call   LCD_DELAY   ;Temporiza
      movlw   b'00000001'     ;Borra LCD y Home.
                call    LCD_REG
                return

;*****************************************************************************
;LCD_DELAY: Rutina de temporización de unos 5 mS. Se emplean las variables Lcd_Temp_1
;y LCD_Temp_2 en lugar del TMR0. Este queda libre para las aplicaciones del usuario

LCD_DELAY:   clrwdt
                movlw   .10
                movwf   Lcd_Temp_1
                clrf   Lcd_Temp_2
LCD_DELAY_1:   decfsz   Lcd_Temp_2,F
      goto   LCD_DELAY_1
      decfsz   Lcd_Temp_1,F
      goto   LCD_DELAY_1
      return

            We need the statement     " Mens_0      equ   $   (programcounter)   ;Mens_0 apunta al primer carácter del mensaje 0" in order to adress the lower byte of the list .
Try co compile the program and make (when possible; any suggestios how I couls access the first caracter of the list "Hola"
Thanks
 

Offline Andy Watson

  • Super Contributor
  • ***
  • Posts: 2085
Re: Microchip assembly language
« Reply #12 on: July 29, 2016, 11:46:03 am »
            We need the statement     " Mens_0      equ   $   (programcounter)   ;Mens_0 apunta al primer carácter del mensaje 0" in order to adress the lower byte of the list .
The example that I gave earlier is apparently the gputil version. The mplab version of the assembler directive is simply "low", e.g.

      call   LCD_REG      ;Borra LCD y Home (colocar cursor en 1ª posición)
      movlw   low  Mens_1
      call   Mensaje      ;Visualiza el mensaje 1

See page 40:
http://ww1.microchip.com/downloads/en/DeviceDoc/33014K.pdf
 

Offline Ata

  • Contributor
  • Posts: 19
  • Country: ve
Re: Microchip assembly language
« Reply #13 on: July 29, 2016, 11:59:21 am »
Hi Jcaser..

All you need is to add the following upper case code in your Routine: Mensaje.
And it will work ok.

Mensaje         movwf   Temporal_1      ;Salva posición de la tabla

      MOVLW   LOW(Tabla_mensajes)+1
      SUBWF   Temporal_1,F

Mensaje_1       movf    Temporal_1,W    ;Recupera posición de la tabla
                call    Tabla_Mensajes  ;Busca caracter de salida
                movwf   Temporal_2      ;Guarda el caracter
                movf    Temporal_2,F
                btfss   STATUS,Z        ;Mira si es el último
                goto    No_es_ultimo
                return
No_es_ultimo    call    LCD_DATO        ;Visualiza en el LCD
                incf    Temporal_1,F    ;Siguiente caracter
                goto    Mensaje_1


 

Offline Ata

  • Contributor
  • Posts: 19
  • Country: ve
Re: Microchip assembly language
« Reply #14 on: July 29, 2016, 12:27:34 pm »
Jcaser

I forgot .... Remove the equ $ from Mens_0 and Mens_1 ... Leave them as labels

Tabla_Mensajes   movwf   PCL      ;Calcula el desplazamiento sobre la tabla

Mens_0      retlw   'H'
                  retlw   'o'
                  retlw   'l'
                  retlw   'a'
                  retlw   0x00      ;Ultimo carácter del mensaje 0
     
Mens_1       retlw   'A'
                   retlw   'd'
                   retlw   'i'
                   retlw   'o'
                   retlw   's'
                   retlw   0x00      ;Ultimo carácter del mensaje 1
 

Offline Ata

  • Contributor
  • Posts: 19
  • Country: ve
Re: Microchip assembly language
« Reply #15 on: July 29, 2016, 12:38:10 pm »
Jcaser..

Another omission... Please correct your Tabla_mensajes as follows:

Tabla_mensajes   ADDWF   PCL
Mens_0   DT   "Hola",00
Mens_1   DT   "Adios",00

Now all will work ok
 

Offline Ata

  • Contributor
  • Posts: 19
  • Country: ve
Re: Microchip assembly language
« Reply #16 on: July 29, 2016, 01:16:54 pm »
Jcaser

Every time you write to PCL ( movwf PCL, addwf PCL, subwf PCL, andwf PCL, etc) you will change PCL's contents but also PCH will take the actual PCLATH value.....

This means that your data-table: Tabla_mensajes  Must be within any 256 boundary program area pointed by the contents of PCLATH.

So you need to include in your start area (INICIO) the following code:

MOVLW   HIGH Tabla_mensajes
MOVWF   PCLATH

This way, when the code ADDWF PCL or MOVWF PCL are executed... PCH will have the corresponding 256 address bank where your Table_mensajes is located.

At power-on-reset  PCLATH=00, If your Tabla_mensajes is not placed on the first 256 byte-address.. It will explain why it did not work at the beginning.
 

Offline jcaser1948Topic starter

  • Contributor
  • Posts: 10
  • Country: es
Re: Microchip assembly language
« Reply #17 on: July 29, 2016, 02:48:54 pm »
Dear Alta
I have tried your solution.
The code is like this
;   EJERCICIO 18 : LCD con varios mensajes
;      -----------------------------------
;

      List   p=16F870   ;Tipo de procesador
      include   "P16F870.INC"   ;Definiciones de registros internos
                          
Lcd_var      equ   0x20      ;Variables (2) de las rutinas de manejo del LCD
Delay_Cont   equ   0x21      ;Variable para la temporización
Temporal_1   equ   0x22      ;Variable temporal
Temporal_2   equ   0x23      ;Variable temporal

      org   0x00      ;Vector de Reset
      goto   Inicio
      org   0x05      ;Salva vector de interrupción

      include   "lcd_cxx.inc"   ;Incluye las rutinas de manejo del LCD

;******************************************************************************************
;Según el valor contenido en el registro W, se devuelve el carácter a visualizar

Tabla_Mensajes   movwf   PCL      ;Calcula el desplazamiento sobre la tabla
      
Tabla_mensajes   ADDWF   PCL
     Mens_0    DT   "Hola",00
     Mens_1    DT   "Adios",00

;*********************************************************************************
;Delay_var: Esta rutina de propósito general realiza una temporización variable
;entre 50 mS y 12.8". Se emplea un preescaler de 256 y al TMR0 se le carga con 195.
;La velocidad de trabajo es de 4Mhz y por tanto el TMR0 se incrementa cada uS. De
;esta forma, el TMR0 debe contar 195 eventos que, con un preescaler de 256 hace una
;intervalo total de 50000 uS/50 mS (195 * 256). El valor 195 hay que expresarlo
;en Hex. (c3) y como el TMR0 es ascendente habrá que cargar su complemento (3C hex.)
;Dicho intervalo de 50 mS se repite tantes veces como indique la variable "Delay_cont",
;es por ello que el delay mínimo es de 50 mS ("Delay_cont=1) y el máxima de 12.8"
;(Delay_cont=255).

Delay_var:   bcf   INTCON,T0IF   ;Desconecta el flag de rebosamiento
      movlw   0x3c      ;Complemento hex. de 195
      movwf   TMR0      ;carga el TMR0
Intervalo   clrwdt         ;Refrescar el WDT
      btfss   INTCON,T0IF   ;Rebasamiento del TMR0 ??
      goto   Intervalo   ;Todavía no      
      decfsz   Delay_Cont,F   ;Decrementa contador de intervalos
      goto   Delay_var   ;Repite el intervalo de 50 mS
      return   

;*************************************************************************************
;Mensaje: Esta rutina visualiza en el LCD el mensaje cuyo inicio está  indicado en
;el acumulador. El fin de un mensaje se determina mediante el código 0x00

Mensaje         movwf   Temporal_1      ;Salva posición de la tabla
      
      MOVLW   LOW(Tabla_mensajes)+1
      SUBWF   Temporal_1,F
      
Mensaje_1       movf    Temporal_1,W    ;Recupera posición de la tabla
      
      
                call    Tabla_Mensajes  ;Busca caracter de salida
                movwf   Temporal_2      ;Guarda el caracter
                movf    Temporal_2,F
                btfss   STATUS,Z        ;Mira si es el último
                goto    No_es_ultimo
                return
No_es_ultimo    call    LCD_DATO        ;Visualiza en el LCD
                incf    Temporal_1,F    ;Siguiente caracter
                goto    Mensaje_1

;**********************************************************************************
;
Inicio        
      
      MOVLW   HIGH Tabla_mensajes
      MOVWF   PCLATH

      clrf    PORTB      ;Borra los latch de salida
      bsf   STATUS,RP0   ;Selecciona banco 1
      clrf   TRISB      ;Puerta B se configura como salida
      movlw   b'00011000'      
      movwf   TRISA      ;RA0-RA2 salidas, RA3-RA4 entradas
      movlw   b'00000110'      
      movwf   ADCON1      ;Configuramos como salidas digitales      
      movlw   b'00000111'
      movwf   OPTION_REG   ;Preescaler de 256 para el TMR0
      bcf   STATUS,RP0   ;Selecciona banco 0   
      
      call   LCD_INI      ;Secuencia de inicio del LCD
      movlw   b'00001100'
      call   LCD_REG      ;Envía instrucción: LCD ON, Cursor OFF y blink OFF

Loop      movlw   b'00000001'
      call   LCD_REG      ;Borra LCD y Home (colocar cursor en 1ª posición)
      movlw   Mens_0
      call   Mensaje      ;Visualiza el mensaje 0
      movlw   .20
      movwf   Delay_Cont
      call   Delay_var   ;Temporiza 2 segundos
      movlw   b'00000001'
      call   LCD_REG      ;Borra LCD y Home (colocar cursor en 1ª posición)
      movlw   Mens_1
      call   Mensaje      ;Visualiza el mensaje 1
      movlw   .20
      movwf   Delay_Cont
      call   Delay_var   ;Temporiza 2 segundos
      goto   Loop

      END         ;Fin del programa fuente

It still does not compile, probaly because I undertood something wrong in your kindly explanatios. Please check if this code is like what  you intended to convey Gracias
 

Offline jcaser1948Topic starter

  • Contributor
  • Posts: 10
  • Country: es
Re: Microchip assembly language
« Reply #18 on: July 29, 2016, 03:07:47 pm »
            We need the statement     " Mens_0      equ   $   (programcounter)   ;Mens_0 apunta al primer carácter del mensaje 0" in order to adress the lower byte of the list .
The example that I gave earlier is apparently the gputil version. The mplab version of the assembler directive is simply "low", e.g.

      call   LCD_REG      ;Borra LCD y Home (colocar cursor en 1ª posición)
      movlw   low  Mens_1
      call   Mensaje      ;Visualiza el mensaje 1

See page 40:
http://ww1.microchip.com/downloads/en/DeviceDoc/33014K.pdf
Thaks Andy, with your solution it compiles and works fine
 Gracias
 

Offline Ata

  • Contributor
  • Posts: 19
  • Country: ve
Re: Microchip assembly language
« Reply #19 on: July 29, 2016, 04:24:39 pm »
Jcaser..

It doesn't compile because you had duplicated the label: Tabla_mensajes

You have to ways to do it...  Both needs to set PCLATH at the beginnig (Inicio)
If you don't set PCLATH.. I will only work if Table_mensajes is located on the first 256 address of Prog-memory.

MOVLW    HIGH Tabla_mensajes
MOVWf    PCLATH                            So you can place your Tabla_mensajes  wherever you want

And you don't need: Mens_0  equ $... Also, doing MOVLW LOW Mens_0 is the same like MOVLW Mens_0  Because the MPASM will only take the label's (Mens_0) low byte address by default.

Andy's way: (Better)

Tabla_Mensajes   MOVWF   PCL      ;Calcula el desplazamiento sobre la tabla
Mens_0    DT   "Hola",00
Mens_1    DT   "Adios",00

Mensaje        movwf    Temporal_1        ;Salva posición de la tabla
Mensaje_1    movf    Temporal_1,W      ;Recupera posición de la tabla
                     call       Tabla_Mensajes   ;Busca caracter de salida
                     movwf  Temporal_2          ;Guarda el caracter
                     movf    Temporal_2,F
                     btfss    STATUS,Z              ;Mira si es el último
                     goto    No_es_ultimo
                     return
No_es_ultimo    call    LCD_DATO        ;Visualiza en el LCD
                         incf    Temporal_1,F    ;Siguiente caracter
                         goto    Mensaje_1

        .....
        call   LCD_REG      ;Borra LCD y Home (colocar cursor en 1ª posición)
        movlw   low Mens_0
        call   Mensaje      ;Visualiza el mensaje 0
        .....

My Way:

Tabla_Mensajes   ADDWF  PCL      ;Calcula el desplazamiento sobre la tabla
Mens_0    DT   "Hola",00
Mens_1    DT   "Adios",00

Mensaje        movwf    Temporal_1        ;Salva posición de la tabla
                     MOVLW   LOW(Tabla_mensajes)+1
                     SUBWF   Temporal_1,F
Mensaje_1    movf    Temporal_1,W      ;Recupera posición de la tabla
                     call       Tabla_Mensajes   ;Busca caracter de salida
                     movwf  Temporal_2          ;Guarda el caracter
                     movf    Temporal_2,F
                     btfss    STATUS,Z              ;Mira si es el último
                     goto    No_es_ultimo
                     return
No_es_ultimo    call    LCD_DATO        ;Visualiza en el LCD
                         incf    Temporal_1,F    ;Siguiente caracter
                         goto    Mensaje_1

        ........
        call   LCD_REG      ;Borra LCD y Home (colocar cursor en 1ª posición)
        movlw   low Mens_0
        call   Mensaje      ;Visualiza el mensaje 0
        ........
 

Offline jcaser1948Topic starter

  • Contributor
  • Posts: 10
  • Country: es
Re: Microchip assembly language
« Reply #20 on: July 29, 2016, 05:41:20 pm »
ATA,Thanks for your prompt answer .
With your solutio it does not compile. It says "Symbol not previously defined (Tabla_mensajes)"
here is the program again as I understood your way

;   EJERCICIO 18 : LCD con varios mensajes
;      -----------------------------------
;

      List   p=16F870   ;Tipo de procesador
      include   "P16F870.INC"   ;Definiciones de registros internos
                          
Lcd_var      equ   0x20      ;Variables (2) de las rutinas de manejo del LCD
Delay_Cont   equ   0x21      ;Variable para la temporización
Temporal_1   equ   0x22      ;Variable temporal
Temporal_2   equ   0x23      ;Variable temporal

      org   0x00      ;Vector de Reset
      goto   Inicio
      org   0x05      ;Salva vector de interrupción

      include   "lcd_cxx.inc"   ;Incluye las rutinas de manejo del LCD

;******************************************************************************************
;Según el valor contenido en el registro W, se devuelve el carácter a visualizar

         
      
Tabla_Mensajes   ADDWF   PCL ;Calcula el desplazamiento sobre la tabla
Mens_0    DT   "Hola",00
Mens_1    DT   "Adios",00

;*********************************************************************************
;Delay_var: Esta rutina de propósito general realiza una temporización variable
;entre 50 mS y 12.8". Se emplea un preescaler de 256 y al TMR0 se le carga con 195.
;La velocidad de trabajo es de 4Mhz y por tanto el TMR0 se incrementa cada uS. De
;esta forma, el TMR0 debe contar 195 eventos que, con un preescaler de 256 hace una
;intervalo total de 50000 uS/50 mS (195 * 256). El valor 195 hay que expresarlo
;en Hex. (c3) y como el TMR0 es ascendente habrá que cargar su complemento (3C hex.)
;Dicho intervalo de 50 mS se repite tantes veces como indique la variable "Delay_cont",
;es por ello que el delay mínimo es de 50 mS ("Delay_cont=1) y el máxima de 12.8"
;(Delay_cont=255).

Delay_var:   bcf   INTCON,T0IF   ;Desconecta el flag de rebosamiento
      movlw   0x3c      ;Complemento hex. de 195
      movwf   TMR0      ;carga el TMR0
Intervalo   clrwdt         ;Refrescar el WDT
      btfss   INTCON,T0IF   ;Rebasamiento del TMR0 ??
      goto   Intervalo   ;Todavía no      
      decfsz   Delay_Cont,F   ;Decrementa contador de intervalos
      goto   Delay_var   ;Repite el intervalo de 50 mS
      return   

;*************************************************************************************
;Mensaje: Esta rutina visualiza en el LCD el mensaje cuyo inicio está  indicado en
;el acumulador. El fin de un mensaje se determina mediante el código 0x00

Mensaje         movwf   Temporal_1      ;Salva posición de la tabla
      
      MOVLW   LOW(Tabla_mensajes)+1
      SUBWF   Temporal_1,F
      
Mensaje_1       movf    Temporal_1,W    ;Recupera posición de la tabla
      
      
                call    Tabla_Mensajes  ;Busca caracter de salida
                movwf   Temporal_2      ;Guarda el caracter
                movf    Temporal_2,F
                btfss   STATUS,Z        ;Mira si es el último
                goto    No_es_ultimo
                return
No_es_ultimo    call    LCD_DATO        ;Visualiza en el LCD
                incf    Temporal_1,F    ;Siguiente caracter
                goto    Mensaje_1

;**********************************************************************************
;
Inicio        
      
      MOVLW   HIGH Tabla_mensajes
      MOVWF   PCLATH

      clrf    PORTB      ;Borra los latch de salida
      bsf   STATUS,RP0   ;Selecciona banco 1
      clrf   TRISB      ;Puerta B se configura como salida
      movlw   b'00011000'      
      movwf   TRISA      ;RA0-RA2 salidas, RA3-RA4 entradas
      movlw   b'00000110'      
      movwf   ADCON1      ;Configuramos como salidas digitales      
      movlw   b'00000111'
      movwf   OPTION_REG   ;Preescaler de 256 para el TMR0
      bcf   STATUS,RP0   ;Selecciona banco 0   
      
      call   LCD_INI      ;Secuencia de inicio del LCD
      movlw   b'00001100'
      call   LCD_REG      ;Envía instrucción: LCD ON, Cursor OFF y blink OFF

Loop      movlw   b'00000001'
      call   LCD_REG      ;Borra LCD y Home (colocar cursor en 1ª posición)
      movlw   low Mens_0
      call   Mensaje      ;Visualiza el mensaje 0
      movlw   .20
      movwf   Delay_Cont
      call   Delay_var   ;Temporiza 2 segundos
      movlw   b'00000001'
      call   LCD_REG      ;Borra LCD y Home (colocar cursor en 1ª posición)
      movlw   low Mens_1
      call   Mensaje      ;Visualiza el mensaje 1
      movlw   .20
      movwf   Delay_Cont
      call   Delay_var   ;Temporiza 2 segundos
      goto   Loop

      END         ;Fin del programa fuente
You may compile it, if you like;the Include is in my previous post .
Y gracias por todo
 

Offline Ata

  • Contributor
  • Posts: 19
  • Country: ve
Re: Microchip assembly language
« Reply #21 on: July 29, 2016, 10:37:17 pm »
Jcaser .. Please read the compiler errors...
Tabla_mensajes was misspelled as Tabla_Mensajes... That's the error.
Change all to Tabla_mensajes and all errors are gone..

Now its ok..

;   EJERCICIO 18 : LCD con varios mensajes
;      -----------------------------------
;

      List   p=16F870   ;Tipo de procesador
      include   "P16F870.INC"   ;Definiciones de registros internos
                         
Lcd_var      equ   0x20      ;Variables (2) de las rutinas de manejo del LCD
Delay_Cont   equ   0x21      ;Variable para la temporización
Temporal_1   equ   0x22      ;Variable temporal
Temporal_2   equ   0x23      ;Variable temporal

      org   0x00      ;Vector de Reset
      goto   Inicio
      org   0x05      ;Salva vector de interrupción

      include   "lcd_cxx.inc"   ;Incluye las rutinas de manejo del LCD

;******************************************************************************************
;Según el valor contenido en el registro W, se devuelve el carácter a visualizar

         
     
Tabla_mensajes   ADDWF   PCL,F ;Calcula el desplazamiento sobre la tabla
Mens_0    DT   "Hola",00
Mens_1    DT   "Adios",00

;*********************************************************************************
Delay_var:   bcf   INTCON,T0IF   ;Desconecta el flag de rebosamiento
      movlw   0x3c      ;Complemento hex. de 195
      movwf   TMR0      ;carga el TMR0
Intervalo   clrwdt         ;Refrescar el WDT
      btfss   INTCON,T0IF   ;Rebasamiento del TMR0 ??
      goto   Intervalo   ;Todavía no     
      decfsz   Delay_Cont,F   ;Decrementa contador de intervalos
      goto   Delay_var   ;Repite el intervalo de 50 mS
      return   

;*************************************************************************************
;Mensaje: Esta rutina visualiza en el LCD el mensaje cuyo inicio está  indicado en
;el acumulador. El fin de un mensaje se determina mediante el código 0x00

Mensaje         movwf   Temporal_1      ;Salva posición de la tabla
     
      MOVLW   LOW(Tabla_mensajes)+1
      SUBWF   Temporal_1,F
     
Mensaje_1       movf    Temporal_1,W    ;Recupera posición de la tabla
     
     
                call    Tabla_mensajes  ;Busca caracter de salida
                movwf   Temporal_2      ;Guarda el caracter
                movf    Temporal_2,F
                btfss   STATUS,Z        ;Mira si es el último
                goto    No_es_ultimo
                return
No_es_ultimo    call    LCD_DATO        ;Visualiza en el LCD
                incf    Temporal_1,F    ;Siguiente caracter
                goto    Mensaje_1

;**********************************************************************************
;
Inicio       
     
      MOVLW   HIGH Tabla_mensajes
      MOVWF   PCLATH

      clrf    PORTB      ;Borra los latch de salida
      bsf   STATUS,RP0   ;Selecciona banco 1
      clrf   TRISB      ;Puerta B se configura como salida
      movlw   b'00011000'     
      movwf   TRISA      ;RA0-RA2 salidas, RA3-RA4 entradas
      movlw   b'00000110'     
      movwf   ADCON1      ;Configuramos como salidas digitales     
      movlw   b'00000111'
      movwf   OPTION_REG   ;Preescaler de 256 para el TMR0
      bcf   STATUS,RP0   ;Selecciona banco 0   
     
      call   LCD_INI      ;Secuencia de inicio del LCD
      movlw   b'00001100'
      call   LCD_REG      ;Envía instrucción: LCD ON, Cursor OFF y blink OFF

Loop      movlw   b'00000001'
      call   LCD_REG      ;Borra LCD y Home (colocar cursor en 1ª posición)
      movlw   low Mens_0
      call   Mensaje      ;Visualiza el mensaje 0
      movlw   .20
      movwf   Delay_Cont
      call   Delay_var   ;Temporiza 2 segundos
      movlw   b'00000001'
      call   LCD_REG      ;Borra LCD y Home (colocar cursor en 1ª posición)
      movlw   low Mens_1
      call   Mensaje      ;Visualiza el mensaje 1
      movlw   .20
      movwf   Delay_Cont
      call   Delay_var   ;Temporiza 2 segundos
      goto   Loop

      END         ;Fin del programa fuente

 

Offline jcaser1948Topic starter

  • Contributor
  • Posts: 10
  • Country: es
Re: Microchip assembly language
« Reply #22 on: July 30, 2016, 12:19:06 pm »
Dear Alta
I have changed Tabla_mensajes as you suggested. I still get the  Error[151]
  C:\USERS\JCASE\MPLABXPROJECTS\LABORA_EJER_18_PIC16F870_ALTA.X\LABORA_EJER_18_PIC16F870.ASM 45 : Operand contains unresolvable labels or is too complex
The offending line is   MOVLW   LOW(Tabla_mensajes)+1  (at pos 45)
sorry for the bothering, but this error nags me. It should compile, but it does not, and de distinctionbetween lower and upper case does not seem to be the problem
Thanks
 

Offline StillTrying

  • Super Contributor
  • ***
  • Posts: 2850
  • Country: se
  • Country: Broken Britain
Re: Microchip assembly language
« Reply #23 on: July 30, 2016, 03:38:41 pm »
Here's 2 variations that should work.


Mensaje         movwf   Temporal_1      ;Salva posición de la tabla
        MOVLW   LOW(Tabla_mensajes + 1 )
        SUBWF   Temporal_1,F
Mensaje_1       movf    Temporal_1,W    ;Recupera posición de la tabla



Mensaje      movwf   Temporal_1      ;Salva posición de la tabla
            MOVLW   LOW(Tabla_mensajes)
        ADDLW  1
            SUBWF   Temporal_1,F
Mensaje_1    movf    Temporal_1,W    ;Recupera posición de la tabla

.  That took much longer than I thought it would.
 

Offline jcaser1948Topic starter

  • Contributor
  • Posts: 10
  • Country: es
Re: Microchip assembly language
« Reply #24 on: July 30, 2016, 04:11:27 pm »
This compiles (both solutions). Thank everyone for the help
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf