Autor Tema: ¿Diferencia entre #define y const en CCS C?  (Leído 13360 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
¿Diferencia entre #define y const en CCS C?
« en: 10 de Febrero de 2010, 18:42:38 »
¿Sabe alguno de ustedes que diferencia práctica hay entre estas dos formas de utilizar un mismo valor constante?

Código: C#
  1. #define nTimer1_for_head_read_complete 50
  2. const int8 nTimer1_for_head_read_complete=50;

Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: ¿Diferencia entre #define y const en CCS C?
« Respuesta #1 en: 10 de Febrero de 2010, 19:13:14 »
Hola Diego

Si usas #define el preprocesador (compilación) convertirá todo lo que pongas ahí en una constante ROM que nunca ocupará espacio en la memoria RAM. Es como si pusieras movlw variable.

Si usas const el compilador optará por depositar la variable en rom de programa como de sólo lectura o depositará la variable en ram... cualquiera de las dos opciones dependiendo de dónde convenga más para optimizar el programa.

Para extraer el valor de tal variable const se usaría un retlw.

Aquí lo que dicen los amigos de CCS al respecto...

Citar
const
 Data is read-only.  Depending on compiler configuration, this qualifier may just make the data read-only -AND/OR- it may place the data into program memory to save space.

Desconectado Modulay

  • Moderadores
  • DsPIC30
  • *****
  • Mensajes: 2651
Re: ¿Diferencia entre #define y const en CCS C?
« Respuesta #2 en: 10 de Febrero de 2010, 19:43:59 »
Pues no sabía que #define llegaba a ocupar memoria física...pensaba que no salía de la compilación, como mera herramienta del lenguaje

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: ¿Diferencia entre #define y const en CCS C?
« Respuesta #3 en: 10 de Febrero de 2010, 20:00:00 »
El define es un macro y es puramente del compilador, no guarda ninguna dato en la rom  :?

Por ejemplos si se hace:

Código: C
  1. #define Temp 37

Y se ejecuta la igualdad:
Código: C
  1. Var=Temp;
En asm haría:
Código: ASM
  1. movlw   d'37'
  2.      movwf   Var

Reemplaza el texto Temp por el valor definido.


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado Cryn

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4169
Re: ¿Diferencia entre #define y const en CCS C?
« Respuesta #4 en: 10 de Febrero de 2010, 21:44:42 »
además que al hacer defines no solo se puede hacer con numeros, también con stings o comandos...

#define output_high on

y después hacer:

on(pin_a1);

y bueno una serie de ellas, así que por ello me parece que es más un tema del compilador, el se encarga de hacer el trabajo sucio y reemplazar las definiciones en donde se debe y como se debe.

En cambio un const es solo para los tipos de datos que soporta el compilador y seguro que estarán en ROM

saludos.
.

Desconectado jeremylf

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1341
Re: ¿Diferencia entre #define y const en CCS C?
« Respuesta #5 en: 10 de Febrero de 2010, 22:16:12 »
Y que conviene usar y cuando?

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: ¿Diferencia entre #define y const en CCS C?
« Respuesta #6 en: 10 de Febrero de 2010, 22:40:00 »
El define es un macro y es puramente del compilador, no guarda ninguna dato en la rom  :?


Claro, es puramente del compilador, pero enfocándose en el ejemplo de Diego con variables sí ocupa rom de programa (como tu ejemplo Suky). En otros ejemplos como los de Cryn pues no se ocupa rom.

¿Qué es mejor, define o const?

Usando CONST... habría que evaluarlos desde el punto de vista ASM. En un PIC16 leer un dato desde memoria de programa implica usar CALL y RETLW y en un PIC18 implica usar instrucciones de lectura de tabla. Algún conocedor de ASM PIC18 podría decirnos cuál es más rápido.

Pero usando DEFINE la carga del dato es inmediata usando MOVLW... aunque consume más ROM de programa si se llama en varios lugares.

Desconectado Cryn

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4169
Re: ¿Diferencia entre #define y const en CCS C?
« Respuesta #7 en: 10 de Febrero de 2010, 23:16:06 »
Hice un pequeña prueba y ni const ni define producen este código asm

Código: C
  1. .................... #include <16f88.h>
  2. .................... //////// Standard Header file for the PIC16F88 device ////////////////
  3. .................... #device PIC16F88
  4. .................... #list
  5. ....................  
  6. .................... #fuses INTRC_IO,NOWDT,PUT
  7. .................... #use fast_io(a)
  8. ....................  
  9. .................... #define temp 0x20
  10. .................... #define on output_high  
  11. ....................  
  12. .................... const int temp2=0x25;
  13. .................... int var,var2;
  14. ....................  
  15. .................... void main(void){
  16. 0004:  CLRF   04
  17. 0005:  BCF    03.7
  18. 0006:  MOVLW  1F
  19. 0007:  ANDWF  03,F
  20. 0008:  BSF    03.5
  21. 0009:  BCF    1F.4
  22. 000A:  BCF    1F.5
  23. 000B:  MOVF   1B,W
  24. 000C:  ANDLW  80
  25. 000D:  MOVWF  1B
  26. 000E:  MOVLW  07
  27. 000F:  MOVWF  1C
  28. ....................    var=temp;
  29. 0010:  MOVLW  20
  30. 0011:  BCF    03.5
  31. 0012:  MOVWF  20
  32. ....................    var2=temp2;
  33. 0013:  MOVLW  25
  34. 0014:  MOVWF  21
  35. ....................    on(pin_a0);
  36. 0015:  BSF    05.0
  37. ....................    output_high(pin_a1);
  38. 0016:  BSF    05.1
  39. .................... }
  40. ....................  
  41. 0017:  SLEEP

entonces parece que básicamente son lo mismo, al menos en mi versión 4.104 de CCS

0011:  BCF    03.5 es irrelevante ya que solo es para seleccionar banco, si se cambia el orden de asignaciones a var y var2 el BCF se mantiene en esa posición.

Raro no? yo pienso que el compilador debería tratar de manera diferente a los const... o que dicen??

saludos.
.

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: ¿Diferencia entre #define y const en CCS C?
« Respuesta #8 en: 10 de Febrero de 2010, 23:48:52 »
#define usa movlw como lo habíamos comentado y const sólo usará salto a tablas cuando son muchos datos.

La optimización de CCS realmente es buena.

Usando un arreglo de constantes CCS sí genera la tabla en ROM...

Código: [Seleccionar]
#include "16f84a.h"
const int8 temp[] = {0xA0, 3,5,6,7,8,1,1,1};


void main()
{
int8 prueba[9];
int8 i;

for(i=0; i<9; ++i)
   {
   prueba=temp[i];
   }
}

Esto es lo que genera:

Código: [Seleccionar]
0000:  MOVLW  00
0001:  MOVWF  0A
0002:  GOTO   011
0003:  NOP
.................... #include "16f84a.h"
.................... //////// Standard Header file for the PIC16F84A device ////////////////
.................... #device PIC16F84A
.................... #list
.................... 
.................... const int8 temp[] = {0xA0, 3,5,6,7,8,1,1,1};
.................... 
.................... 
.................... void main()
.................... {
0011:  CLRF   04
0012:  MOVLW  1F
0013:  ANDWF  03,F
.................... int8 prueba[9];
.................... int8 i;
.................... 
.................... for(i=0; i<9; ++i)
0014:  CLRF   1B
0015:  MOVF   1B,W
0016:  SUBLW  08
0017:  BTFSS  03.0
0018:  GOTO   01F
....................    {
....................    prueba=temp[i];
0019:  MOVF   1B,W
001A:  CALL   004
001B:  MOVWF  0D
001C:  MOVWF  12
....................    }
001D:  INCF   1B,F
001E:  GOTO   015
.................... }
001F:  SLEEP

La instrucción CALL 004 brinca a una subrutina con RETLW pero el volcado ASM LST no lo muestra. Winpic800 lo muestra así...

Código: [Seleccionar]
  0x0000 : 0x3000   movlw   0x00
  0x0001 : 0x008A   movwf   0x0A
  0x0002 : 0x2811   goto    0x11
  0x0003 : 0x0000   nop   
  0x0004 : 0x100A   bcf     0x0A , 0
  0x0005 : 0x108A   bcf     0x0A , 1
  0x0006 : 0x110A   bcf     0x0A , 2
  0x0007 : 0x0782   addwf   0x02 , F
  0x0008 : 0x34A0   retlw   0xA0        ;  .
  0x0009 : 0x3403   retlw   0x03        ;  .
  0x000A : 0x3405   retlw   0x05        ;  .
  0x000B : 0x3406   retlw   0x06        ;  .
  0x000C : 0x3407   retlw   0x07        ;  .
  0x000D : 0x3408   retlw   0x08        ;  .
  0x000E : 0x3401   retlw   0x01        ;  .
  0x000F : 0x3401   retlw   0x01        ;  .
  0x0010 : 0x3401   retlw   0x01        ;  .
  0x0011 : 0x0184   clrf    0x04
  0x0012 : 0x301F   movlw   0x1F
  0x0013 : 0x0583   andwf   0x03 , F
  0x0014 : 0x019B   clrf    0x1B
  0x0015 : 0x081B   movf    0x1B , W
  0x0016 : 0x3C08   sublw   0x08
  0x0017 : 0x1C03   btfss   0x03 , 0
  0x0018 : 0x281F   goto    0x1F
  0x0019 : 0x081B   movf    0x1B , W
  0x001A : 0x2004   call    0x04
  0x001B : 0x008D   movwf   0x0D
  0x001C : 0x0092   movwf   0x12
  0x001D : 0x0A9B   incf    0x1B , F
  0x001E : 0x2815   goto    0x15
  0x001F : 0x0063   sleep 

Desconectado RICHI777

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1498
Re: ¿Diferencia entre #define y const en CCS C?
« Respuesta #9 en: 11 de Febrero de 2010, 10:47:48 »
Hola,
Citar
El define es un macro y es puramente del compilador, no guarda ninguna dato en la rom 
 movlw   d'37'     movwf   Var
Reemplaza el texto Temp por el valor definido.

Si nos refereimos a "guardar" el 37 se esta guardando como parte de nuestro programa. Creo que las diferencias son conceptuales, los defines como bien se dijo son reemplazadas por el preprocesador que todos sabemos no es muy inteligente, por eso hay que tener cuidado cuando se establecen operaciones con defines involucrados por el tema de signos y alcance, por el eso el ANSI define los sufijos "U" "L" "UL" que instruyen al preprocesador a tratar la constante como unsgined, long y unsigned long.

Saludos !

Desconectado PalitroqueZ

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5474
    • Electrónica Didacta
Re: ¿Diferencia entre #define y const en CCS C?
« Respuesta #10 en: 11 de Febrero de 2010, 22:19:03 »
yo creo que dependiendo del uso que se le vaya a dar cada uno se diferenciará de otro, pero asi como pone Diego el ejemplo, no tiene ninguna diferencia.

#define es una etiqueta que se asocia a un dato
y const (para este ejemplo) también.

si no se llama a la etiqueta en el código principal, por supuesto el compilador no lo tomará en cuenta al compilar.





La propiedad privada es la mayor garantía de libertad.
Friedrich August von Hayek

Desconectado RedPic

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 5544
    • Picmania by Redraven
Re: ¿Diferencia entre #define y const en CCS C?
« Respuesta #11 en: 12 de Febrero de 2010, 06:14:38 »
Siguiendo las pruebas que ya habéis comenzado de escribir el C y ver qué genera en ASM hay que tener en cuenta lo que dice migsantiago sobre la optimización ...

Si hacemos ...

Código: C#
  1. #define    nTimer1_for_head_read_complete 255
  2. const int8 nTimer2_for_head_read_complete=255;
  3.  
  4. void main(){
  5.  
  6.    int8 MyInt;
  7.  
  8.    MyInt=nTimer1_for_head_read_complete;
  9.    MyInt=nTimer2_for_head_read_complete;
  10.  
  11. }

Obtenemos ...

Código: ASM
  1. ....................    MyInt=nTimer1_for_head_read_complete;
  2. 0018:  MOVLW  FF
  3. 001A:  MOVWF  06
  4. ....................    MyInt=nTimer2_for_head_read_complete;
  5. 001C:  MOVWF  06

Si ahora cambiamos nTimer1_for_head_read_complete por nTimer2_for_head_read_complete ...

Código: C#
  1. void main(){
  2.  
  3.    int8 MyInt;
  4.  
  5.    MyInt=nTimer2_for_head_read_complete;
  6.    MyInt=nTimer1_for_head_read_complete;
  7.  
  8. }

obtenemos ...

Código: ASM
  1. ....................    MyInt=nTimer2_for_head_read_complete;
  2. 0018:  MOVLW  FF
  3. 001A:  MOVWF  06
  4. ....................    MyInt=nTimer1_for_head_read_complete;
  5. 001C:  MOVWF  06

La situación es absolutamente la misma pero con las variables intercambiadas, lo cual es lógico por la optimización del CCS C: Carga W con 0xFF y lo guarda en MyInt, como W sigue conteniendo 0xFF lo vuelve a guardar en MyInt ...

Si entre ambas inicializo MyInt a cero el cabrón del CCS Optimizado sabe muy bien lo que se hace ...

Código: C#
  1. void main(){
  2.  
  3.    int8 MyInt;
  4.  
  5.    MyInt=nTimer1_for_head_read_complete;
  6.    MyInt=0;
  7.    MyInt=nTimer2_for_head_read_complete;
  8.  
  9. }

Código: ASM
  1. ....................    MyInt=nTimer1_for_head_read_complete;
  2. 0018:  MOVLW  FF
  3. 001A:  MOVWF  06
  4. ....................    MyInt=0;
  5. 001C:  CLRF   06
  6. ....................    MyInt=nTimer2_for_head_read_complete;
  7. 001E:  MOVWF  06

Como hemos puesto a cero una dirección de memoria con el CLRF entonces W no ha cambiado por lo que seguimos en las mismas.

La prueba definitiva esta en cargar entre ambas un valor que sea distinto a cero y al del #define/const ...

Código: C#
  1. void main(){
  2.  
  3.    int8 MyInt;
  4.  
  5.    MyInt=nTimer1_for_head_read_complete;
  6.    MyInt=127;
  7.    MyInt=nTimer2_for_head_read_complete;
  8.  
  9. }

Código: ASM
  1. ....................    MyInt=nTimer1_for_head_read_complete;
  2. 0018:  MOVLW  FF
  3. 001A:  MOVWF  06
  4. ....................    MyInt=127;
  5. 001C:  MOVLW  7F
  6. 001E:  MOVWF  06
  7. ....................    MyInt=nTimer2_for_head_read_complete;
  8. 0020:  MOVLW  FF
  9. 0022:  MOVWF  06

Y ahora si, ya podemos ver claramente que el #define y el const int8 generan exactamente el mismo código. Teníais razón (los que la teníais) ja, ja, ja  :D :D :D
Contra la estupidez los propios dioses luchan en vano. Schiller
Mi Güeb : Picmania

Desconectado Suky

  • Moderador Local
  • DsPIC33
  • *****
  • Mensajes: 6758
Re: ¿Diferencia entre #define y const en CCS C?
« Respuesta #12 en: 12 de Febrero de 2010, 08:37:43 »
El define es un macro y es puramente del compilador, no guarda ninguna dato en la rom  :?


Claro, es puramente del compilador, pero enfocándose en el ejemplo de Diego con variables sí ocupa rom de programa (como tu ejemplo Suky). En otros ejemplos como los de Cryn pues no se ocupa rom.

mmm... Entiendo! Pero hay que aclarar que son iguales solo para el ejemplo puntual que presenta Diego, para no confundir  ;-) Porque son conceptos distintos.


Saludos!
No contesto mensajes privados, las consultas en el foro

Desconectado migsantiago

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8257
    • Sitio de MigSantiago
Re: ¿Diferencia entre #define y const en CCS C?
« Respuesta #13 en: 12 de Febrero de 2010, 11:29:19 »
mmm... Entiendo! Pero hay que aclarar que son iguales solo para el ejemplo puntual que presenta Diego, para no confundir  ;-) Porque son conceptos distintos.


Saludos!

De acuerdo.

Desconectado Cryn

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 4169
Re: ¿Diferencia entre #define y const en CCS C?
« Respuesta #14 en: 12 de Febrero de 2010, 12:25:49 »
también de acuerdo
.