hola que tal picmaniacos os pongo la libreria modificada de J1M para poder usar el PIC18F2450 por medio del puertoA (RA1,RA2,RA3) y el puertoB (RB0-RB3)
Kiero ver si encontrais algun fallo pq en la pcb no me termina de funcionar.
//----------------------------------------------------------------------------//
// Define for LCD
#include <string.h>
#define STRDSPLMAX 16 //Display 16 charactor / Line
static u08 buffer_display[STRDSPLMAX+1];
///////////////////////////////////////////////////////////////////////////
//// LCDD.C ////
//// Driver for common LCD modules ////
//// ////
//// lcd_init() Must be called before any other function. ////
//// ////
//// lcd_putc(c) Will display c on the next position of the LCD. ////
//// The following have special meaning: ////
//// \f Clear display ////
//// \n Go to start of second line ////
//// \b Move back one position ////
//// ////
//// lcd_gotoxy(x,y) Set write position on LCD (upper left is 1,1) ////
//// ////
//// lcd_getc(x,y) Returns character at position x,y on LCD ////
//// ////
///////////////////////////////////////////////////////////////////////////
//Conexión a 7 pines del MCU: 3 de control / interface de datos de 4 bits:
// Líneas de control asignadas
// RA1 rs
// RA2 rw
// RA3 enable
// Líneas de Datos
// RB0 D4
// RB1 D5
// RB2 D6
// RB3 D7
////////////////////////////////////////////////////////////////////////
struct lcd_pines_control
{ // Estructura que se define para facilitar acceso
boolean nada;
boolean rs; //y asociarlos a los bits(RA1,RA2,RA3) del PORTA
boolean rw; //se asigna luego a esta estructura el PORTA
boolean enable;
int otros : 4;
} lcd_control;
struct lcd_pines_datos
{ // Se hace lo mismo con esta estructura para el PORTB
int datos:4; //los 4 bits más bajos son los de datos
int no_usados:4;
} lcd_datos;
#byte lcd_control = 5 //Se pone la estructura entera en el PORTA
#byte trisa = 0x85 //Registro de dirección de datos
#byte lcd_datos = 6 //Lo mismo para los datos, en el PORTB
#byte trisb = 0x86 //Registro de dirección de datos
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40 // LCD RAM address for the second line
#define LINE1 1
#define LINE2 2
#define DSPL_LEFT 0
#define DSPL_RIGHT 1
#define DSPL_CENTER 2
BYTE lcd_read_byte() {
BYTE low,high;
trisa&=0b11110001;//Señales de control (salidas), el resto lo que sean
trisb|=0b00001111;//Las de datos pasan a ser entradas, las demás igual
lcd_control.rw = 1;
delay_cycles(1);
lcd_control.enable = 1;
delay_cycles(1);
high = lcd_datos.datos;
lcd_control.enable = 0;
delay_cycles(1);
lcd_control.enable = 1;
delay_us(1);
low = lcd_datos.datos;
lcd_control.enable = 0;
trisb&=0b11110000; // Dejamos RB0 a RB3 como salidas
return( (high<<4) | low);
}
void lcd_send_nibble( BYTE n ) {
lcd_datos.datos = n;
delay_cycles(1);
lcd_control.enable = 1;
delay_us(2);
lcd_control.enable = 0;
}
void lcd_send_byte( BYTE address, BYTE n ) {
lcd_control.rs = 0;
while (bit_test(lcd_read_byte(),7) ) ;
lcd_control.rs = address;
delay_cycles(1);
lcd_control.rw = 0;
delay_cycles(1);
lcd_control.enable = 0;
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0x0f);
}
void lcd_init() {
BYTE i;
trisa&=0b11110001; //Se asigna salidas en RA1, RA2 y RA3, resto puerto
//como estaba
trisb&=0b11110000; // Lo mismo para RB0 a RB3
lcd_control.rs = 0;
lcd_control.rw = 0;
lcd_control.enable = 0;
delay_ms(15);
for(i=1;i<=3;++i) {
lcd_send_nibble(3);
delay_ms(5);
}
lcd_send_nibble(2);
lcd_send_byte(0,0b00101000);//Se envía Function set 0 0 1 DL N F -
lcd_send_byte(0,0b00001100);//Se envía Display on/off 0 0 0 0 1 D C B
lcd_send_byte(0,0b00000001);//Se envía Clear Display
lcd_send_byte(0,0b00000110);//Se envía Entry Modeset 0 0 0 0 0 1 I/D S
////////////////////////////////////////////////////////////////////////
//DL: datos 4 bits(0); 8 bits (1)
//N: 2 líneas (1); 1 línea (0)
//F: 5x10 (1); 5x8 (0)
//D: display on (1); off (0)
//C: cursor on (1); off (0)
//B: parpadeo pos.cursor (1); no (0)
//I/D: incremento en R/W (1) o decremento (0)
//S: acompaña desplaz.display (1); no (0)
////////////////////////////////////////////////////////////////////////
}
void lcd_gotoxy( BYTE x, BYTE y)
{
BYTE address = 0;
if (y == LINE2)
address= lcd_line_two;
address += x-1;
lcd_send_byte(0, 0x80|address);
}
void lcd_putc( char c) {
switch (c)
{
case '\f' : lcd_send_byte(0,1);
delay_ms(2);
break;
case '\n' : lcd_gotoxy(1,2); break;
case '\b' : lcd_send_byte(0,0x10); break;
default : lcd_send_byte(1,c); break;
}
}
char lcd_getc( BYTE x, BYTE y)
{
char value;
lcd_gotoxy(x,y);
while ( bit_test(lcd_read_byte(),7) ); // wait until busy flag is low
lcd_control.rs=1;
value = lcd_read_byte();
lcd_control.rs=0;
return(value);
}
//----------------------------------------------------------------------------//
void lcd_string (int Line, char *string,int delay)
{
int i;
lcd_gotoxy (0,Line);
//while (*string != 0)
for (i = 0; i < STRDSPLMAX; i++)
{
lcd_putc (*string++);
delay_ms (delay);
}
}
//----------------------------------------------------------------------------//
void dspl_line (u08 *cStr, u08 nAlign, u08 nLine)
{
u08 cLine[STRDSPLMAX+1];
u08 len; //x
len = strlen (cStr);
if (len > STRDSPLMAX)
len = 16;
memset (cLine, 0x20, STRDSPLMAX);
switch (nAlign)
{
//OK
case DSPL_LEFT : memcpy (cLine, cStr, len);
break;
// OK
case DSPL_CENTER: memcpy (cLine+((STRDSPLMAX - len)/2), cStr, len);
break;
// OK
case DSPL_RIGHT: memcpy (cLine+ (STRDSPLMAX - len), cStr, len);
break;
default :
break;
}
lcd_string (nLine, cLine, 5);
}