Manejar libreria lcd.h con cualquier pin de cualquier puerto

Como va? Siempre posteando dudas o preguntas, esta vez es una solución. Veo que cada dos por tres se hacen posts preguntando como cambiar los pines del puerto para controlar un display clásico como lo es el de 16x2 con el controlador HD44780. La solución es bastante bastante sencilla. De esta manera podemos utilizar CUALQUIER PIN DISPONIBLE DEL MICRO PARA CUALQUIER PIN DEL DISPLAY LCD. No es necesario que sean correlativos, o todos del mismo puerto, etc.

Básicamente, el concepto es declarar primero las etiquetas de los pines con los #define correspondientes Y, EN LAS LINEAS SIGUIENTES, INCLUIR LA LIBRERÍA LCD.H

¿Por que esto? Todas las directivas con un # delante se llaman "directivas de pre-procesador". ¿Que significa? Que el compilador las procesa antes de realizar el proceso de compilación. Por ejemplo, cuando detecta una instrucción del tipo #include reemplaza en el código el contenido completo de ese archivo que estamos incluyendo y luego compila el programa.

¿Por que ponemos #include <16f628a.h> al principio y no al final? Por el mismo motivo que primero definimos las variables y luego las usamos. ¿Podríamos primero usarlas y luego definirlas? No, porque el compilador no va a saber a que nos estamos refiriendo. Como el proceso de compilación se hace linea a linea y a la hora de compilar una linea se tiene en cuenta lo que se compilo anteriormente, primero definimos todas las instrucciones para el microcontrolador y luego las usamos en el programa.

Lo mismo ocurre con la librería del LCD. Primero definimos las etiquetas de los pines que queremos usar (notese que yo use cualquier pin y no son correlativos para nada) y luego incluimos la librería. De esta manera lo que hacemos es decirle al compilador: "cuando te encuentres escrita la palabra LCD_ENABLE_PIN es que me estoy refiriendo al pin 5 del Puerto B" y una vez que definimos todas las etiquetas incluimos la librería, entonces cuando el compilador encuentre la directiva de inclusión de la librería del lcd y reemplace el contenido en el programa ya va a saber a que nos referimos cuando escribimos LCD_ENABLE_PIN.

Código:
#include <16f628a.h>

#FUSES NOWDT              	   	//No Watch Dog Timer
#FUSES PUT                   		//Power Up Timer
#FUSES INTRC                	 	//Internal RC Osc
#FUSES MCLR                		//Master Clear pin used for I/O
#FUSES NOBROWNOUT               	//No brownout reset
#FUSES NOLVP               	  	//No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES PROTECT                          //Code protected from reads

#use delay(int=4000000)

#define LCD_ENABLE_PIN	 	PIN_B5                                    
#define LCD_RS_PIN              PIN_B4                                    
#define LCD_RW_PIN	       	PIN_B2                                    
#define LCD_DATA4            	PIN_A6                                    
#define LCD_DATA5      		PIN_A7                                    
#define LCD_DATA6   	   	PIN_A0                                    
#define LCD_DATA7           	PIN_A1

#include <lcd.c>

void main()
{
lcd_init();
printf(lcd_putc,"Hola Mundo");
}

Saludos!!!
 
Última edición:
Buen aporte, da pie para resaltar que #define no solo sirve para definir piner, sino funciones. Ejemplo sencillo:

Código:
#include <16F877A.h>
#device adc=8

#FUSES NOWDT                 	//No Watch Dog Timer
#FUSES HS                    	//High speed Osc (> 4mhz for PCM/PCH) (>10mhz for PCD)
#FUSES NOPUT                 	//No Power Up Timer
#FUSES NOPROTECT             	//Code not protected from reading
#FUSES NODEBUG               	//No Debug mode for ICD
#FUSES NOBROWNOUT            	//No brownout reset
#FUSES NOLVP                 	//No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#FUSES NOCPD                 	//No EE protection
#FUSES NOWRT                 	//Program memory not write protected
#FUSES RESERVED              	//Used to set the reserved FUSE bits

#use delay(clock=20000000)

#byte portb=6
#define suma(x,y) x+y

void main()
{

   setup_adc_ports(NO_ANALOGS);
   setup_adc(ADC_CLOCK_DIV_2);
   setup_psp(PSP_DISABLED);
   setup_spi(SPI_SS_DISABLED);
   setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
   setup_timer_1(T1_DISABLED);
   setup_timer_2(T2_DISABLED,0,1);
   setup_comparator(NC_NC_NC_NC);
   setup_vref(FALSE);
   set_tris_b(0);
   portb=0;
   int x = 100;
   int y = 120;

   while(true){
      portb = suma(x,y);
   }

}
La sentencia #define suma(x,y) x+y nos permite reemplazar la suma 'x+y' escribiendo suma(x,y). El ejemplo puede ser algo obsoleto pero es para dar una idea de lo que los #define permiten hacer.
 
No son funciones sino macro-sustituciones. Cada vez que pones suma(x,y) hecha con un #define el compilador copia el codigo que esta al lado, pero no invoca nada, asi que toda la teoria de funciones no vale para estas cosas (paso de parametros por valor, variables locales, devolucion de resultados, etc).
 
Atrás
Arriba