Si además quieres enviarnos un Artículo para el Blog y redes sociales, pulsa el siguiente botón:
Hola;
Mediante un PIC16F877, estoy intentando controlar un display. Necesito las funciones de inicialización, control busy, envio y sus respectivas rutinas de retardo en codigo C, para el display PC4004-A de 4x40. Utiliza dos controladores ks0066u y 4 drivers. El caso esque no hay forma de que lo haga funcionar y de este modo podre descartar la programación. Si alguien ha utilizado este display o similar, se lo agradeceria con antelación por su ayuda.
UN saludo
BROWN
Esto es lo que uso yo para un display de 16x1, el controlador es parecido, pero compatible a nivel de registros. Solo tienes que escribir OutToDisplay() para que mande los datos DataLCD a D0-D7 y ControlLCD a R/W, CS, y E, dependiendo de tu conexionado. Mi función OutToDisplay() incluye un retardo de unos 10 us.
/*==========================================================================*/
/* Rutinas de display LCD para controlador HD44780A o similar 13/12/2001 */
/* Adaptadas a CCS 3,236 para PIC y hardware Reciclator1 20/2/2007 */
/* Cambiar en DisplayInit() la inicialización según las necesidades */
/* */
/* La funcion OutToDisplay() envía al display el dato DataLCD y ControlLCD */
/*==========================================================================*/
#include "display.h"
static int8 cursor;
/*==========================================================================*/
/* CONTROL DEL DISPLAY */
/*==========================================================================*/
void LcdCtr (char dato)
{
ControlLCD = 0x06; /* E WR RS = 110 RS=0, E y rw inactivo */
OutToDisplay(); /* Envía los datos al display */
ControlLCD = 0x04; /* E WR RS = 100 RS=0, E inactivo y rw activo */
OutToDisplay();
DataLCD = dato; /* saca el dato */
OutToDisplay();
ControlLCD = 0x00; /* E WR RS = 000 RS=0, E activo y rw activo */
OutToDisplay();
ControlLCD = 0x00; /* E WR RS = 000 RS=0, E activo y rw activo */
OutToDisplay();
ControlLCD = 0x04; /* E WR RS = 100 RS=0, E inactivo y rw activo */
OutToDisplay();
ControlLCD = 0x06; /* E WR RS = 110 RS=0, E y rw inactivo */
OutToDisplay();
delay_us(44); // Según Optrex esto tarda 40us en procesarse
}
/*==========================================================================*/
/* Inicializa el display */
/*==========================================================================*/
void LcdInit (void)
{
// LcdCtr incluye el retardo de 40 ms que tarda el display en procesar
delay_ms(15); // Según Optrex esperar 10ms antes de usar el display
LcdCtr (0x38); // Function set 38 = 00111000 8 bits, 2 lines */
LcdCtr (0x06); /* Entry Mode Set 00000110 (Increment, No shift) */
LcdCtr (0x0C); /* Display ON/OFF 00001110 Display ON, Cursor ON, No blink */
LcdClear ();
LcdHome ();
LcdCursorOff();
}
/*==========================================================================*/
/* Visualiza un caracter en la posicion actual del cursor */
/*==========================================================================*/
void LcdChar (char ch)
{
ControlLCD = 0x07; /* E WR RS = 110 RS=0, E y rw inactivo */
OutToDisplay();
ControlLCD = 0x05; /* E WR RS = 100 RS=0, E inactivo y rw activo */
OutToDisplay();
DataLCD = ch; /* saca el dato */
OutToDisplay();
ControlLCD = 0x01; /* E WR RS = 000 RS=0, E activo y rw activo */
OutToDisplay();
ControlLCD = 0x01; /* E WR RS = 000 RS=0, E activo y rw activo */
OutToDisplay();
ControlLCD = 0x05; /* E WR RS = 100 RS=0, E inactivo y rw activo */
OutToDisplay();
ControlLCD = 0x07; /* E WR RS = 110 RS=0, E y rw inactivo */
OutToDisplay();
delay_us(44); // Según Optrex esto tarda 40us es procesarse
}
/*==========================================================================*/
/* Visualiza un mensaje en la posicion actual del cursor */
/*==========================================================================*/
void LcdMsg ( char *mensaje)
{
while (*mensaje)
{
if ((cursor%ADISPLAY)==0)
LcdGoto();/* va a la posicion actual del cursor (cmmbia linea) */
LcdChar (*mensaje++);
}
}
/*==========================================================================*/
/* Visualiza un mensaje de n caracteres en la posicion actual del cursor */
/*==========================================================================*/
void LcdDisplayMsgN (char *mensaje, int16 d)
{
while (d-- && *mensaje)
{
if ((cursor%ADISPLAY)==0)
LcdGoto();/* va a la posicion actual del cursor (cambia linea) */
LcdChar (*mensaje++);
}
}
/*==========================================================================*/
/* Funciones de posicionamiento del cursor */
/*==========================================================================*/
void LcdCursorLeft (void)
{
LcdCtr (0x10); /* 00010000 Cursor left */
cursor--;
}
/*==========================================================================*/
void LcdCursorRight (void)
{
LcdCtr (0x14); /* 00010100 Cursor right */
cursor++;
}
/*==========================================================================*/
void LcdClear (void)
{
int16 cont;
LcdCtr (0x01); /* 00000001 Clear display */
delay_ms(2); // Según Optrex esto tarda 1,64ms es procesarse
cursor=0;
}
/*==========================================================================*/
void LcdHome (void)
{
int8 cont;
LcdCtr (0x02); /* 00000010 Cursor home */
delay_ms(2); // Según Optrex esto tarda 1,64ms es procesarse
cursor=0;
}
/*==========================================================================*/
void LcdCursorOn (void)
{
LcdCtr (0x0E); /* 00001110 Display ON, Cursor ON, No blink */
}
/*==========================================================================*/
void LcdCursorOff (void)
{
LcdCtr (0x0C); /* 00001100 Display ON, Cursor OFF, No blink */
}
/*==========================================================================*/
/* Posiciona el cursor en coordenadas (x,y) */
/*==========================================================================*/
void LcdXY (int8 x, int8 y)
{
register int8 daddr;
daddr = x + (y ? 0x40: 0);
LcdCtr (0x80 | daddr); /* Carga la direccion absoluta */
delay_ms(10);
cursor=x+(y*ADISPLAY);
}
/*==========================================================================*/
/* Posiciona el cursor en coordenada lineal cursor */
/*==========================================================================*/
void LcdGoto (void)
{
register char x,y;
int8 cont;
x=cursor%ADISPLAY;
y=cursor/ADISPLAY;
y<<=6;
LcdCtr (0x80 | x | y); /* Carga la direccion absoluta */
delay_ms(10);
}
//=============================================================================
// Inicializacion y bucle principal
void main()
{
setup_adc_ports(ALL_ANALOG);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(0);
setup_spi(FALSE);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_128);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DIV_BY_4,255,1);
setup_comparator(NC_NC_NC_NC);
setup_vref(FALSE);
enable_interrupts(INT_RB);
enable_interrupts(INT_TIMER0);
LcdInit(); // Inicializa el display
LcdChar ("Hola, Estoy aqui.."); // Mensaje "estoy vivo"
while (TRUE) // Bucle principal
{
}
}