TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: pacalaconcurso en 12 de Diciembre de 2002, 11:30:00
-
bueno como sabeis la libreria de comunicacion con la lcd de CCS solo esta preparada para lcd`s de dos lineas.
asi la uso para la pantalla de cuatro pero ahora me encuentro otro problema:
he comprado una lcd de 2x16 de cebek y al usarla con CCS no tira bien (parece ser algo relacionado con los retardos, pues modificandolos consiguo que algunas letras si las muestre, pero no todas...). si la uso con pbp va perfecto.
se ha encontrado alguien el mismo problema o sabe la solucion??? me planteo el tener que empezar la rutina desde cero (o cambiar de marca de lcd, claro)
// D0 enable
// D1 rs
// D2 rw
// D4 D4
// D5 D5
// D6 D6
// D7 D7
//
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 // on to port D (at address 8)
#define set_tris_lcd(x) set_tris_d(x)
#define lcd_line_two 0x40 // LCD RAM address para la segunda linea
#define lcd_line_three 0x14 // LCD RAM address para la tercera linea
#define lcd_line_four 0x54 // LCD RAM address para la cuarta linea
byte CONST LCD_INIT_STRING[4] = {0x28, 0x0C, 1, 6}; //inicializacion de la lcd
STRUCT lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; //para escribir todas las patitas salidas
STRUCT lcd_pin_map const LCD_READ = {0,0,0,0,15}; // para leer el bus de datos son entradas
byte lcd_read_byte() {
byte low,high;
set_tris_lcd(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_lcd(LCD_WRITE);
return( (high<<4) | low);
}
void lcd_send_nibble( byte n ) {
lcd.data = n;
delay_cycles(5);
lcd.enable = 1;
delay_us(4);
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(5);
lcd.rw = 0;
delay_cycles(5);
lcd.enable = 0;
lcd_send_nibble(n >> 4);
lcd_send_nibble(n & 0xf);
}
void lcd_init() {
byte i;
set_tris_lcd(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);
//delay_ms(5);
}
void lcd_gotoxy( byte x, byte y) {
byte address;
switch(y) {
case 1 : address=0;
break;
case 2 : address=lcd_line_two;
break;
case 3 : address=lcd_line_three;
break;
case 4 : address=lcd_line_four;
break;
}
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 "n" : lcd_gotoxy(1,2); break;
case "b" : 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);
}
un saludo
-
bueno me respondo a mi mismo:
a veces, muy pocas eso si, las maquinas tambien fallan.
tras cambiar y recambiar el codigo y no conseguir nada, simplemente cambie la pantalla en la tienda por otra igual (el de la tienda es amigo, claro) y !!!!solucionado!!.
creo que a veces me vuelvo loco solo y joeee, es el cacharo el loco
.
aunque parezca mentira, me paso lo siguiente:
mote la caja del famoso rotor con sus botoncillos, la pantalla y cuendo la pongo en marcha na de na, solo unos garabatos en la pantalla.....
tras eso comienza mi meditacion sobre el porque.. 
se me ocurre probar con pbp un mensajito y joeee funciona
con lo que me quedo frio del todo claro....
tras probar 10001 cosas con mi rutina solo consigo ver algunos caracteres y claro, hize el famoso bucle para presentar uno a uno todos los caracteres en la pantalla y me doy cuenta de que la jilipollez que escribi en pbp salian todas las letras
...
cuando volvi a probar en pbp con la frase "Hola lucas"........os imaginais como me quede 
de todo se aprende.
un saludo
-
/*
aqui te dejo un codigo de libreria de lcd para el compilador CCS :-/ espsero que le sirva
es especialmente fireware S6A0069 tiene la ventaja que puede configurar el lcd casi por completo bueno bye :)
*/
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
// LCD.H //
// VERSION 2.1 //
// JULIO 2009 //
// //
//////////////////////////////////////////////////////////////////////////////////////////////////////////////
#nolist
// DEFINICION DE CONSTANTES PARA USO EN FUNCIONES
#define HOME 0x02 // PARA PONER CURSOR EN LA POSICION 0 DEL DISPLAY. USAR CON WRITE_LCD_COM
#define INCREASE 0x02 // INCREMENTA CURSOR. USAR CON LCD.ID
#define DECREASE 0x00 // DECREMENTA CURSOS. USAR CON LCD.ID
#define SHIFT_ON 0x01 // SHIFT DISPLAY. USAR CON LCD.SHIFT
#define SHIFT_OFF 0x00 // NO SHIFT DISPLAY. USAR CON LCD.SHIFT
#define LCD_ON 0x04 // ACTIVA LCD. USAR CON LCD.MODE
#define LCD_OFF 0x00 // DESACTIVA LCD. USAR CON LCD.MODE
#define CURSOR_ON 0x02 // ACTIVA CURSOR. USAR CON LCD.CURSOR
#define CURSOR_OFF 0x00 // DESACTIVA CURSOR. USAR CON LCD.CURSOR
#define BLINK_ON 0x01 // ACTIVA PARPADEO DEL CURSOR. USAR CON LCD.BLINK
#define BLINK_OFF 0x00 // DESACTIVA PARPADEO DEL CURSOR. USAR CON LCD.BLINK
#define BUS_8 0x10 // DEFINE BUS DE 8 BITS. USAR CON LCD.INTERFASE
#define BUS_4 0x00 // DEFINE BUS DE 4 BITS. USAR CON LCD.INTERFASE
#define CLEAR 0x01 // LIMPIA DISPLAY. USAR CON FUNCION WRITE_LCD_DATA()
#define NOCLEAR 0x00 // NO LIMPIA DISPLAY. USAR CON FUNCION WRITE_LCD_DATA()
#define LINE1 0x00 // PRIMERA DIRECCION DE LINEA 1.
#define LINE2 0x40 // PRIMERA DIRECCION DE LINEA 2.
#define LINE3 0x14 // PRIMERA DIRECCION DE LINEA 3.
#define LINE4 0x54 // PRIMERA DIRECCION DE LINEA 4.
#define LARGO 16 // Editar esta línea para indicar la cantidad de caracteres por línea del display
#define LINEAS 2 // Editar este línea para indicar la cantidad de líneas que dispone el display
#define NULL 0x00
#list
struct
{
char TEXT[LARGO+1]; // define texto para escribir en lcd
int ID; // define si el cursor de incrementará o decrementará
int SHIFT; // define el shift del cursor
int MODE; // define si el display está ON ú OFF
int CURSOR; // define si el cursor estará visible
int BLINK; // define si el cursor parpadeará
int INTERFASE; // define interfase de 4/8 bits
} lcd;
// CONFIGURAR AQUI LOS PUERTO QUE SE USARAN PARA BUS DE DATOS Y DE CONTROL
/*
#byte DataBus = PORTD // DEFINE BUS DE DATOS
#byte Tris_DataBus = TRISD // DEFINE TRIS DE BUS DE DATOS
#byte ControlBus = PORTE // DEFINE BUS DE CONTROL
#byte Tris_ControlBus = TRISE // DEFINE TRIS DEL BUS DE CONTROL
*/
#byte DataBus = PORTD // DEFINE BUS DE DATOS
#byte Tris_DataBus = TRISD // DEFINE TRIS DE BUS DE DATOS
#byte ControlBus = PORTE // DEFINE BUS DE CONTROL
#byte Tris_ControlBus = TRISE // DEFINE TRIS DEL BUS DE CONTROL
// GENERA PULSOS DE ESCRITURA PARA COMANDOS DEL DISPLAY Y SACA DATO
void WriteLcdComData(int x)
{
Tris_ControlBus = 0xF8 & Tris_ControlBus;
Tris_DatalBus = 0x00;
DataBus = ControlBus = 0x00;
ControlBus = 3;
ControlBus = 0;
ControlBus = 4;
DataBus = x;
ControlBus = 0;
ControlBus = 3;
delay_us(50);
}
// LIMPIA DISPLAY
void ClearLcd(void)
{
WriteLcdComData(CLEAR); // display clear
delay_ms(2);
}
// INICIALIZA EL EL DISPLAY
void IniLcd(void)
{
delay_ms(20);
WriteLcdComData(0x30);
delay_ms(5);
WriteLcdComData(0x30);
delay_us(150);
WriteLcdComData(0x30);
}
// CONFIGURA EL DISPLAY. LOS DATOS PARA LA CONFIGURACION DEBEN SER PUERTOS ANTES DE LLAMAR
// A ESTA FUNCION. LOS DATOS SON PARTE DE LA ESTRUCTURA LCD.
void SetupLcd(void)
{
WriteLcdComData(0x04 | lcd.ID | lcd.SHIFT); //ENTRY MODE SET
WriteLcdComData(0x08 | lcd.MODE | lcd.CURSOR | lcd.BLINK); // DISPLAY ON OFF
WriteLcdComData(0x28 | lcd.INTERFASE); // SET FUNCTION
}
// ESCRIBE DATOS EN EL DISPLAY. X REPRSENTA DESDE QUE DIRECCIÓN DEL DISPLAY SE DESEAN ESCRIBIR LOS DATOS
// E Y INDICA SE SE LIMPIARÁ EL DISPLAY ANTES DE ESCRIBIR
// SI C = CLEAN, EL DISPLAY ES LIMPIADO
// SI C = NOCLEAN, SOLO SE ESCRIBEN LOS DATOS DESDE LA POCISION ESPECIFICADA POR POS
// LOS DATOS A ESCRIBIR DEBE SER COPIADOS PREVIAMENTE EN EL ELEMENTO LCD.TEXT DE LA ESCTRUCTIRA LCD
void WriteLcd(int pos, int c)
{
int *p;
Tris_ControlBus = 0xF8 & Tris_ControlBus;
Tris_DatalBus = 0x00;
DataBus = ControlBus =0x00;
if (c)
{
clear_lcd();
delay_ms(2);
}
pos|= 0x80;
WriteLcdComData(pos);
p = lcd.TEXT;
for (; *p!=NULL; p++)
{
DataBus = 0xff;
ControlBus = 2;
ControlBus = 1;
ControlBus = 5;
DataBus = *p;
ControlBus = 1;
ControlBus = 2;
delay_us(50);
}
}
void PutcLcd(int ini, char data)
{
if (ini != CURRENT)
{
ini|= 0x80;
WriteLcdComData(ini);
}
Tris_ControlBus = 0xF8 & Tris_ControlBus;
Tris_DatalBus = ControlBus = 0x00;
DataBus = 0xff;
ControlBus = 2;
ControlBus = 1;
ControlBus = 5;
DataBus = data;
ControlBus = 1;
ControlBus = 2;
delay_us(50);
}
void ClearLcdLine(int x)
{
int y;
for (y=0; y<=LARGO; y++)
{
lcd.TEXT[y] = ' ';
}
lcd.TEXT[++y] = NULL;
switch (x)
{
case 1 : WriteLcd(LINE1,NOCLEAR);
break;
case 2 : WriteLcd(LINE2,NOCLEAR);
break;
case 3 : WriteLcd(LINE3,NOCLEAR);
break;
case 4 : WriteLcd(LINE4,NOCLEAR);
break;
default : break;
}
}