Yo tengo el mismo problema, no consigo hacer funcionar el LCD con un 18F452. Uso el CCS con las librerías del propio CCS, aunque he cambiado los puertos de salida al puerto D, en lugar del B.
Os agradecería un comentario al respecto, puesto que no sé por donde puede fallar el asunto.
El código también conecta con un teclado, aunque esta opción la tengo comentada, puesto que primero quiero hacer funcionar el LCD solo.
A continuación os pongo el código que uso:
[code]
#include <18F452.h>
#Fuses HS,NOPROTECT,NOBROWNOUT,NOWDT,PUT,NODEBUG,NOLVP
#use delay( clock=20000000 )
#include <math.h>
#include "Lcd.c"
// Keypad Layout
// 1 2 3 A
// 4 5 6 B
// 7 8 9 C
// * 0 # D
struct keypad_pin_map
{
int key: 4;
int row: 4;
} PortC;
#Byte PortC = 0xF82
#Byte PortD = 0xF83
#use fast_io( C )
#use fast_io( D )
struct Keypad_pin_map const WR = {0,0};
struct Keypad_pin_map const RD = {15,0};
//"1"=17, "2"=18, "3"=20, "A"=24
//"4"=33, "5"=34, "6"=36, "B"=40
//"7"=65, "8"=66, "9"=68, "C"=72
//"*"=129 "0"=130 "#"=132 "D"=136
byte ReadKeyPad()
{
byte i,k,l,Res;
Res = 0;
for (i=0; i<4; i++)
{
Set_Tris_C( WR );
PortC.Key = 0;
PortC.Row = exp(i*log(2));
delay_us(50);
Set_Tris_C( RD );
k = PortC.Key;
l = exp((4+i)*log(2));
if( k!= 0) { Res = k|l; }
}
return Res;
}
void main()
{
byte c;
lcd_init();
lcd_putc("f HOLA
" );
lcd_putc( " MUNDO " );
delay_ms(1000);
/*
while(1)
{
c = ReadKeyPad();
if (c != 0) printf(lcd_putc, "f%u", c );
}
*/
}
[code]
Además el código de "lcd.c" modificado para que funcione sobre el puerto D és el siguiente:
[code]
// As defined in the following structure the pin connection is as follows:
// D0 enable
// D1 rs
// D2 rw
// D4 D4
// D5 D5
// D6 D6
// D7 D7
//
// LCD pins D0-D3 are not used and PIC B3 is not used.
struct lcd_pin_map { // This structure is overlayed
boolean enable; // on to an I/O port to gain
boolean rs; // access to the LCD pins.
boolean rw; // The bits are allocated from
boolean unused; // low order up. ENABLE will
int data : 4; // be pin B0.
} lcd;
#byte lcd = 8 // This puts the entire structure
// on to port B (at address 6)
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40 // LCD RAM address for the second line
byte CONST LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
// These bytes need to be sent to the LCD
// to start it up.
// The following are used for setting
// the I/O port direction register.
STRUCT lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; // For write mode all pins are out
STRUCT lcd_pin_map const LCD_READ = {0,0,0,0,15}; // For read mode data pins are in
byte lcd_read_byte() {
byte low,high;
set_tris_d(LCD_READ);
lcd.rw = 1;
delay_cycles(1);
lcd.enable = 1;
delay_cycles(1);
high = lcd.data;
lcd.enable = 0;
delay_cycles(1);
lcd.enable = 1;
delay_us(1);
low = lcd.data;
lcd.enable = 0;
set_tris_d(LCD_WRITE);
return( (high<<4) | low);
}
void lcd_send_nibble( byte n ) {
lcd.data = n;
delay_cycles(1);
lcd.enable = 1;
delay_us(2);
lcd.enable = 0;
}
void lcd_send_byte( byte address, byte n ) {
lcd.rs = 0;
while ( bit_test(lcd_read_byte(),7) ) ;
lcd.rs = address;
delay_cycles(1);
lcd.rw = 0;
delay_cycles(1);
lcd.enable = 0;
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}
void lcd_init() {
byte i;
set_tris_d(LCD_WRITE);
lcd.rs = 0;
lcd.rw = 0;
lcd.enable = 0;
delay_ms(15);
for(i=1;i<=3;++i) {
lcd_send_nibble(3);
delay_ms(5);
}
lcd_send_nibble(2);
for(i=0;i<=3;++i)
lcd_send_byte(0,LCD_INIT_STRING);
}
void lcd_gotoxy( byte x, byte y) {
byte address;
if(y!=1)
address=lcd_line_two;
else
address=0;
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 "
" : lcd_gotoxy(1,2); break;
case "" : 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);
lcd.rs=1;
value = lcd_read_byte();
lcd.rs=0;
return(value);
}
[code]