TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: jukinch en 28 de Enero de 2008, 03:21:18
-
Hola amigos:
Necesito saber que puedo estar haciendo mal. -
Estoy haciendo mis primeras prácticas con el lcd y estoy luchando con el texto fantasma.-
En el lcd me aparece el texto como si fuera con bajo contraste pero lo reseteo al pic un par de veces y se pone el texto normal con buen contraste.-
Transcribo más abajo el código ccs y la libreria.-
Hice el conexionado de la siguiente manera:
// B2 E
// B3 RS
// B4 D4
// B5 D5
// B6 D6
// B7 D7
RW a masa
Saludos.-
Jukinch.-
//------Directivas para el compilador--------
#include <16f84a.h> //pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
#use fast_io(b)
#INCLUDE "lcd16f84a.c" //Incluyo la libreria
//
//
//------Programa principal----------
//---------------------------------------------------------------------------
void main(void) {
//------Puertos y pines-------------
set_tris_a(0xff); //puerto a como entradas
set_tris_b(0x00); //puerto a como salidas
//-----Inicializo el LCD y muestro el saludo inicial----------
lcd_init();
Lcd_putc( "\f");
delay_ms(100);
Lcd_putc ("uControl.com.ar");
}
archivo libreria lcd16f84a.c
///////////////////////////////////////////////////////////////////////////
// LCD.C modificada por uControl.com.ar
///////////////////////////////////////////////////////////////////////////
// B0
// B1
// B2 E
// B3 RS
// B4 D4
// B5 D5
// B6 D6
// B7 D7
// (Sin 'RW')
//
// Funciones soportadas:
// lcd_init()
// lcd_gotoxy( BYTE col, BYTE fila)
// lcd_putc( char c)
// \f Clear display
// \n Go to start of second line
// \b Move back one position
//
///////////////////////////////////////////////////////////////////////////
#define use_portb_lcd TRUE //LCD conectado al puerto b.
//
struct lcd_pin_map {
BOOLEAN unused1; // RB0
BOOLEAN unused2; // RB1
BOOLEAN enable; // RB2
BOOLEAN rs; // RB3
int data : 4; // RB4-RB7
} lcd;
//
#byte lcd = 0xF81 // Direccion de la estructura "lcd".
#byte lcd = 6 // Direccion del puerto B.
#define set_tris_lcd(x) set_tris_b(x)
#define lcd_type 2 // Tipo de LCD: 0=5x7, 1=5x10, 2=2 lineas
#define lcd_line_two 0x40 // Dirección de la LCD RAM para la 2da. linea
//
//Defino la cadena de inicializacion del LCD.
BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
//
//Configuro el estado de cada pin para lectura y escritura:
struct lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; // Escribir.
struct lcd_pin_map const LCD_READ = {0,0,0,0,15}; // Leer.
//
//Funciones:
BYTE lcd_read_byte() {
BYTE low,high;
set_tris_lcd(LCD_READ);
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(1);
lcd.enable = 1;
delay_us(2);
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(1);
delay_cycles(1);
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.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 '\n' : lcd_gotoxy(1,2); break;
case '\b' : lcd_send_byte(0,0x10); break;
default : lcd_send_byte(1,c); break;
}
}
-
Eso pinta mas a problemas de hardware que a software. Estas haciendo las pruebas en una placa de desarrollo o estas en un portoboard con cables, si es lo ultimo seguro quepor ahi se esta haciendo un falso contacto y al momento que reseteas el pic mueves algun cable :mrgreen:
-
Gracias Poseidon20 por tu respuesta.
Estoy haciendo las pruebas en una placa de desarrollo.
Jukinch
-
Otra vez por aquí amigos foreros.
Les cuento que solucioné el problema del lcd fantasma!!! . :)
El lcd que tengo es un marca FORDATA FDCC1602G.
Se ve que este guacho lcd es un poco perezoso y le tengo que dar más tiempos entre instrucción e instrucción.-
Solución:
1ro hice pruebas con proton y andaba bien el display.
2do hice pruebas con asm y andaba bien el display.
3ro Entonces me empeciné a solucionar el problema de usar CCS que es el lenguaje que quiero aprender a full :)
Probé cuanta librería encontré. y nada. siempre igual. Seguía sin ver nada.
O probando con el reset hasta que se veía bien con contraste a full.
4to para ver paso por paso como se inicializaba creé el programa que postéo más abajo. Y exageré los tiempos para estar tranquilo que no fallara el LCD y boalá!!!!!!. Ahora anda bien.
5to Estoy como perro con dos colas.- :)
6to Una vez más gracias pozeidón20 por tu respuesta.
Un abrazo a todos.
Jukinch
Aquí va el programa:
///////////////////////////////////////////////////////////////////////////////
// Autor: JUKINCH para el foro todopic
// Fecha: 30/ENERO/08
//
// Programa: INICIALIZACIÓN DE LCD en 8 bits
// Version: 0.0
//
// Dispositivo: PIC 16F84A Compilador: CCS vs3.42
// Entorno IDE: ccs
// PIC: 16f84a
// Notas: El programa está hecho para ejemplificar como see inicializa
// el display LCD HITACHI o Compatible.-
// Y escribe HOLA TODO PIC
// El código no es óptimo. Se podría simplificar usando funciones.
// Es para ejemplificar.-
// Además los tiempos de espera entre instrucción e instrucción se hicieron
// mucho más largos para evitar que se sature el display
///////////////////////////////////////////////////////////////////////////////
// Conexión del LCD al Pic (configuración de pines)
//
// PIC LCD
//
// PORTA.0 E
// PORTA.1 RS
// PORTA.2 R_W
//
//
//
// PORTB.0 D0
// PORTB.1 D1
// PORTB.2 D2
// PORTB.3 D3
// PORTB.4 D4
// PORTB.5 D5
// PORTB.6 D6
// PORTB.7 D7
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
#include <16f84a.h> //pic a utilizar
#fuses XT,NOWDT,NOPROTECT,PUT //ordenes para el programador
#use delay (clock=4000000) //Fosc=4Mhz
void strobe_enable(void); // declaro función
//------Programa principal--------------------------------------
void main(void)
{
//------Puertos y pines-----------------------------------------
set_tris_a(0b00000); // puerto a como salidas
set_tris_b(0b00000000); // puerto b como salidas
disable_interrupts(GLOBAL); // todas las interrupciones desactivadas
//-----Inicializo el LCD------------------------
output_low(PIN_A1); // RS = 0;
output_low(PIN_A2); // R_W = 0;
output_low(PIN_A0); // E = 0;
delay_ms(500); // espera más de 15 milisegundos para que le llegue al display
// el mínimo requerido de vdd
output_b(0b00110000); //inicializo el lcd en 8 bits hex = 0x030
strobe_enable(); // espera más de 5 milisegundos.
output_b(0b00110000); //inicializo el lcd en 8 bits hex = 0x030
strobe_enable(); // espera más de 160 microsegundos.-
output_b(0b00110000); //inicializo el lcd en 8 bits hex = 0x030
strobe_enable(); // espera más de 160 microsegundos.-
output_b(0b00111000); //establece display de 2 lineas y caracteres de 5x8
strobe_enable(); // espera más de 160 microsegundos.-
output_b(0b00001000); // Apaga el display
strobe_enable(); // espera más de 160 microsegundos.-
output_b(0b00000001); // Borra el display
strobe_enable(); // espera más de 160 microsegundos.-
output_b(0b00000110); // Entry mode set
strobe_enable(); // espera más de 160 microsegundos.-
//-----Fin de inicialización de LCD------------------------
//-----escribo en LCD------------------------
output_b(0b00000010); // Cursor al Home
strobe_enable(); // espera más de 160 microsegundos.-
output_b(0b00001100); // Prendo display
strobe_enable(); // espera más de 160 microsegundos.-
// --------- prepara para mandar caracteres ----------------------------------
output_high(PIN_A1); // RS = 1; Poner a positivo la señal de 'RS' (Envio de un dato)
output_low(PIN_A2); // R_W = 0;
//-----ESCRIBE HOLA ------------------------
output_b(0b01001000); // letra H. Enviar el byte de datos (8 bits en los pines D0 a D7)
strobe_enable(); // espera más de 160 microsegundos.-
output_b(0b01001111); // letra O. Enviar el byte de datos (8 bits en los pines D0 a D7)
strobe_enable(); // espera más de 160 microsegundos.-
output_b(0b01001100); // letra L. Enviar el byte de datos (8 bits en los pines D0 a D7)
strobe_enable(); // espera más de 160 microsegundos.-
output_b(0b01000001); // letra A. Enviar el byte de datos (8 bits en los pines D0 a D7)
strobe_enable(); // espera más de 160 microsegundos.-
//-----MUEVE CURSOR PARA HACER UN ESPACIO ------------------
//-----prepara para mandar comandos ------------------------
output_low(PIN_A1); // RS = 0; Poner a negativo la señal de 'RS' (Envio de comando)
output_low(PIN_A2); // R_W = 0;
output_b(0b00010100); // desplaza el cursor hacia la derecha
strobe_enable(); // espera más de 160 microsegundos.-
// --------- prepara para mandar caracteres ----------------------------------
output_high(PIN_A1); // RS = 1; Poner a positivo la señal de 'RS' (Envio de un dato)
output_low(PIN_A2); // R_W = 0;
//-----ESCRIBE TODO ------------------------
output_b(0b01010100); // letra T. Enviar el byte de datos (8 bits en los pines D0 a D7)
strobe_enable(); // espera más de 160 microsegundos.-
output_b(0b01001111); // letra O. Enviar el byte de datos (8 bits en los pines D0 a D7)
strobe_enable(); // espera más de 160 microsegundos.-
output_b(0b01000100); // letra D. Enviar el byte de datos (8 bits en los pines D0 a D7)
strobe_enable(); // espera más de 160 microsegundos.-
output_b(0b01001111); // letra O. Enviar el byte de datos (8 bits en los pines D0 a D7)
strobe_enable(); // espera más de 160 microsegundos.-
//-----MUEVE CURSOR PARA HACER UN ESPACIO ------------------
//-----prepara para mandar comandos ------------------------
output_low(PIN_A1); // RS = 0; Poner a negativo la señal de 'RS' (Envio de comando)
output_low(PIN_A2); // R_W = 0;
output_b(0b00010100); // desplaza el cursor hacia la derecha
strobe_enable(); // espera más de 160 microsegundos.-
// --------- prepara para mandar caracteres ----------------------------------
output_high(PIN_A1); // RS = 1; Poner a positivo la señal de 'RS' (Envio de un dato)
output_low(PIN_A2); // R_W = 0;
//-----ESCRIBE PIC ------------------------
output_b(0b01010000); // letra P. Enviar el byte de datos (8 bits en los pines D0 a D7)
strobe_enable(); // espera más de 160 microsegundos.-
output_b(0b01001001); // letra I. Enviar el byte de datos (8 bits en los pines D0 a D7)
strobe_enable(); // espera más de 160 microsegundos.-
output_b(0b01000011); // letra C. Enviar el byte de datos (8 bits en los pines D0 a D7)
strobe_enable(); // espera más de 160 microsegundos.-
//-----prepara para mandar comandos ------------------------
output_low(PIN_A1); // RS = 0; Poner a negativo la señal de 'RS' (Envio de comando)
}
//-----definición de funciones--------------------------------------
void strobe_enable(void)
{
output_high(PIN_A0); //E=1; // ACTIVA la señal de 'E' (a positivo)
delay_ms(25);
output_low(PIN_A0); //E=0; // Desactivar la señal de 'E' (a negativo)
}
-
Me alegro que hayas podido solucionar tu problema, y que mejor que te dieras cuenta del error, eso te servira como experiencia :mrgreen:
-
Poseidon20:
Gracias por el aliento.
:-/ voy a modificar la librería lcd.c para poder setear los tiempos de espera.
Luego te cuento.-
Jukinch