TODOPIC
Microcontroladores PIC => Lenguaje C para microcontroladores PIC => Mensaje iniciado por: mrgse en 11 de Mayo de 2009, 12:49:28
-
(Nose porque el anterior no se ha publicado)
Estoy buscando por el foro un programa de LCD pero todos los k veo son demasiado complejos. Yo simplemente quiero que se vea en mi LCD un : "HOLA"
Uso un PIC16F877, conectado al LCD por el puerto B.
El programa que tengo escrito es este, pero no se como simularlo y poder ver si funciona. A ver si podeis recomendarme algun simulador o almenos decir si es correcto.
#include "16F877.h"
#use delay(clock=4000000)
#include "lcd.c"
#define use_portb_lcd TRUE
void main(void)
{
set_tris_b(0x00);
lcd_init();
lcd_putc("HOLA";
}
A parte, que diferencia hay entre:
lcd_putc("HOLA");
i
printf(lcd_putc,"HOLA",);
Gracias
-
Un buen programa para simular seria el Proteus, aquí en este mismo foro hay bastante información para que comiences con el.
La diferencia entre putc y printf radica en que este ultimo puedes enviarles al lcd variables convertidas a string:
printf:Te permite especificar el formato en que queremos mostrar los datos.
Parámetros: Cadena de formato (cómo se visualizan los datos) y Lista de valores (datos que se visualizan)
Formatos:
%d Entero con signo.
%u Entero sin signo.
%x Hexadecimal minúscula.
%X Hexadecimal mayúscula.
%f Flotante
Ejemplo:
Hola
Data=10;
printf(lcd_putc
,“El valor es
: %u”
,Data
);
El valor es : 10
Data=10;
printf(lcd_putc
,“El valor es
: %03u”
,Data
);
El valor es : 010
Data=3.12;
printf(lcd_putc
,“El valor es
: %1.2f”
,Data
);
El valor es : 3.12
-
Hola
Te puedes ahorrar la parte de la configuración del trisb, ya se hace en la librería. Ese programa no te va a funcionar porque lcd_putc solo envía caracter por caracter, para enviar cadenas debes usar printf, esa es la diferencia.
#include "16F877.h"
#use delay(clock=4000000)
#include "lcd.c"
#define use_portb_lcd TRUE
void main(void)
{
delay_ms(1000);
lcd_init();
printf(lcd_putc,"HOLA");
}
jeje Suky me ganó la respuesta :P
-
Ese programa no te va a funcionar porque lcd_putc solo envía caracter por caracter, para enviar cadenas debes usar printf, esa es la diferencia.
Migsantiago, lcd_putc no envia caracter por caracter. Y un lcd_putc("Hola"); funciona bien (En la libreria flex_lcd :mrgreen:).
-
Ah bueno, modificando librerías todo se puede :D
En la nueva lcd.c original de CCS 4.088 quién sabe si se pueda. :?: :?: :?:
-
Muchas gracias por las respuestas!!!!!!!
-
Lcd_putc() deberia funcionar bien.
Lo que debes tener en cuenta es siempre borrar el display antes de enviar el primer mensaje (la vieja libreria hace un borrado del display al final de Lcd_init() ).
Esto debe ser costumbre para adaptarlo a todas las marcas, ya que algunos al hacer el reset lo hacen y otros no... :mrgreen:
-
Lo que debes tener en cuenta es siempre borrar el display antes de enviar el primer mensaje...
Es fundamental lo que dice mi colega, sino el display se cuelga. Si te fijas la hoja de datos de los display en la maquina de estado de inicialización, generalmente no figura , pero te aseguro que sino borras no funciona porque hice la programación de una rutina de inicialización a pulmón. Y no por masoquista, sino porque era para un micro cypress y no te lo dan resuelto como en los pics.
Si te interesa te dejo las funciones que hice, pero son para cypress, pero supongo que la idea puede servier:
Funciones para Display Gráfico (http://www.kiteducativo.com.ar/foro/index.php?topic=7.0)
-
Hola, con este programa:
#include "16F877.h"
#use delay(clock=4000000)
#include "lcd.c"
#define use_portb_lcd TRUE
void main(void)
{
delay_ms(1000);
lcd_init();
printf(lcd_putc,"HOLA");
}
al darle tension al circuito, la primera linea del LCD marca todos los cuadros de negro, y la segunda no hace nada. No entiendo ... :S
que hago mal??
Uso el pic 16f877, tengo conectado: los dos Vdd a 5 V
los dos Vss a 0 V
Entre Vdd i Vss cond de 100nF
Entre OSC1 i OSC2 un cristal de 4Mhz, a la vez con dos cond de 15pF que van a tierra.
RB7 del PIC a DB7 del LCD
RB6 del PIC a DB6 del LCD
RB5 del PIC a DB5 del LCD
RB4 del PIC a DB4 del LCD
RB2 del PIC a R/W del LCD
RB1 del PIC a RS del LCD
RB0 del PIC a E del LCD
El LCD lo alimento correctamente y con buen contraste ya que en la primera linea veo todos los cuadros en negro.
-
Acabo de desconectar el PIC del circuito, i le doy tension al LCD tan solo, y la primera linea sigue poniendose oscura, (los cuadros). Nose si servira de ayuda esta informacion
EL PIC funciona correctamente pork he realizado un programa que encienda y apague un LED y lo he probado practicamente y funciona.
-
Podras pegar aqui una copia de la libreria lcd.c que estas utilizando??
Es para saber que pines vienen configurados alli... :lol:
-
UPPSS!!
Prueba a cambiar el orden de tus intrucciones asi:
#define use_portb_lcd TRUE
#include "lcd.c"
Puede ser por alli que no funciona...
-
///////////////////////////////////////////////////////////////////////////
//// LCDD.C ////
//// Driver for common LCD modules ////
//// ////
//// lcd_init() Must be called before any other function. ////
//// ////
//// lcd_putc(c) Will display c on the next position of the LCD. ////
//// The following have special meaning: ////
//// \f Clear display ////
//// \n Go to start of second line ////
//// \b Move back one position ////
//// ////
//// lcd_gotoxy(x,y) Set write position on LCD (upper left is 1,1) ////
//// ////
//// lcd_getc(x,y) Returns character at position x,y on LCD ////
//// ////
///////////////////////////////////////////////////////////////////////////
//// (C) Copyright 1996,2003 Custom Computer Services ////
//// This source code may only be used by licensed users of the CCS C ////
//// compiler. This source code may only be distributed to other ////
//// licensed users of the CCS C compiler. No other use, reproduction ////
//// or distribution is permitted without written permission. ////
//// Derivative programs created using this software in object code ////
//// form are not restricted in any way. ////
///////////////////////////////////////////////////////////////////////////
// As defined in the following structure the pin connection is as follows:
// D0 enable
// D1 rs
// D2 rw
// D4 D4
// D5 D5
// D6 D6
// D7 D7
//
// LCD pins D0-D3 are not used and PIC D3 is not used.
// Un-comment the following define to use port B
//#define use_portb_lcd TRUE
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;
#if defined use_portb_lcd
#locate lcd = getenv("sfr:PORTB") // This puts the entire structure over the port
#define set_tris_lcd(x) set_tris_b(x)
#else
#locate lcd = getenv("sfr:PORTD") // This puts the entire structure over the port
#define set_tris_lcd(x) set_tris_d(x)
#endif
#define lcd_type 2 // 0=5x7, 1=5x10, 2=2 lines
#define lcd_line_two 0x40 // LCD RAM address for the second line
BYTE const LCD_INIT_STRING[4] = {0x20 | (lcd_type << 2), 0xc, 1, 6};
// These bytes need to be sent to the LCD
// to start it up.
// The following are used for setting
// the I/O port direction register.
struct lcd_pin_map const LCD_WRITE = {0,0,0,0,0}; // For write mode all pins are out
struct lcd_pin_map const LCD_READ = {0,0,0,0,15}; // For read mode data pins are in
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(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);
lcd.rw = 0;
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.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[i]);
}
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;
}
}
char lcd_getc( BYTE x, BYTE y) {
char value;
lcd_gotoxy(x,y);
while ( bit_test(lcd_read_byte(),7) ); // wait until busy flag is low
lcd.rs=1;
value = lcd_read_byte();
lcd.rs=0;
return(value);
}
-
UPPSS!!
Prueba a cambiar el orden de tus intrucciones asi:
#define use_portb_lcd TRUE
#include "lcd.c"
Puede ser por alli que no funciona...
Deberías hacer lo que te propone MGLSOFT o directamente habilitarlo en la librería, fíjate que tiene la opción.
// Un-comment the following define to use port B
//#define use_portb_lcd TRUE
-
He quitado las // de la libreria, pero sigue pasando lo mismo.
-
Perdona, cometí dos omisiones en tu programa.
La primera ya te la comentaron, debes declarar primero el puerto y después invocar el lcd.c.
Y la segunda es que falta por completo la declaración de los fusibles del pic :D Disculpa por no fijarme, usa estos...
#include "16F877.h"
#use delay(clock=4000000)
#fuses xt,nowdt,noput,nobrownout,nolvp,noprotect
#define use_portb_lcd TRUE
#include "lcd.c"
El pic ni siquiera estaba funcionando porque no estaba declarada la forma en que entraba el oscilador :mrgreen:
-
Perdona, cometí dos omisiones en tu programa.
La primera ya te la comentaron, debes declarar primero el puerto y después invocar el lcd.c.
Y la segunda es que falta por completo la declaración de los fusibles del pic :D Disculpa por no fijarme, usa estos...
#include "16F877.h"
#use delay(clock=4000000)
#fuses xt,nowdt,noput,nobrownout,nolvp,noprotect
#define use_portb_lcd TRUE
#include "lcd.c"
El pic ni siquiera estaba funcionando porque no estaba declarada la forma en que entraba el oscilador :mrgreen:
(http://img254.imageshack.us/img254/7936/auch.gif) Yo tampoco me dí cuenta!
-
Con el siguiente programa:
#include "16F877.h"
#use delay(clock=4000000)
#fuses xt,nowdt,noput,nobrownout,nolvp,noprotect
#define use_portb_lcd TRUE
#include "lcd.c"
void main(void)
{
delay_ms(1000);
lcd_init();
printf(lcd_putc,"HOLA");
}
Sigue pasandome lo mismo. Todas las connexiones del LCD estan a 5V exceptuando la de GND i la de control de contraste. Incluso si desconecto las entradas de datos! Necesito ayuda urgente!! GRACIAS!!
-
Hola acabo de ver que en mi libreria lcd.c en los comentarios pone lcdd.c, i dice que los pines van al puerto D, puede ser eso?¿ Alguien me puede pasar una libreria de lcd que trabaje con el puerto B i con los pines que he escrito en post anteriores?
Incluso si podeis pasarme un programa muy senzillo que tan solo ponga Hola en el LCD. Eso si, incluir la libreria, porque me temo que es allio donde esta el error. Gracias!
-
FINALMENTE: FUNCIONO! Nose porque porque he usado el mismo programa que he puesto anteriormente...pero funciono!
-
mrgse si usaste una protoboard probablemente hubo una mala conexion de un pin del pic o del lcd,
si funciona en proteus funciona en la realidad.
-
Vaya qué bien :D
Otro cliente Todopic satisfecho. 8)
-
Por cierto, siempre se conectan las paas de la D4 a la D7 del LCD, pero se podria conectar de la D0 a la D3?? Como??
-
No, en modo a 4 bits solo se usan desde D4 a D7, D0 a D7 es para modo a 8 bits...
-
hola amigos
MGLSOFT el amigo mrgse, se refiere que si es posible enviar datos en vez de D4 a d7 la parte alta del puesto B, hacerlo con laparte baja usando D0 a D3, y si es asi como se hace.
Creo que bastaria con cambiar los pines de nombre en la parte de la definicioón, o si tiene una función en la cual le pasas los pines se los cambias ahi, vosotrosque opinais.
Un saludo
-
Si miras del lado del Pic podes usar los pines que quieras, D0~D3 ó D4~D7, o inclusive pines de éste u otros puertos mezclados.
Si te fijas del lado del LCD, para entrar en modo 4 bits, tenes que usars si o si los pines D4~D7, no hay otra alternativa.
-
Era por parte del LCD, pero si no se puede nada, a usar D4 a D7.