LCD 44780 4-bits para PIC16F, driver y ejemplo.
+3
Risanti
pentax33
arcachofo
7 participantes
Página 1 de 2.
Página 1 de 2. • 1, 2
LCD 44780 4-bits para PIC16F, driver y ejemplo.
Con este driver se puede manejar un LCD compatible con 44780 en modo 4-bits, su funcionamiento es independiente de la velocidad de reloj, que tiene que estar definida en el programa principal: #define FREQ 8000 //para 8MHz.
El caso es que todavía no he conseguido que funcione a 4 MHz, pero lo he probado desde 8 a 20 MHz con PIC16f876A y PIC16F627A, se agradería confirmación de que funciona con otros PIC16F... o de no funciona...claro.
En el driver hay una seción donde se definen los pines a utilizar, la cosa es copiarla, pegarla en el programa principal y ajustar los datos a tus necesidades, además hay información sobre las funciones implementadas. El driver tiene sus propias funciones de retardo, utilizables en el programa principal: espera_ms() y pausa()
Este es el driver (lcd_sdcc_sgr.h):
guardarlo con el nombre: lcd_sdcc_sgr.h. o con otro nombre y cambiar la linea include en el programa principal.
Este es un ejemplo de uso para PIC16F628A, aunque se puede cambiar la defición del pic y los bits de configuración para usarlo con otros PIC16F (lcd_Hola_Mundo.c):
El caso es que todavía no he conseguido que funcione a 4 MHz, pero lo he probado desde 8 a 20 MHz con PIC16f876A y PIC16F627A, se agradería confirmación de que funciona con otros PIC16F... o de no funciona...claro.
En el driver hay una seción donde se definen los pines a utilizar, la cosa es copiarla, pegarla en el programa principal y ajustar los datos a tus necesidades, además hay información sobre las funciones implementadas. El driver tiene sus propias funciones de retardo, utilizables en el programa principal: espera_ms() y pausa()
Este es el driver (lcd_sdcc_sgr.h):
- Código:
/*****************************************************************************
******************************************************************************
**** ****
**** --- DRIVER LDC 44780 4-BITS para PIC16F --- ****
**** ****
******************************************************************************
******************************************************************************
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
FUNCIONES DISPONIBLES:
------------------------------------------------------------------------------
lcd_car() //envia un caracter, ejemplo: lcd_car("A");
lcd_dato() //envía byte, ejemplo: char a= 0xE5; lcd_dato(a); lcd_dato(0xE5)
lcd_comand() //envía comando, ejemplo: lcd_comand(linea2); lcd_comand(0x0E)
lcd_num() //envía número entero (int), ejemplo: lcd_num(1756);
lcd_clear() //borra display.
lcd_init() //inicializa lcd.
espeara_ms() //delay milisegundos, ejemplo: espera_ms(10);
pausa() //delay 4xValor+1 µs, ejemplo: pausa(2); pausa de 9 µs.
********************************************************************************
********************************************************************************
EN EL PROGRAMA PRINCIPAL DONDE VAYA A USAR LAS FUNCIONES LCD
INSERTAR LAS SIGUIENTES LINEAS CON LAS DEFINICIONES DE PUERTO Y RELOJ USADOS:
//---------------------------- PUERTO LCD --------------------------------
//------------------------------------------------------------------------
#define RS RC1 //PIN PARA RS.
#define RW RC2 //PIN PARA RW.
#define EN RC3 //PIN PARA ENABLE.
#define DATOT TRISC //TRIS DE DATOS, PINES 4, 5, 6, 7 DEL PUERTO.
#define DATOP PORTC //PORT DE DATOS, MISMO PUERTO.
#define FREQ 8000 // 8000 KHz = 8 Mhz, LA FRECUENCIA EN KHz.
#include "lcd_sdcc_sgr.h"
********************************************************************************
*******************************************************************************/
//----------------------------- ACCIONES ---------------------------------
//------------------------------------------------------------------------
#define write RW = 0; pausa(u9); DATOT &= 0x0F; pausa(u9)
#define read DATOT |= 0xF0; pausa(u9); RW = 1; pausa(u9)
#define EN0 EN = 0; pausa(u9)
#define EN1 EN = 1; pausa(u9)
//--------------------------- COMANDOS LCD -------------------------------
//------------------------------------------------------------------------
#define clear 0x01 // Clear Display
#define home 0x02 // Cursor a Home
#define normal 0x06 // Normal
#define rev 0x04 // Normal-reverse
#define scroll 0x07 // con scroll
#define scroll_rev 0x05 // Reverse
#define d8_bit 0x38 // 8 bit 2 lineas ( 5x7 font )
#define d4_bit 0x28 // 4 bit 2 lineas ( 5x7 font )
#define reset 0x30 // Reset
#define dis_on 0x0C // Display on modo 2 lineas
#define dis_off 0x08 // Display off
#define linea1 0x80 // Linea 1 posicion 1
#define linea2 0xC0 // Line 2 posicion 1
#define cursor_on 0x0E // Cursor on
#define cursor_off 0x0C // Cursor off
#define blink_on 0x0F // Cursor blink
#define cursor_der 0x14 // Mover cursor derecha
#define cursor_izq 0x10 // Mover cursor izquierda
#define display__der 0x1C // Scroll display derecha
#define display__izq 0x18 // Scroll display izquierda
#define cg_addr 0x40 //
//----------------------- CONFIGURAR VARIABLES ---------------------------
//------------------------------------------------------------------------
unsigned char d;
unsigned char n;
unsigned char coms = FREQ / 4000;
unsigned char u9 = FREQ / 2000;
unsigned char pa = FREQ / 400;
//----------------------------- FUNCIONES --------------------------------
//------------------------------------------------------------------------
void pausa( unsigned char a )
{ a; //tiempo = (4a + 1)µs a>=2, para 4MHz
_asm // "a" ya está en w
sublw 1
bucle:
addlw 1
btfss STATUS,0
goto bucle
_endasm;
}
void espera_ms( unsigned int ms )
{
ms = ms * coms;
while (ms > 0 )
{
pausa(247);
ms--;
}
}
char lcd_read()
{
read; //modo lectura
EN1;
d = DATOP & 0xF0; //lee nibble alto
EN0;
EN1;
d |= DATOP >> 4; //lee nibble bajo
EN0;
return d;
}
char lcd_busy()
{
RS = 0;
lcd_read();
d = d & 0x80; //aisla bit busy
if( d == 0x80 ) //comprueba si está ocupado
return(1);
else
return(0);
}
void write_n( char dat )
{
write; //modo escritura
DATOP &= 0x0F;
DATOP |= dat & 0xF0; //escribe nibble alto
EN1;
EN0;
dat <<= 4;
DATOP &= 0x0F;
DATOP |= dat & 0xF0; //escribe nibble bajo
EN1;
EN0;
pausa(pa);
}
void lcd_dato( char dato )
{
while( lcd_busy() == 1 ); //leer bit busy hasta que sea 0
RS = 1; //modo datos
write_n( dato );
}
void lcd_comand( char comand )
{
RS = 0; //modo comandos
write_n( comand );
}
void lcd_clear()
{
lcd_comand( clear );
lcd_comand( home );
}
void lcd_init( void )
{
DATOT = 0; //todo a salidas
DATOP = 0; //todo a 0
espera_ms(20);
write_n( reset ); //secuancia de reset
espera_ms(10);
write_n( reset );
pausa(pa);
write_n( reset );
pausa(u9); //secuencia de inicio:
lcd_comand( d4_bit ); //0x28 modo 4 bits 2 lineas
lcd_comand( normal ); //0x06 entrada normal hacia adelante
lcd_comand( dis_on ); //0x0c display on
lcd_comand( linea1 ); //0x80 linea 1 posicion 1
}
void lcdh( char a )
{
if (a > 9)
a += 55;
else
a += 48;
lcd_dato(a);
}
void lcd_hex( char nb )
{
char n;
n = ( nb >> 4 ) & 0x0f;
lcdh(n);
n = nb & 0x0f;
lcdh(n);
}
void lcd_num( int num )
{
lcd_hex( num >> 8 );
lcd_hex( num & 0xff );
}
void lcd_car( unsigned char *car )
{
char n = 0;
while( car[n])
{
lcd_dato( car[n] );
n++;
}
}
guardarlo con el nombre: lcd_sdcc_sgr.h. o con otro nombre y cambiar la linea include en el programa principal.
Este es un ejemplo de uso para PIC16F628A, aunque se puede cambiar la defición del pic y los bits de configuración para usarlo con otros PIC16F (lcd_Hola_Mundo.c):
- Código:
/*------------------------- lcd_Hola_Mundo.c --------------------------*/
/* ----------------------------------------------------------------------- */
/* Template source file generated by piklab */
#include //nomre del pic a usar
/* ----------------------------------------------------------------------- */
/* Bits de configuración: adapte los parámetros a su necesidad */
typedef unsigned int word;
word at 0x2007 CONFIG = _WDT_OFF & _PWRTE_ON & _HS_OSC & _MCLRE_OFF & _BOREN_OFF & _LVP_OFF & _DATA_CP_OFF & _CP_OFF;
//--------------------------- DEFINICIONES -------------------------------
//------------------------------------------------------------------------
#define RS RB1
#define RW RB2
#define EN RB3
#define DATOT TRISB
#define DATOP PORTB
#define FREQ 8000 // 8 Mhz
#include "lcd_sdcc_sgr.h"
//------------------------------------------------------------------------
void main()
{
char frase[] = "Hola";
char lin[] = "Mundo";
unsigned char n;
lcd_init();
while(1)
{
lcd_clear();
lcd_comand( linea1 );
espera_ms(1000);
n = 0;
while( frase[n] )
{
lcd_dato(frase[n]);
n++;
}
espera_ms(1000);
lcd_comand( linea2 );
n = 0;
while( lin[n] )
{
lcd_dato(lin[n]);
n++;
}
espera_ms(1000);
}
}
arcachofo- Participante Activo
- Mensajes : 91
Fecha de inscripción : 26/11/2008
Rutina de LDC hd44780
Hola gente i felices fiestas
Por fin he podido dedicar un tiempo a mi hobby i he localizado esta libreria de funcionamiento de un LCD dejo el enlace para que la visiten.
http://www.warpedlogic.co.uk/?q=node/10
Seguire investigando.
Por fin he podido dedicar un tiempo a mi hobby i he localizado esta libreria de funcionamiento de un LCD dejo el enlace para que la visiten.
http://www.warpedlogic.co.uk/?q=node/10
Seguire investigando.
pentax33- Participante
- Mensajes : 11
Fecha de inscripción : 28/11/2008
Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.
Hola a todos..
Estoy probando esta libreria, consulta la has probado con un osc de 4mhz.. la estoy probando con un pic. 16f876A, pero no consigo que trabaje correctamente. Pero aun estoy revisando para descartar aun error externo (de esos errores no previstos)..
RiSanti
Estoy probando esta libreria, consulta la has probado con un osc de 4mhz.. la estoy probando con un pic. 16f876A, pero no consigo que trabaje correctamente. Pero aun estoy revisando para descartar aun error externo (de esos errores no previstos)..
RiSanti
Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.
Estoy probando esta libreria, consulta la has probado con un osc de 4mhz..
No... precisamente, a 4 MHz no me funcionaba y no sé porqué, seguramente problemas algún tiempo, pero nunca llegué a encontrar solución, recuerdo que hice bastantes pruebas, pero no hubo manera...
Pero desde 8 a 20 MHz prové con varios relojes y funcionaba bién:
El caso es que todavía no he conseguido que funcione a 4 MHz, pero lo he probado desde 8 a 20 MHz con PIC16f876A y PIC16F627A,
Quizás puedas probarlo a mayor velocidad.
En el enlace que puso pentax33 el un mensaje anterior hay una librería que es para pic18f, pero está muy bién comentada, con los tiempos necesarios en cada momento, quizás habría que repasar el código y ver donde no se cumplen los tiempos en el caso de 4MHz.
Saludos.
Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.
Gracias...
Por lo menos mi problema le a pasado a otro.. es un consuelo.. para saber que va por el codigo el problema, si debe ser algo con los tiempos, Consulta? sabes mas menos cuales son los pasos para iniciar LCd en 4bit, he encontrado algo de informacion ,ademas para despues enviar datos de 8 bit, entiendo que se envia primero los 4bit de mayor peso y despues los otros pero como se diferencias, nose si hay que esperar un tiempo o existe algun pin como de sincronismo, al parece es con En (segun la libreria). pero no estoy seguro..
Voy a hacer lo mejor .. que es pruebas tras pruebas..
RiSanti
Por lo menos mi problema le a pasado a otro.. es un consuelo.. para saber que va por el codigo el problema, si debe ser algo con los tiempos, Consulta? sabes mas menos cuales son los pasos para iniciar LCd en 4bit, he encontrado algo de informacion ,ademas para despues enviar datos de 8 bit, entiendo que se envia primero los 4bit de mayor peso y despues los otros pero como se diferencias, nose si hay que esperar un tiempo o existe algun pin como de sincronismo, al parece es con En (segun la libreria). pero no estoy seguro..
Voy a hacer lo mejor .. que es pruebas tras pruebas..
RiSanti
Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.
Mira, aquí tienes información sobre la inicialización: http://www.geocities.com/dinceraydin/lcd/initalization.htm
y aquí más sobre lcd (la anterior està dentro de esta): http://www.geocities.com/dinceraydin/lcd/index.html
Pero hay al menos dos maneras de inicializar, la que se usa el la librería de este tema (3 resets) es distinta a la que usa el tipo del enlace del mensaje de Pentax.
Respecto a los nibles, yo no le puse ninguna pausa, el tema es que funciona con relojes rápidos, pero nó con 4 MHz.
Sería cuestión de ver el cursor, no recuerdo si después de inicializar estaba en modo cursor parpadeante o no.. sinó se puede poner (hay un comando)
Quizás hacer un programa que solo inicialice o que espere un tiempo antes de mandar nada y ver si el cursor parpadea.. digo para ver si inicia bién o no.
Saludos.
y aquí más sobre lcd (la anterior està dentro de esta): http://www.geocities.com/dinceraydin/lcd/index.html
Pero hay al menos dos maneras de inicializar, la que se usa el la librería de este tema (3 resets) es distinta a la que usa el tipo del enlace del mensaje de Pentax.
Respecto a los nibles, yo no le puse ninguna pausa, el tema es que funciona con relojes rápidos, pero nó con 4 MHz.
- Código:
void write_n( char dat )
{
write; //modo escritura
DATOP &= 0x0F;
DATOP |= dat & 0xF0; //escribe nibble alto
EN1;
EN0;
dat <<= 4;
DATOP &= 0x0F;
DATOP |= dat & 0xF0; //escribe nibble bajo
EN1;
EN0;
pausa(pa);
}
Si... el tema es que no recuerdo.. si inicializaba bien y fallaba al mandar caracteres o ni siquiera inicializaba.Voy a hacer lo mejor .. que es pruebas tras pruebas..
Sería cuestión de ver el cursor, no recuerdo si después de inicializar estaba en modo cursor parpadeante o no.. sinó se puede poner (hay un comando)
Quizás hacer un programa que solo inicialice o que espere un tiempo antes de mandar nada y ver si el cursor parpadea.. digo para ver si inicia bién o no.
Saludos.
Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.
Gracias por la informacion.. Segun pruebas que he realizado con esta libreria, tengo problemas con lo que respecta la iniciación
Si Correcto segun lo que analizo de esta lib. realiza tres reset y ademas manipula el bit EN. cada vez que los envia
Pero despues de ejecutar Clear y Enviar un Cadena Caracteres para que lo imprima en Linea 1 , este solo imprime caracteres sin sentido. Pero lo curioso despues de hacer esto , procedo a Resetear el Pic (Pulsador entre MCLR y GND). el Lcd comienza a trabajar normalmente. por esto pienso que hay algún problema con algún tiempo o algo en la Iniciación o otra cosa rara.
Bueno ademas he probado iniciarlo de otra manera como modificando la lib.
Bueno seguire probando y revisando, estoy seguro que hay algun detalle que aun no visualizo..
Atte.
RiSanti
- Código:
lcd_init();
Si Correcto segun lo que analizo de esta lib. realiza tres reset y ademas manipula el bit EN. cada vez que los envia
- Código:
void lcd_init( void )
{
DATOT = 0; //todo a salidas
DATOP = 0; //todo a 0
espera_ms(20);
write_n( reset ); //secuencia de reset envia 30h ,en cada reset se ejecuta
// RW = 0; pausa(u9); DATOT &= 0x0F; pausa(u9)
espera_ms(10);
write_n( reset );
pausa(pa);
write_n( reset );
pausa(u9); //secuencia de inicio:
lcd_comand( d4_bit ); //0x28 modo 4 bits 2 lineas
lcd_comand( normal ); //0x06 entrada normal hacia adelante
lcd_comand( dis_on ); //0x0c display on
lcd_comand( linea1 ); //0x80 linea 1 posicion 1
}
Pero despues de ejecutar Clear y Enviar un Cadena Caracteres para que lo imprima en Linea 1 , este solo imprime caracteres sin sentido. Pero lo curioso despues de hacer esto , procedo a Resetear el Pic (Pulsador entre MCLR y GND). el Lcd comienza a trabajar normalmente. por esto pienso que hay algún problema con algún tiempo o algo en la Iniciación o otra cosa rara.
Bueno ademas he probado iniciarlo de otra manera como modificando la lib.
- Código:
void lcd_init( void )
{
DATOT = 0; //todo a salidas
DATOP = 0; //todo a 0
espera_ms(20);
EN0;
for(i=0 ;i < 3; i++) // 3 pero solo a los bit d4-d7 durante muchos ms
{
DATOP &= 0x0F;
DATOP |= 0x30 & 0xF0;
espera_ms(20);
}
lcd_comand( d4_bit ); //0x28 modo 4 bits 2 lineas
lcd_comand( normal ); //0x06 entrada normal hacia adelante
lcd_comand( dis_on ); //0x0c display on
lcd_comand( linea1 ); //0x80 linea 1 posicion 1
}
Bueno seguire probando y revisando, estoy seguro que hay algun detalle que aun no visualizo..
Atte.
RiSanti
Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.
Pero lo curioso despues de hacer esto , procedo a Resetear el Pic
(Pulsador entre MCLR y GND). el Lcd comienza a trabajar normalmente.
Esto me hace pensar que el problema no es de la secuencia: si funciona bién despues de un reset del PIC, entonces quizás el problema es otro.. quizás un tema de voltajes: En el primer enlace de mi mensaje anterior habla de eso y dice que con los 3 reset se debería solucionar esto; el caso es que la tensión tiene que estar en un punto estable > 4.5 V (o algo así), si la fuente que usas tarda un poco en alcanzar la tensión nominal, o el circuito tiene condensadores grandes... o lo que sea que retrase un poco la tensión estable, quizás falle...
No sé.. pero por probar, se podría probar a inicializar el LCD después de un par de segundos (o lo que sea) para estar seguros de que no hay problemas de este tipo.
Si el problema es de este tipo, quizás habria que subir el primer delay:
- Código:
void lcd_init( void )
{
DATOT = 0; //todo a salidas
DATOP = 0; //todo a 0
espera_ms(20); //*******************ESTE
Otra cosa: no sé si es cuestión de velocidades (funciona con 8-20 MHZ pero no con 4MHz) o cuestion de oscilador interno/externo; otra cosa a probar sería reloj externo de 4MHz.
Saludos.
Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.
Gracias Pikitin.. por sus consejos ...
Es bastante bueno compartir experiencias y opiniones, mas aun ya que estos temas no son comunes donde vivo..
Bueno, sobre esperar que la tension del LCD se estabilice lo he prodabo hasta puntos absurdos osea por ejemplo. Todos los pines que van al LCd E.RW.Rs, d4-d7 en 0 y espero como 10seg y recién comienzo a función de iniciar LCD. pero el mismo efecto. ademas probé con alimentar antes el LCD y después el Pic para ver si era un tema de voltaje pero nada.. ademas he probado con ejecutar la rutina iniciación cada vez que pulso un pulsador y esto responde pero no al primer intento.
Bueno estoy ya un poco frustrado.. pero son por estas situaciones que me gusta la electrónica, sigo buscando una una respuesta a este problema..
Atte.
RiSanti
Es bastante bueno compartir experiencias y opiniones, mas aun ya que estos temas no son comunes donde vivo..
Bueno, sobre esperar que la tension del LCD se estabilice lo he prodabo hasta puntos absurdos osea por ejemplo. Todos los pines que van al LCd E.RW.Rs, d4-d7 en 0 y espero como 10seg y recién comienzo a función de iniciar LCD. pero el mismo efecto. ademas probé con alimentar antes el LCD y después el Pic para ver si era un tema de voltaje pero nada.. ademas he probado con ejecutar la rutina iniciación cada vez que pulso un pulsador y esto responde pero no al primer intento.
- Código:
if (RB5==0){
delay_ms(100);
lcd_init();
}
Bueno estoy ya un poco frustrado.. pero son por estas situaciones que me gusta la electrónica, sigo buscando una una respuesta a este problema..
Atte.
RiSanti
Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.
Ademas el LCD que estoy usando no es un HD 44780, sino un GMD1602H, segun el Datasheet es compatible el protocolo de comunicacion...
Risanti.
Risanti.
Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.
Quizás esto te pueda ser util: http://www.8051projects.net/lofiversion/t16483/Problem-with-LCD-1602.html
Usa el GMD1602B y sin librería, así que puedes ver la rutina de inicio (la última es la que dice que funciona).
Usa el GMD1602B y sin librería, así que puedes ver la rutina de inicio (la última es la que dice que funciona).
Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.
Disculpa por no seguir con este tema. Básicamente mi trabajo me quita mucho tiempo.. jjaaj pero para esta semana retome este tema básicamente con otro LCD 16x02 que compre. mira lo raro es que con este display funciona como debería funcionar. la libreria es operativa , creo que el otro display quizá tenga algun daño, aunque solo es durante la iniciación ya que se se intenta reiteradas veces el lcd se inicia y trabaja normalmente. raro..
bueno por lo menos tengo una que funciona bien.. jajaaj
atte.
RiSanti
bueno por lo menos tengo una que funciona bien.. jajaaj
atte.
RiSanti
Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.
Ok.. gracias por la información.
Por cierto.. te ha funcionado a 4Mhz??
Con oscilador interno o externo??
Saludos.
Por cierto.. te ha funcionado a 4Mhz??
Con oscilador interno o externo??
Saludos.
Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.
Bueno pikitin..
Estoy usando Pic16f876 a 4MHZ sin problemas.. Gracias
Estoy usando Pic16f876 a 4MHZ sin problemas.. Gracias
Problemas al compilar
Hola,
Al intentar compilar la librería me da un error que no he conseguido encontrar qué significa.
Estoy utilizando un 16F84A y he puesto los fuses de este modelo
La versión de SDCC es la siguiente:
SDCC : avr/pic16/pic14/xa51 2.8.0 #5117 (Jun 2 2008) (UNIX)
Al intentar compilar la librería me da un error que no he conseguido encontrar qué significa.
- Código:
message: using default linker script "/usr/share/gputils/lkr/16f84a.lkr"
warning: relocation of section "UDL__mulint_0" failed, relocating to a shared memory location
error: linker script has no definition that matches the type of section "UDL__mulint_0"
Estoy utilizando un 16F84A y he puesto los fuses de este modelo
- Código:
#include <pic16f84a.h>
typedef unsigned int word;
word at 0x2007 CONFIG = _HS_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF;
La versión de SDCC es la siguiente:
SDCC : avr/pic16/pic14/xa51 2.8.0 #5117 (Jun 2 2008) (UNIX)
mentes- Nuevo Usuario
- Mensajes : 9
Fecha de inscripción : 01/10/2010
Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.
Hola mentes.
Es un error del linker, pero creo que solo pasa con 16f84 y 16f84a; prueba a compilarlo con otro pic para confirnarlo.
El fallo es de gputils, googlea un poco a ver que encuentras.
Saludos.
Es un error del linker, pero creo que solo pasa con 16f84 y 16f84a; prueba a compilarlo con otro pic para confirnarlo.
El fallo es de gputils, googlea un poco a ver que encuentras.
Saludos.
Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.
Efectivamente cambiando el modelo a la hora de ejecutar el compilador desaparece el error. Además del 16F84 también ocurre con 16C711 que es equivalente al 16F84 en cuanto a Memoria, Ram y número de I/O.
He compilado otros programas para el 16F84 así que el problema está en esta librería. ¿Tienes idea que parte del código es la que produce el error?
También he probado a grabar el .hex compilado con otros modelos, y el LCD no inicia, supongo que en este caso el problema es por generar un .hex que no es para un 16F84.
He conseguido iniciar el LCD con la siguiente librería, pero soy incapaz de escribir algo coherente, sólo salen letras y símbolos aleatorios. No tengo muy claro como ejecutar la función para que escriba correctamente.
Y la función main() que yo he añadido es:
* Para ahorrar espacio he eliminado algunos comentarios del código, el autor de la librería es http://sergiols.blogspot.com/
He compilado otros programas para el 16F84 así que el problema está en esta librería. ¿Tienes idea que parte del código es la que produce el error?
También he probado a grabar el .hex compilado con otros modelos, y el LCD no inicia, supongo que en este caso el problema es por generar un .hex que no es para un 16F84.
He conseguido iniciar el LCD con la siguiente librería, pero soy incapaz de escribir algo coherente, sólo salen letras y símbolos aleatorios. No tengo muy claro como ejecutar la función para que escriba correctamente.
- Código:
#ifndef LCD_H
#define LCD_H
#define LCD_DATA PORTB // Puerto de datos
#define LCD_DATA_TRIS TRISB // Control del puerto de datos
#define LCD_RS RB2 // Modo
#define LCD_ENABLE RB3 // Habilitación/deshab. en envíos de datos al lcd.
#define LCD_CLEAR 0x01 // Clear Display
#define LCD_HOME 0x02 // Cursor a Home
#define LCD_NORMAL 0x06 // Cursor en modo incrementar.
#define LCD_REV 0x04 // Normal-reverse
#define LCD_SCROLL 0x07 // Usa scroll
#define LCD_SCROLL_REV 0x05 // Reverse
#define LCD_D8_BIT 0x38 // 8 bit 2 lineas ( 5x7 font )
#define LCD_D4_BIT_CONF 0x20 // 4 bit
#define LCD_D4_BIT 0x28 // 4 bit 2 lineas ( 5x7 font )
#define LCD_RESET 0x30 // Reset
#define LCD_DIS_ON 0x0C // Display on modo 2 lineas
#define LCD_DIS_OFF 0x08 // Display off
#define LCD_LINE1 0x80 // Linea 1 posicion 1
#define LCD_LINE2 0xC0 // Linea 2 posicion 1
#define LCD_CURSOR_ON 0x0E // Cursor on
#define LCD_CURSOR_OFF 0x0C // Cursor off
#define LCD_BLINK_ON 0x0F // Cursor blink
#define LCD_CURSOR_DER 0x14 // Mover cursor derecha
#define LCD_CURSOR_IZQ 0x10 // Mover cursor izquierda
#define LCD_DISPLAY__DER 0x1C // Scroll display derecha
#define LCD_DISPLAY__IZQ 0x18 // Scroll display izquierda
#define LCD_CHARMODE 0x01
#define LCD_COMMANDMODE 0x00
void lcd_send_quartet( char mode, char dato );
void lcd_send( char mode, char dato );
void lcd_init (void);
void lcd_message ( char * mess );
char lcd_hexa(char a);
#endif
- Código:
#include <pic16f84a.h>
#include "lcd.h"
// tiempo = (5a+1)µs a>=2 basado en micro a 20mhz
void delay_us ( char a ){
a;
_asm // a ya está cargado en el registro w
sublw 1 //(1-a)
bucle:
ADDLW 1
btfss 0x03,0 //test si w=0 carry=1
goto bucle
_endasm;
}
void delay_ms(int ms){
unsigned int j;
unsigned int k = ms * 10;
for (j=0; j<k; j++)
delay_us (33); //101µs
}
void lcd_send_quartet( char mode, char dato ){
LCD_RS = mode;
PORTB = dato | (PORTB & 0x0f) ;
LCD_ENABLE = 1;
_asm // delay de 4µs
nop
nop
nop
nop
_endasm;
LCD_ENABLE = 0;
}
void lcd_send( char mode, char dato ){
unsigned int j;
char dat = dato;
LCD_RS = mode;
dat = dato & 0xf0;
PORTB = dat | (PORTB & 0x0f) ;
LCD_ENABLE = 1;
_asm // delay de 4µs
nop
nop
nop
nop
_endasm;
LCD_ENABLE = 0;
dat = ((dato<<4)& 0xf0);
PORTB = dat | (PORTB & 0x0f) ;
LCD_ENABLE = 1;
_asm // delay de 4µs
nop
nop
nop
nop
_endasm;
LCD_ENABLE = 0;
for (j=0; j<30; j++){ // delay de 41µs
_asm
nop
_endasm;
}
}
void lcd_init (void){
LCD_DATA_TRIS &= 0x03;
//LCD_DATA = 0x00;
delay_ms(15);
lcd_send_quartet(LCD_COMMANDMODE, LCD_RESET);
delay_ms(5);
lcd_send_quartet(LCD_COMMANDMODE, LCD_RESET);
delay_us(25);
lcd_send_quartet(LCD_COMMANDMODE, LCD_RESET);
delay_us(25);
lcd_send_quartet(LCD_COMMANDMODE, LCD_D4_BIT_CONF);
delay_us(25);
lcd_send(LCD_COMMANDMODE, LCD_D4_BIT);
delay_us(25);
lcd_send(LCD_COMMANDMODE, LCD_CLEAR);
delay_ms(2);
lcd_send(LCD_COMMANDMODE, LCD_CURSOR_OFF);
delay_ms(2);
lcd_send(LCD_COMMANDMODE, LCD_NORMAL);
delay_us(10);
lcd_send(LCD_COMMANDMODE, LCD_DIS_ON);
delay_us(10);
}
void lcd_message ( char * mess ){
while ( *mess ){
lcd_send(LCD_CHARMODE, *mess ) ;
mess++ ;
}
}
char lcd_hexa(char a){
if (a >9)
a+=55;
else
a+=48;
return a;
}
Y la función main() que yo he añadido es:
- Código:
void main() {
char *m_ptr = "Hola";
lcd_init();
lcd_message(m_ptr);
}
* Para ahorrar espacio he eliminado algunos comentarios del código, el autor de la librería es http://sergiols.blogspot.com/
mentes- Nuevo Usuario
- Mensajes : 9
Fecha de inscripción : 01/10/2010
Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.
Es raro el error este...
Prueba a compilar en "Compilar archivo" con tu archivo.c como ventana activa en vez de "Construir proyecto" a ver que pasa.
Pero es extraño que con la librería de sergiols no haya problema y con esta sí... evidentemente algo pasa con esta. Pero no creo que sea problema de código, además funciona en otros pic.
El error es del linker y no se refiere a ninguna función de la librería lcd, se refiere a la función UDL__mulint_0 que parece ser una funcion de multiplicación de int, pero tampoco es un problema de esa función, sino de que el linker no consigue posicionarla correctamente en memoria y luego no la encuentra cuando tiene que usarla.... o algo así, tampoco controlo mucho como funciona el linker.He compilado otros programas para el 16F84 así que el problema está en esta librería. ¿Tienes idea que parte del código es la que produce el error?
Prueba a compilar en "Compilar archivo" con tu archivo.c como ventana activa en vez de "Construir proyecto" a ver que pasa.
Esa librería solo sirve para 16f84A a 4MHz (es ese el problema?), lo bueno de esta es que puedes adaptarlo a distintas velocidades de reloj.He conseguido iniciar el LCD con la siguiente librería, pero soy incapaz de escribir algo coherente, sólo salen letras y símbolos aleatorios. No tengo muy claro como ejecutar la función para que escriba correctamente.
Pero es extraño que con la librería de sergiols no haya problema y con esta sí... evidentemente algo pasa con esta. Pero no creo que sea problema de código, además funciona en otros pic.
Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.
He compilado varios programas, así que algo tiene este código que al linker no le gusta.
Deduces que utilizo algún IDE, pero compilo y grabo desde la consola.
La librería de sergiols sirve para varios pic, y por ejemplo yo la estoy utilizando con un cristal de 8Mhz.
La ventaja de la sgr es que tiene la opción de Read, está más comentada y hay ejemplos de como utilizar las funciones. Con la de sergiols no he conseguido escribir nada en el LCD y no sé si estoy utilizando mal las funciones o hay otro problema.
Deduces que utilizo algún IDE, pero compilo y grabo desde la consola.
- Código:
sdcc --debug -mpic14 -p16f84a archivo.c
picprog --input archivo.hex --burn -d pic16f84a --pic /dev/ttyS0
La librería de sergiols sirve para varios pic, y por ejemplo yo la estoy utilizando con un cristal de 8Mhz.
La ventaja de la sgr es que tiene la opción de Read, está más comentada y hay ejemplos de como utilizar las funciones. Con la de sergiols no he conseguido escribir nada en el LCD y no sé si estoy utilizando mal las funciones o hay otro problema.
mentes- Nuevo Usuario
- Mensajes : 9
Fecha de inscripción : 01/10/2010
Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.
Si... algo pasa.He compilado varios programas, así que algo tiene este código que al linker no le gusta.
OK... si, no sé porqué suponía que usabas piklab.Deduces que utilizo algún IDE, pero compilo y grabo desde la consola.
Entonces prueba esto:
- Código:
sdcc -mpic14 -p16f84a -V --debug -c tu_archivo.c
Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.
Vaya.. fui a previsualizar el mensaje y creo que le di a enviar.
y quizás funcione a 8 MHz, pero parece que está hecha para 4 MHz:
Quizás esté relacionado con la cantidad de memoria y el modo "realocatable" (o algo así) que creo que usa el linker.
Si por ejemplo copias el contenido de la librería y lo pegas en tu archivo en lugar de #include "lcd_sdcc_sgr.h" también debería funcionar sin el "-c" al lanzar sdcc.
Si, sirve para varios pic, eso lo decía por esto:La librería de sergiols sirve para varios pic, y por ejemplo yo la estoy utilizando con un cristal de 8Mhz.
- Código:
#include <pic16f84a.h>
#include "lcd.h"
y quizás funcione a 8 MHz, pero parece que está hecha para 4 MHz:
- Código:
void delay_ms(int ms){
unsigned int j;
unsigned int k = ms * 10;
for (j=0; j<k; j++)
delay_us (33); //101µs **** Aunque a mi me salen 133 µs
}
................
................
_asm // delay de 4µs
nop
nop
nop
nop
_endasm;
Quizás esté relacionado con la cantidad de memoria y el modo "realocatable" (o algo así) que creo que usa el linker.
Si por ejemplo copias el contenido de la librería y lo pegas en tu archivo en lugar de #include "lcd_sdcc_sgr.h" también debería funcionar sin el "-c" al lanzar sdcc.
Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.
Definitivamente es un problema de cantidad de memoria.
Si se compila con la opción "-c" (no linkear) compila bien y genera el asm.
Si ahora llamamos al linker sin la opción "-r" que biene por defecto para usar memoria compartida, que el pic no tiene... no?, da el verdadero error :
La libreria de sergiols es más pequeña y entonces debe entrar bien en memoria.
Si se compila con la opción "-c" (no linkear) compila bien y genera el asm.
Si ahora llamamos al linker sin la opción "-r" que biene por defecto para usar memoria compartida, que el pic no tiene... no?, da el verdadero error :
$ /usr/bin/gplink -I/usr/bin/../share/sdcc/lib -I/usr/share/sdcc/lib -I/usr/bin/../share/sdcc/lib/pic -I/usr/share/sdcc/lib/pic -c -m -w -o lcd_Hola_Mundo.hex lcd_Hola_Mundo.o libsdcc.lib pic16f84a.lib
message: using default linker script "/usr/share/gputils/lkr/16f84a.lkr"
error: no target memory available for section "UDL__divuint_0"
La libreria de sergiols es más pequeña y entonces debe entrar bien en memoria.
Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.
¡Acertaste!
Hay un problema de espacio. He comentado lcd_num() lcd_car() y compila, graba y ¡funciona!
¿Eso quiere decir que ahí se acaba la memoria del PIC, ya no puedo añadir más funciones al programa?
¿Existe alguna manera de calcular cuanto espacio va a necesitar un programa?
Supongo que el problema es de Ram ya que sólo tiene 68 bytes.
Hay un problema de espacio. He comentado lcd_num() lcd_car() y compila, graba y ¡funciona!
¿Eso quiere decir que ahí se acaba la memoria del PIC, ya no puedo añadir más funciones al programa?
¿Existe alguna manera de calcular cuanto espacio va a necesitar un programa?
Supongo que el problema es de Ram ya que sólo tiene 68 bytes.
mentes- Nuevo Usuario
- Mensajes : 9
Fecha de inscripción : 01/10/2010
Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.
Bien! al menos mis divagaciones sirvieron para algo
Creo que tambien podrías comentar lcd-busy y la linea while(lcd_busy... en lcd_data... creo que tampoco son imprescincibles.
y si no las vas a usar lcd-hex y la otra que está encima... lcdh o algo así.
Es que ese pic tiene muy poca flash, y sdcc solo para las rutinas de inicio se come unos 300 bytes, osea que queda muy poco libre.
Yo usaría como mínimo un 16f628a o por ahí.
De todas formas esas dos funciones no sirven para nada.Hay un problema de espacio. He comentado lcd_num() lcd_car() y compila
Creo que tambien podrías comentar lcd-busy y la linea while(lcd_busy... en lcd_data... creo que tampoco son imprescincibles.
y si no las vas a usar lcd-hex y la otra que está encima... lcdh o algo así.
Pues por lo visto no...¿Eso quiere decir que ahí se acaba la memoria del PIC, ya no puedo añadir más funciones al programa?
Es que ese pic tiene muy poca flash, y sdcc solo para las rutinas de inicio se come unos 300 bytes, osea que queda muy poco libre.
Yo usaría como mínimo un 16f628a o por ahí.
Pues a priori creo que no hay manera, además también depende de las optimizaciones del compilador que se usen, sdcc tiene unas pocas, alguna de ellas que influyen en el tamaño del código generado.¿Existe alguna manera de calcular cuanto espacio va a necesitar un programa?
Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.
De momento esto me va a servir para entender como se maneja el LCD, pero por lo que veo para la aplicación final voy a necesitar algo con más memoria como me indicas.
Voy a ir viendo como trabaja cada función y quitando lo que no sea imprescindible. Cuando lo tenga pondré aquí una versión reducida de la librería para el 16F84.
Tus comentarios me han sido de gran ayuda, gracias.
Voy a ir viendo como trabaja cada función y quitando lo que no sea imprescindible. Cuando lo tenga pondré aquí una versión reducida de la librería para el 16F84.
Tus comentarios me han sido de gran ayuda, gracias.
mentes- Nuevo Usuario
- Mensajes : 9
Fecha de inscripción : 01/10/2010
Página 1 de 2. • 1, 2
Temas similares
» ADC para PIC16F*, driver y ejemplo.
» SDCC: Driver para LCD. PIC16F*
» SDCC: Driver para ADC PIC16f87x.
» Libreria LCD 4Bit , para Pic16f
» SDCC: Driver para Usart PIC16*
» SDCC: Driver para LCD. PIC16F*
» SDCC: Driver para ADC PIC16f87x.
» Libreria LCD 4Bit , para Pic16f
» SDCC: Driver para Usart PIC16*
Página 1 de 2.
Permisos de este foro:
No puedes responder a temas en este foro.