Autor Tema: Para que sirven los ".h"???  (Leído 19038 veces)

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

Desconectado Marttyn

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1835
    • IDEAA
Re:Para que sirven los ".h"???
« Respuesta #15 en: 27 de Enero de 2017, 08:42:02 »
Muy sencillo:
Si quieres que la librería 1 vea la librería 2, añades en el header de la librería 1,  la librería 2.
Para eso sirve añadir headers.

Eso que comentas es muy util, incluido el IFNDEF, pero no quita que tengas que incluir un header extra para poder hacer los DEFINE correspondietes.
Si mi libreria necesita unos DEFINE, como por ejemplo el tipo de bateria para hacer los calculos. Y las constantes del tipo de bateria estan dentro de la misma libreria, entonces si inserto la libreria antes de los DEFINE la libreria me tira un error de que no estan definidos ciertos valores, y si la inserto despues de los DEFINE, el error me lo tira diciendo que esas constantes no existen.

Marttyn, creo que lo mejor en tu caso es utilizar macros para hacer los cálculos. Una macro es como una función y puedes pasarle el parámetro que quieras después de estar definida. Es más elegante y no cometes errores si cambias el orden de las líneas.

En principio no he encontrado utilidad para los macros, ya que quiero que todos estos calculos se hagan antes de compilar para liberar instrucciones en el PIC. Con macros entiendo que la funcion te queda creada y cuando le pasas los valores el PIC tendra que hacer los calculos.
Esta es una pequeña porcion de la libreria:

Código: C
  1. #ifndef BAT_ADC_CH
  2. #ERROR "Hay que declarar el canal del ADC que se usa para leer el voltaje"
  3. #endif
  4.  
  5. #ifndef BAT_PIC_VREF
  6. #ERROR "Hay que declarar el voltaje de referencia o el voltaje al que funciona el PIC"
  7. #endif
  8.  
  9. #ifndef BAT_R1
  10. #ERROR "Hay que declarar R1 del divisor de tension"
  11. #endif
  12.  
  13. #ifndef BAT_R2
  14. #ERROR "Hay que declarar R2 del divisor de tension"
  15. #endif
  16.  
  17. #define BAT_PROPORCION_IN_OUT   ((float)(BAT_R1 + BAT_R2) / BAT_R2)             // Vin / Vout
  18. #define BAT_PROPORCION_OUT_IN   ((float)BAT_R2 / (BAT_R1 + BAT_R2))             // Vout / Vin
  19. #define BAT_ADCxVOLT                    ((float)ADC_MAX_VAL / BAT_PIC_VREF)
  20. #define BAT_VOLTxADC                    ((float)BAT_PIC_VREF / ADC_MAX_VAL)
  21. #define BAT_VIN_MAX                             (BAT_PROPORCION_IN_OUT * BAT_PIC_VREF)
  22.  
  23. //Vin * (ADCMaxVal / Vref) * (R2 / (R1 + R2))
  24. #define ADC_BAT_BAJA    (long)(V_BAT_BAJA * BAT_ADCxVOLT * BAT_PROPORCION_OUT_IN)
  25. #define ADC_BAT_MEDIA   (long)(V_BAT_MEDIA * BAT_ADCxVOLT * BAT_PROPORCION_OUT_IN)
  26. #define ADC_BAT_ALTA    (long)(V_BAT_ALTA * BAT_ADCxVOLT * BAT_PROPORCION_OUT_IN)
  27.  
  28. #define RANGO_ADC_BAT   (ADC_BAT_MAX - ADC_BAT_MIN)

Tengo que decir que habiendo aprendido a usar Arduino, el CCS se me queda bastante pobre a la hora de desarrollar librerias. Arduino usa un lenguaje C mucho mas "estandar" que permite cosas muy interesantes. No hay mas que ver librerias de Adafruit para ver con que complejidad y "encapsulamiento" se pueden programar las librerias, para que luego tu codigo sea mucho mas limpio y legible.
La gente ve las cosas que existen y se pregunta por qué.
Yo prefiero imaginar lo que no existe y preguntarme por qué no.

Desconectado KILLERJC

  • Colaborador
  • DsPIC33
  • *****
  • Mensajes: 8242
Re:Para que sirven los ".h"???
« Respuesta #16 en: 27 de Enero de 2017, 12:47:08 »
Citar
Tengo que decir que habiendo aprendido a usar Arduino, el CCS se me queda bastante pobre a la hora de desarrollar librerias. Arduino usa un lenguaje C mucho mas "estandar" que permite cosas muy interesantes. No hay mas que ver librerias de Adafruit para ver con que complejidad y "encapsulamiento" se pueden programar las librerias, para que luego tu codigo sea mucho mas limpio y legible.

Concuerdo que CCS no es estandar para nada, y por eso es una de las cosas que aborrezco del mismo. Arduino usa C++ lo cual incorpora unas cuaaantas cosas mas. Aunque el fuerte de C++ es su STL, RTTI y manejo de memoria dinamica, pero que no creo que sean usados en la programacion de micros como arduino especialmente este ultimo, Creo que unicamente toman de C++ el tema de las clases con sus inheritance / cast de c++ / nullptr y tal ves algo mas que me olvide.

En C podes realizar lo mismo que haces con Arduino, si es que correctamente creas tu codigo para que no dependa de nada del hardware (incluso con CCS), luego creas otro archivo para el hardware, de esta forma si necesitas cambiar el micro o de fabricante el codigo anterior todavia sirve, porque es puro C. Algunos rebusques son crear headers internos ( solo para el archivo de la libreria ) y headers externos, como el para el port a cada micro que te guste y... interfaz de funciones para que sea usado desde otro archivo (los cuales no incluyen nada que no necesiten ej. struct/union/defines/etc) asi no se contamina el espacio de nombres de variables.
« Última modificación: 27 de Enero de 2017, 13:04:26 por KILLERJC »

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5883
    • Picuino
Re:Para que sirven los ".h"???
« Respuesta #17 en: 28 de Enero de 2017, 06:53:27 »
A lo que me refería es a que se pueden utilizar los define con macros:

Código: C
  1. #define BAT_PROPORCION_IN_OUT(R1, R2)   ((float)(R1 + R2) / R2)

Así puedes definir la macro sin que estén definidas R1 y R2. Luego utilizas la macro con dos valores cualquiera o con otras definiciones:


Código: C
  1. #include "cabecera.h"
  2.  
  3. int v = BAT_PROPORCION_IN_OUT(2200, 1000)
  4.  
  5. #define R1 2200
  6. #define R2 1000
  7.  
  8. int v = BAT_PROPORCION_IN_OUT(R1, R2)

Pero tu solución también vale.

Un saludo.
« Última modificación: 28 de Enero de 2017, 11:20:00 por Picuino, Razón: Corregir macro »

Desconectado Marttyn

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1835
    • IDEAA
Re:Para que sirven los ".h"???
« Respuesta #18 en: 30 de Enero de 2017, 15:42:39 »
Gracias Picuino!
Pero al hacer como dices tu, los macros se calculan antes de compilar? O utiliza memoria de programa para ello?
La gente ve las cosas que existen y se pregunta por qué.
Yo prefiero imaginar lo que no existe y preguntarme por qué no.

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5883
    • Picuino
Re:Para que sirven los ".h"???
« Respuesta #19 en: 30 de Enero de 2017, 17:07:54 »
Las macros se convierten en constantes antes de compilar. No ocupan memoria ni tiempo de ejecución.
Esa es la parte buena de las macros.
Un saludo.

Desconectado Marttyn

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1835
    • IDEAA
Re:Para que sirven los ".h"???
« Respuesta #20 en: 09 de Febrero de 2017, 12:44:39 »
Las macros se convierten en constantes antes de compilar. No ocupan memoria ni tiempo de ejecución.
Esa es la parte buena de las macros.
Un saludo.

No entiendo como... un macro utiliza "variables", por lo que no se puede calcular antes de compilar. A menos que sea un macro utilizado solo para constantes definidas.
La gente ve las cosas que existen y se pregunta por qué.
Yo prefiero imaginar lo que no existe y preguntarme por qué no.

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5883
    • Picuino
Re:Para que sirven los ".h"???
« Respuesta #21 en: 09 de Febrero de 2017, 13:15:10 »
Eso es. Sólo se utilizan constantes.

Desconectado colotron

  • PIC12
  • **
  • Mensajes: 73
    • Canal de YouTube
Re:Para que sirven los ".h"???
« Respuesta #22 en: 09 de Febrero de 2017, 14:07:21 »
Las macros se convierten en constantes antes de compilar. No ocupan memoria ni tiempo de ejecución.
Esa es la parte buena de las macros.
Un saludo.

No entiendo como... un macro utiliza "variables", por lo que no se puede calcular antes de compilar. A menos que sea un macro utilizado solo para constantes definidas.

No, no son variables, es texto, el preprocesador trabaja con texto.

#define UNA_MACRO_CON_ARGUMENTO(ARG) ((ARG)*5 - 12)

Hace de cuenta que cuando invocas
algunaVariable = UNA_MACRO_CON_ARGUMENTO(40);

El pre-procesador de C hace un buscar/reemplazar, busca primero UNA_MACRO_CON_ARGUMENTO, y donde decía ARG ahora reemplaza con 40
algunaVariable = ((40)*5 - 12);
El pre-procesador se ejecuta antes del compilador, hace esos reemplazos, y luego se llama al compilador.
Luego si yo la uso mal y escribo:
algunaVariable = UNA_MACRO_CON_ARGUMENTO("prrrffff");

el pre-procesador va a poner
algunaVariable = (("prrrffff")*5 - 12);
y el compilador no va a entender nada y quejarse en la línea de código anterior.

Pero si defino mal la macro, por ejemplo cometo un error de tipeo:
#define UNA_MACRO_CON_ARGUMENTO(ARG) ((ATG)*5 - 12)
algunaVariable = UNA_MACRO_CON_ARGUMENTO(40);

ahora se convierte en:
algunaVariable = ((ATG)*5 - 12);
el compilador se va a preguntar donde está ATG y va a marcar error en la línea de algunaVariable, y NO en la definición de la macro.
Muchas veces me pasó que uso alguna macro, el compilador informa de error en la línea tal (que claro, la línea es una llamada a una función que toma un argumento que se saca de una macro que a su vez llama a otra función que hace un typecasting...) y uno pierde horas buscando errores en funciones cuando el problema era una macro mal definida.

NO hay chequeo de error de macros, es decir, a nivel pre-procesador. Y por eso se dice que una macro es "parecida" a una función, pero no lo es porque como ya mencionaron no genera código, ni tampoco hay chequeo de errores.
Y es solo eso, un reemplazo textual (un buscar-reemplazar), que puede ser mucho más complicado con varias líneas y varias pasadas.

Con pasadas me refiero a:

#define ECUACION_RECTA(pendiente, offset, valor) (pendiente * valor + offset)
#define ADC_PENDIENTE(ref_mv, resolucionBits) (ref_mv/ (2^resolucionBits-1) )

#define CUENTAS_ADC_A_MV(valorADC) ECUACION_RECTA(ADC_PENDIENTE(2500,10), 0, valorADC)

Esta última línea "diría" que uso un conversor de 10 bits con una referencia de 2,5V (2500mV).

Entonces si escribo

variable = CUENTAS_ADC_A_MV(registroADC) ;

primero el preprocesador hace (pasada 1):
variable = ECUACION_RECTA(ADC_PENDIENTE(2500,10), 0, registroADC);
luego (pasada 2):
variable = ECUACION_RECTA((2500/ (2^10-1) ), 0, registroADC);

y por último (pasada 3):
variable = ( (2500/ (2^10-1) ) * registroADC + 0);

Bueno, seguro hay errores pero yo hago como el preprocesador y no chequeo nada :P
¿Pero creo que la idea se ve?

Desconectado Marttyn

  • Colaborador
  • PIC24H
  • *****
  • Mensajes: 1835
    • IDEAA
Re:Para que sirven los ".h"???
« Respuesta #23 en: 09 de Febrero de 2017, 14:58:06 »
Pero con macros no puedes usar variables como argumento?
Algo asi:

#define UNA_MACRO_CON_ARGUMENTO(ARG) ((ARG)*5 - 12)
int x;

for(x = 0; x<10; x++){
   algunaVariable = UNA_MACRO_CON_ARGUMENTO(x);
}

Como hace el preprocesador con esto?
La gente ve las cosas que existen y se pregunta por qué.
Yo prefiero imaginar lo que no existe y preguntarme por qué no.

Desconectado colotron

  • PIC12
  • **
  • Mensajes: 73
    • Canal de YouTube
Re:Para que sirven los ".h"???
« Respuesta #24 en: 09 de Febrero de 2017, 15:58:54 »
Pero con macros no puedes usar variables como argumento?
Algo asi:

#define UNA_MACRO_CON_ARGUMENTO(ARG) ((ARG)*5 - 12)
int x;

for(x = 0; x<10; x++){
   algunaVariable = UNA_MACRO_CON_ARGUMENTO(x);
}

Como hace el preprocesador con esto?

Bueno, para el preprocesador tanto x como el valor 40 es solo texto, que reemplazará si hay algun #define que así lo indique:

int x;
for(x = 0; x<10; x++){
   algunaVariable = UNA_MACRO_CON_ARGUMENTO(x);
}

Al inspeccionar ese código va a encontrarse con que UNA_MACRO_CON_ARGUMENTO es una macro, luego en donde aparezca su nombre reemplazará su nombre por la definición especificada en el #define, resultando:

for(x = 0; x<10; x++){
   algunaVariable = ((x)*5 - 12);
}

Para el pre-procesador el código fuente que escribimos es un montón de texto, no distingue variables, constantes, funciones... todo texto. Lo que sí entiende es que se pueden definir reglas de edición con #define, y la directivas #if, #else y todo lo que empiece con #; que justamente son las instrucciones para el pre-procesador que realice los reemplazos (#define), incrustaciones (#include), e inclusión condicional que les indiquemos (#if, #ifdef).


 

anything