Es buena practica poner ambos... voy a hacerte una comparacion con ASM
En ASM podias tener un archivo libreria y luego hacias:
#include "lcd.inc"
;Codigo de tu archivo principal
Luego que pasa el compilador, este es el resultado:
;Codigo del LCD
;Codigo de tu archivo principal
Como si fuera un solo archivo para todo.
Hay otras formas de realizarlo en ASM. Y es no incluirlo al archivo, en el cual los 2 archivos estan separados sin nigun include, donde declaras tus subrutinas y variables como "globales", asi mismo para usarlas en tu archivo principal necesitas decirle que existe alguna subrutina y variable con ese nombre "externo" a tu archivo. Ahora el compilador va a tener 2 archivos separados, y el linker va a ser quien una ambos archivos. Es decir va a ver el archivo principal.s y va a notar que existe un simbolo (nombre de la variable) que no es de ese archivo y esta en otro, entonces mientras pasa por archivo y archivo encuentra donde se encuentra definido y lo "enlaza" los une.
No recuerdo bien como era hacerlo pero suponete que era asi:
archivo1.sglobal sumar
global restar
sumar:
;Aca codigo ASM
return
restar:
;Aca codigo ASM
return
main.s;Omito los vectore e incializacion, pero antes poner:
extern sumar
extern restar
;El codigo
CALL sumar
-------------------------------------------------------------------------------------
En C ocurre lo mismo.. Podes hacer las 2 formas. Sin un .h podes hacer:
#include "lcd.c"
// Aca codigo del main.c
Obviamente esto es como poner ambos codigos en todo un archivo. Nomas que lo tenemos separado en 2.. Esto puede ser un problema y tambien es considerado una mala practica en C.
La otra forma es ofrecer con el .h una "interfaz" hacia el .c. Y ahora voy a ser un poco mas especifico con los ejemplos.
Suponete que tenemos estos archivos:
operaciones.cchar sumar(char a, char b)
{
return (a+b);
}
char restar(char a, char b)
{
return (a-b);
}
main.c#include <xc.h>
void main(void)
{
char x;
x = suma(1,2);
x = resta(10,2);
while(1)
{
//Nuestro loop infinito
}
}
Como dije tengo 2 formas de hacerlo pero vamos por la segunda que es la que nos interesa.
El linker no tiene idea que existe las funciones suma y resta en otro archivo, la esta usando pero no saben de donde vienen, y si tratas de compilar los 2 archivos asi nomas vas a tener un error que dice que suma y resta se declararon implicitamente. Tambien a veces si usamos suma y resta en el archivo operaciones.c necesitamos declararlas en ese archivo. Entonces creamos un .h
operaciones.h// Esto es una guarda, para que no se incluya muchas veces en un archivo .c , sino que al incluirse una ves
// ya se define _OPERACIONES_H entonces para la proxima no va a entrar. Solo entra si no esta definido.
#ifndef _OPERACIONES_H
#define _OPERACIONES_H
char sumar(char a, char b);
char restar(char a, char b);
#endif
Para no entrar en tanto detalles voy a resumir la explicacion como vine haciendo hasta ahora, a ese archivo lo incluis en operaciones.c (donde tenes definida las funciones) y en main.c (donde queres usarlas). Y con eso le decis al linker que se encuentra en otro archivo. Es decir al momento de unir los archivos, va a mirar el main.c y va a pensar: "Tengo estas dos funciones en otro archivo" Entonces las va a ir a buscar a otro.c
Como te dije no quiero entrar en detalles sobre porque es que se comparten, ni el alcance de los simbolos, ni otras formas de hacerlo (como usar extern y no incluir un .h), sino darte una explicación simple y entendible de porque necesitarias un .h. Luego avanzaras sobre otros temas, por ahora con lo minimo pienso que te sobraria.
----------------------------------------------------------------------
Hay una cosa que debo aclarar, si observas en nuestro .h no hay nada que ocupe lugar en el micro, Las funciones estan definidas en el .c, las variables deberian estar definidas en los .c, en el .h
deberías poner: prototipos de funciones (como el ejemplo, el cual no tienen codigo), la definicion de una estructura/union, etc. Como nombre antes, si lo que pusiste crea una variable que ocupa espacio tanto en RAM como en ROM eso NO va sobre el .h (omitiendo las macros que eso lo vas a ver mucho mas adelante)