Codigo:
// coach_lcd.c
//
// Funciones para la gestion del display 2x16 [ByCoach]:
//
// lcd_iniciar() Debe ser llamada antes que las otras funciones.
//
// lcd_putc(c) Visualiza c en la siguiente posición del display.
// Caracteres especiales de control:
// f Borrar display
//
Saltar a la segunda linea
// Retroceder una posición.
//
// lcd_gotoxy(x,y) Selecciona la nueva posicion de escritura en el display.
// (la esquina superior izquierda es 1,1)
//
// lcd_getc(x,y) Devuelve el caracter de la posicion x,y del display.
//Definición de pines:
#define lcd_rs PIN_C0 //
#define lcd_rw PIN_C1 //
#define lcd_en PIN_C2 //
#define lcd_DB4 PIN_C4 //
#define lcd_DB5 PIN_C5 //
#define lcd_DB6 PIN_C6 //
#define lcd_DB7 PIN_C7
void lcd_enviar_nibble( int nibble )
{
output_bit( lcd_DB4, bit_test( nibble, 0 ) ); //Pone en el puerto B[4..7] el valor en nibble[0..3]
output_bit( lcd_DB5, bit_test( nibble, 1 ) );
output_bit( lcd_DB6, bit_test( nibble, 2 ) );
output_bit( lcd_DB7, bit_test( nibble, 3 ) );
delay_us( 1 );
output_high( lcd_en ); //Activa y desactiva enable para que el lcd capture el nibble
delay_us( 2 );
output_low( lcd_en );
}
int lcd_leer_byte( void )
{
int valor = 0;
output_high( lcd_rw ); //Se activa rw indicando que se va a realizar una lectura
delay_us( 1 );
output_high( lcd_en ); //Se activa enable para que el lcd saque la parte alta del byte deseado
delay_us( 1 ); //por los pines de datos
if( input( lcd_DB7 ) ) //Se captura la parte alta del byte deseado
bit_set( valor, 7 );
if( input( lcd_DB6 ) )
bit_set( valor, 6 );
if( input( lcd_DB5 ) )
bit_set( valor, 5 );
if( input( lcd_DB4 ) )
bit_set( valor, 4 );
output_low( lcd_en ); //Se desactiva y se vuelve a activar enable para que el lcd saque la parte
delay_us( 1 ); //baja del byte deseado por los pines de datos
output_high( lcd_en );
delay_us( 1 );
if( input( lcd_DB7 ) ) //Se captura la parte baja del byte deseado
bit_set( valor, 3 );
if( input( lcd_DB6 ) )
bit_set( valor, 2 );
if( input( lcd_DB5 ) )
bit_set( valor, 1 );
if( input( lcd_DB4 ) )
bit_set( valor, 0 );
output_low( lcd_en ); //Se desactiva enable, indicando al lcd el fin de la lectura del byte
return( valor ); //Devuelve el byte capturado
}
void lcd_enviar_byte( int dir, int valor ) //Si recibe en dir un 1 se trata de un dato y si es un 0 es un comando
{
output_low( lcd_rs );
while( bit_test( lcd_leer_byte(), 7 ) ); //Lectura del Flag de Busy (ocupado), si 1 se espera, si 0 se continúa
output_bit( lcd_rs, dir ); //Se asigna a rs el valor de dir para indicar si es dato o comando
delay_us( 1 );
output_low( lcd_rw ); //Se pone a cero rw para indicar que se va a realizar una escritura
delay_us( 1 );
output_low( lcd_en ); //Se pone a cero enable para preparar el valor a enviar
lcd_enviar_nibble( valor >> 4 ); //Se envÃa primero la parte alta del byte
lcd_enviar_nibble( valor & 0x0F ); //a continuación se envÃa la parte baja
}
void lcd_posicionar( int x, int y ) //Se reciben las coordenadas x e y a las que se desea desplazarse
{
int dir;
if ( y != 1 ) //La posición "y" determinará la lÃnea elegida, si es 1 -> LÃnea 1, si no -> LÃnea 2
dir = 0x40; //Dirección de la RAM del LCD para la 2ª lÃnea
else
dir = 0x00; //Dirección de la RAM del LCD para la 1ª lÃnea
dir += x - 1; //Resta uno, ya que la posición 1 serÃa la 0 para el lcd
lcd_enviar_byte( 0, dir | 0x80 ); //Se envÃa el byte, indicando que es un comando y poniendo el bit
} //más significativo a 1, para diferenciar este comando de los demás
void lcd_iniciar( void )
{
int i;
int bytes_inicio[4] = { 0x28, 0x0C, 0x01, 0x06 };
output_low( lcd_rs ); //Pone a cero todos los pines de control
output_low( lcd_rw );
output_low( lcd_en );
delay_ms( 30 );
for ( i = 1 ; i <= 3 ; i++ )
{
lcd_enviar_nibble( 3 );
delay_ms( 5 );
}
lcd_enviar_nibble( 2 );
for( i = 0 ; i <= 3 ; i++ ) //Se configura el lcd con las caracterÃsticas indicadas anteriormente
lcd_enviar_byte( 0 , bytes_inicio );
}
void lcd_putc( char c ) //Se recibe el caracter a enviar
{
switch( c )
{
case "f" : lcd_enviar_byte( 0, 1 ); //Si c = "f", se envÃa un 1, e indica que es un comando
delay_ms( 2 ); //Enviando un 1, se borra la pantalla del lcd
break;
case "
" : lcd_posicionar( 1, 2 ); //Si c = "
", se posiciona en la segunda lÃnea
break;
case "" : lcd_enviar_byte( 0, 0x10 ); //Si c = "", se sitúa una posición a la izquierda
break;
default : lcd_enviar_byte( 1, c ); //Si no es ninguna de las anteriores, envÃa un caracter
break;
}
}
char lcd_getc( int x,int y ) //Se reciben las coordenadas x e y de las que se desea el dato
{
char valor;
lcd_posicionar( x, y ); //Se posiciona en el punto deseado
output_high( lcd_rs ); //Pone a 1 el pin rs, indicando que se trata de un dato
valor = lcd_leer_byte(); //Lee el byte de la posición deseada
output_low( lcd_rs );
return( valor ); //Devuelve el caracter leÃdo
}