Kiero hacer una rutina de CCS para LCD que use un PIC18F452, y que tenga el siguiente
pin_map:
----------------------- CONTROL_PIN_MAP---------------------------------------
RS --> RE0
RW --> RE1
E --> RC5
---------------------- DATA_PIN_MAP--------------------------------------------
DB0 --> RB0
DB1 --> RB1
DB2 --> RB2
DB3 --> RB3
DB4 --> RB4
DB5 --> RB5
DB6 --> RB6
DB7 --> RB7
Y tras modificar la rutina para LCD"s que trae el CCS, sigo sin conseguir hacer que
me funcione, no se en que falla mi codigo, agradeceria de veras si alguien me echa una mano.
Aki esta el codigo del sencillo programa principal:
#include <18F452.h>
#fuses NOWDT,HS,NOPROTECT
#use delay(clock=20000000)
#include <lcd_placa.c>
void main()
{
lcd_init();
lcd_putc("fReady...");
}
Y a continuacion os pongo el codigo de la rutina lcd_placa.c
///////////////////////////////////////////////////////////////////////////
//// ////
//// 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 ////
////
Go to start of second line ////
//// 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 ////
//// ////
///////////////////////////////////////////////////////////////////////////
struct lcd_control_pin_map {
BOOLEAN rs;
BOOLEAN rw;
} lcd_control;
BOOLEAN enable;
struct lcd_data_pin_map {
BOOLEAN nc1;
BOOLEAN nc2;
BOOLEAN nc3;
BOOLEAN nc4;
int data : 4;
} lcd_data;
#byte lcd_data = 0xF81 // PORT B
#byte lcd_control = 0xF84 // PORT E
#bit enable = 0xF82.5 //PORT C, bit RC5
#define set_tris_lcd_data(x) set_tris_b(x)
#define set_tris_lcd_control(x) set_tris_e(x)
#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_data_pin_map const LCD_WRITE = {0,0,0,0,0}; // For write mode all pins are out
struct lcd_data_pin_map const LCD_READ = {0,0,0,0,15}; // For read mode data pins are in
struct lcd_control_pin_map const LCD_CONTROL_WRITE = {0,0};
BYTE lcd_read_byte() {
BYTE low,high;
set_tris_lcd_data(LCD_READ);
lcd_control.rw = 1;
delay_cycles(1);
enable = 1;
delay_cycles(1);
high = lcd_data.data;
enable = 0;
delay_cycles(1);
enable = 1;
delay_us(1);
low = lcd_data.data;
enable = 0;
set_tris_lcd_data(LCD_WRITE);
return( (high<<4) | low);
}
void lcd_send_nibble( BYTE n ) {
lcd_data.data = n;
delay_cycles(1);
enable = 1;
delay_us(2);
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);
enable = 0;
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}
void lcd_init() {
BYTE i;
set_tris_lcd_data(LCD_WRITE);
set_tris_lcd_control(LCD_CONTROL_WRITE);
set_tris_c(0x00);
lcd_control.rs = 0;
lcd_control.rw = 0;
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);
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);
}