Gracias MGLSOFT, pero en lugar de usar las librerías, las hago yo mismo en el programa principal para un mejor control y más preciso, os adjunto el código, con cada una de sus funciones:
Codigo:
void LCD_E (void)
{
bit_set(puerto_a,1);
delay_cycles(12);
bit_clear(puerto_a,1);
return;
}
void LCD_REG (void)
{
bit_clear(puerto_a,3);
bit_clear(puerto_a,2);
puerto_b=registro_w;
delay_us(100);
LCD_E();
return;
}
void LCD_DATOS (void)
{
bit_set(puerto_a,3);
puerto_b=registro_w;
delay_us(100);
LCD_E();
return;
}
void LCD_DATOS2 (void)
{
swap(registro_w);
LCD_DATOS();
swap(registro_w);
LCD_DATOS();
return;
}
void LCD_INI (void)
{
registro_w=0x0E;
LCD_REG();
delay_ms(20);
registro_w=0x03;
LCD_REG();
delay_ms(6);
registro_w=0x03;
LCD_REG();
delay_ms(1);
registro_w=0x03;
LCD_REG();
delay_ms(6);
registro_w=0x02;
LCD_REG();
registro_w=0x02;
LCD_REG();
delay_ms(7);
registro_w=0x08;
LCD_REG();
delay_ms(7);
registro_w=0x00;
LCD_REG();
delay_ms(7);
registro_w=0x08;
LCD_REG();
delay_ms(7);
registro_w=0x00;
LCD_REG();
delay_ms(7);
registro_w=0x01;
LCD_REG();
delay_ms(7);
registro_w=0x00;
LCD_REG();
delay_ms(7);
registro_w=0x06;
LCD_REG();
delay_ms(7);
registro_w=0x00;
LCD_REG();
delay_ms(7);
registro_w=0x0C;
LCD_REG();
delay_ms(7);
return;
}
Codigo:
void config_ports(void)
{
delay_cycles(3);
set_tris_a(0x00);
set_tris_b(0x20); // en el TX pongo entrada para no enviar nada al hyperterminal al enviar un caracter, se pone como salida en el momento de enviar (enviar_serie())
// bit_clear(puerto_a,3); // RS=0 (modo instruccion)
// bit_clear(puerto_a,1); // E=0 (señal enable)
ansel=0x00; // todas las puertas como digital
adcon_1=0x00;
osccon=0x6C; // configuración para 4 MHz
delay_ms(10); // espera minima de 4 ms para acabar de configurar el reloj interno (pag 41 de datasheet)
option_reg=0x80;
delay_ms(10);
puerto_a=0;
puerto_b=0;
return;
}
Codigo:
void inicio_USART (void)
{
bit_set(txsta,2); //BGRH=1 (velocidad alta)
bit_clear(txsta,4); //SYNC=0 (modo asíncrono)
bit_set(txsta,5); //TXEN=1 (habilita transmisión)
bit_clear(txsta,6); //TX9=0 (modo de 8 bits)
bit_clear(rcsta,1);
bit_clear(rcsta,2);
bit_clear(rcsta,3);
bit_set(rcsta,4); //CREN=1 (habilita recepción)
bit_clear(rcsta,6); //RX900 (modo de 8 bits)
//TX<-0 (salida), RX<-1 (entrada)
spbrg=0x19; //9.600 baudios (25 en decimal)
// bit_set(rcsta,7); //SPEN=1 (habilita puerto serie)
}
void enviar_serie(char c) //envia un caracter
{
int saltar=0;
set_tris_b(0x00); //TX como salida
bit_set(rcsta,7); //SPEN=1 (habilita puerto serie)
do
{
if (bit_test(txsta,1)) saltar++;
}while(!saltar);
txreg=c;
bit_clear(rcsta,7); //SPEN=0 (deshabilita puerto serie)
set_tris_b(0x20); //TX como entrada, para no enviar transmitir nada al enviar un caracter por PORT_B
}
char recibir_serie (void) //recibe un caracter
{
char c;
int saltar=0;
bit_set(rcsta,7); //SPEN=1 (habilita puerto serie)
set_tris_b(0x24); //bit 2 del puerto B como entrada (RB2,RX)
do
{
if (bit_test(pir1,5)) saltar++;
}while(!saltar);
c=rcreg;
registro_w=c;
set_tris_b(0x20); //dejamos como estaba el puerto B
enviar_serie(c); //hace "ECO" en el hyperterminal
bit_clear(rcsta,7); //SPEN=0 (deshabilita puerto serie)
return c;
}
Tal como se ve en el código, a lahora de enviar un caracter por lcd, lo envio por todo el puerto, supongo que para arreglar (enviar solo 4 bits), ¿como es posible enviar por un puerto los 4 bits de golpe?
También intento solucionar poniendo como entrada la pata TX por derfecto, asi despues, cada vez que tenga que enviar algo por puerto serie, lo configuro como salida y vuelgo a poner como entrada una vez enviado. Pienso que es una buena solucion, pero no funciona muy bien.
Gracias!