LCD 44780 4-bits para PIC16F, driver y ejemplo.
+3
Risanti
pentax33
arcachofo
7 participantes
Página 2 de 2.
Página 2 de 2. • 1, 2
Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.
Hola a todos..
Esta bien interesante esto, yo hace un tiempo re-escribí esta librería,basada en la original de arcachofo, sin embargo no la quería publicar hasta tenerla bien probada.
La verdad yo igual opino en usar un Pic con mas capacidad, ya que por lo general se nos enseña a usar el 16f84A, especialmente en las universidades, pero este es bastante limitado, aunque con algo de imaginación y talento se realizan muchas cosas,
En vez de usar 16f84A se puede usar 16F88, este ultimo tiene 4K de memoria, oscilador interno y ADC. Muy bueno..
Bueno Sin mas, aquí esta la librería la probe con 16F84A con sdcc y funciona bien..
Como se usa..
Ademas, trate de mejorar el problema de trabajar con un PIC Frecuencias de 4Mhz..
Espero que la puedan probar y me den sus comentarios..
Saludos
RiSanti
Esta bien interesante esto, yo hace un tiempo re-escribí esta librería,basada en la original de arcachofo, sin embargo no la quería publicar hasta tenerla bien probada.
La verdad yo igual opino en usar un Pic con mas capacidad, ya que por lo general se nos enseña a usar el 16f84A, especialmente en las universidades, pero este es bastante limitado, aunque con algo de imaginación y talento se realizan muchas cosas,
En vez de usar 16f84A se puede usar 16F88, este ultimo tiene 4K de memoria, oscilador interno y ADC. Muy bueno..
Bueno Sin mas, aquí esta la librería la probe con 16F84A con sdcc y funciona bien..
- Código:
/*****************************************************************************
******************************************************************************
**** COMPILADOR SDCC ****
**** Libreria Lcd 4Bit para LDC 44780 ****
**** ****
/ 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
//------------------------------------------------------------------------
*************Historial de Cambios.********************************************
1- Reescrito y Modifcador por RiSanti ,foro Piclinux
2- Version Original por arcachofo ,foro Piclinux
******************************************************************************
************************Ejemplo de Uso****************************************
#define RS RC1 //PIN PARA RS.
#define RW RC2 //PIN PARA RW.
#define EN RC3 //PIN PARA ENABLE.
#define lcdPortC // Para usar Portc, para datos e 4Bit (ultimos 4bits)
#define FREQ 4000 // 4000 KHz = 4 Mhz, LA FRECUENCIA EN KHz.
********************************************************************************
****************************Definiciones por defecto****************************/
#ifndef __LCD_H__
#define __LCD_H__
//Frecuencia de Operacion de 4MHZ
#ifndef FREQ
#define FREQ 4000
#endif
#ifdef lcdPortB
#define lcdPort TRISB
#define lcdDato PORTB
#endif
#ifdef lcdPortC
#define lcdPort TRISC
#define lcdDato PORTC
#endif
#ifdef lcdPortD
#define lcdPort TRISD
#define lcdDato PORTD
#endif
//Por defecto definicion del Puerto B
#ifndef lcdPort
#define lcdPort TRISB
#define lcdDato PORTB
#endif
//Definicion de Pines de Control RS,RW,EN
#ifndef RS
#define RS RB0
#endif
#ifndef RW
#define RW RB1
#endif
#ifndef EN
#define EN RB2
#endif
//Defincion de Registro de GRam del Lcd
#define LCDLinea2 0x40
#define LCDLinea3 0x10
#define LCDLinea4 0x50
//>>>>>>>>>>>>>>Señales de Control>>>>>>>>>>>>>>//
#define EN1 EN=1; _asm nop _endasm
#define EN0 EN=0; _asm nop _endasm
#define RW1 RW=1; _asm nop _endasm
#define RW0 RW=0; _asm nop _endasm
//------------------ 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 //
//----------------------------- Funciones Disponibles --------------------------------
//------------------------------------------------------------------------
void Espera(char _ms)
{
while (--_ms)
{
_asm
nop
_endasm;
}
}
void espera_ms(unsigned int ms)
{
ms = ms * (FREQ / 4000);
while (ms > 0 )
{
Espera(108);
ms--;
}
}
unsigned char lcd_leer()
{
unsigned _data=0;
lcdPort |= 0xf0; //Los ultimos 4bit son Entradas
RW1; //Modo Lectura
EN1; // Flaco de Subida Para pin EN
_data=lcdDato & 0xf0; //Lectura de Nibble alto
EN0; // Flaco de Bajada Para pin EN
EN1; // Flaco de Bajada Para pin EN
_data|=((lcdDato &0x0f) >>4); //Lectura de Nibble Bajo
EN0; // Flaco de Bajada Para pin EN
RW0;
return (_data);
}
void lcd_Escribir(unsigned char c)
{
lcdPort &= 0x0f; //Los últimos 4bit son salidas
lcdDato=(lcdDato & 0x0f)|(c<<4);
EN1;
EN0;
}
void lcd_EnviarDato(unsigned char _ValorDato,unsigned char _TipoDato )
{
RS=0;
while ((lcd_leer())&0x80); //leer Bit busy, espera a que lcd este libre.
if(_TipoDato>0)
{
RS=1;
}
lcd_Escribir((_ValorDato&0xf0)>>4); //Enviar los El nibble mas significativo del Byte C
lcd_Escribir((_ValorDato&0x0f)) ; //Enviar los El nibble menos Singificativo del Byte C
}
void lcd_comando(unsigned char comando )
{
lcd_EnviarDato(comando,0);
}
void lcd_Borrar()
{
lcd_comando( clear );
lcd_comando( home );
}
void lcd_Imprimir( unsigned char *car )
{
char n = 0;
while( car[n])
{
lcd_EnviarDato( car[n] ,1);
n++;
}
}
void lcd_posicion(unsigned char x ,unsigned char y)
{
switch(y)
{
case 1:
y=0;
break;
case 2:
y=LCDLinea2;
break;
case 3:
y=LCDLinea3;
break;
case 4:
y=LCDLinea4;
break;
default:
y=0;
break;
}
lcd_comando( (0X80|(x+y-1)) );
}
void lcd_Iniciar()
{
RS=0;
EN=0;
RW=0;
espera_ms(50); // Esperar 50ms retardo durante el encendido.
//Enviar 3 veces 0x03 //
lcd_Escribir(3);
espera_ms(5);
lcd_Escribir(3);
espera_ms(5);
lcd_Escribir(3);
espera_ms(5);
//Enviar 1 vez 0x02 //
lcd_Escribir(2);
//Iniciacion 4bit 2 lineas //
lcd_comando( d4_bit ); //0x28 modo 4 bits 2 lineas
lcd_comando( dis_on ); //0x0c display on
lcd_comando( normal ); //0x06 entrada normal hacia adelante
lcd_comando( linea1 ); //0x80 linea 1 posicion 1
}
Como se usa..
- Código:
/* ----------------------------------------------------------------------- */
/* Ejemplo LCD 4Bit Con Pic16f84a, RiSanti*/
#include <pic16f84a.h>
#define FREQ 4000
#include <delay.h>
//***************LCD Definiciones*****
#define RS RB0
#define RW RB1
#define EN RB2
#define lcdPort TRISB
#define lcdDato PORTB
#include <lcd4.h>
//**************************************
typedef unsigned int word;
word at 0x2007 CONFIG = _XT_OSC & _WDT_ON & _PWRTE_OFF & _CP_OFF;
void main() {
TRISB=0;
TRISA=0;
PORTB=0;
lcd_Iniciar();
lcd_comando(linea1);
lcd_Imprimir("Test");
lcd_posicion(1,2); //Posicion (x,Y)
lcd_Imprimir("RiSanti");
while (1)
{
}
}
Ademas, trate de mejorar el problema de trabajar con un PIC Frecuencias de 4Mhz..
Espero que la puedan probar y me den sus comentarios..
Saludos
RiSanti
Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.
Risanti, me gustan tus funciones de lcd_Imprimir() y lcd_posicion() luego probaré tu librería.
De momento he conseguido entender como funciona el LCD, como enviarle comandos y escribir en él.
Dejo aquí esta tabla y una web para los que vengan detrás.
http://www.tolaemon.com/otros/lcdshd.htm
Hasta ahora lo tenía todo conectado al puerto B, tal y como viene de origen la librería, pero al conectar RS, RW y E al puerto A no consigo que funcione, ni siquiera inicia. Por más vueltas que le doy no lo consigo. ¿Alguna sugerencia?
He cambiado lo siguiente:
De momento he conseguido entender como funciona el LCD, como enviarle comandos y escribir en él.
Dejo aquí esta tabla y una web para los que vengan detrás.
http://www.tolaemon.com/otros/lcdshd.htm
Hasta ahora lo tenía todo conectado al puerto B, tal y como viene de origen la librería, pero al conectar RS, RW y E al puerto A no consigo que funcione, ni siquiera inicia. Por más vueltas que le doy no lo consigo. ¿Alguna sugerencia?
He cambiado lo siguiente:
- Código:
#define RS RA2
#define RW RA3
#define EN RA4
mentes- Nuevo Usuario
- Mensajes : 9
Fecha de inscripción : 01/10/2010
Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.
hola..
La libreria deberia funcionar con cualquier puerto.Para las señales Rs Rw En, solo requieren que sean pines previamente configuados como salida, ademas se me ocurre que no funciona debido a que el pin RA4 es tipo colector abierto,por lo cual el pin EN,no trabaja bien.
Trata de usar EN con otro pin ya sea del puerto A o B.
La libreria deberia funcionar con cualquier puerto.Para las señales Rs Rw En, solo requieren que sean pines previamente configuados como salida, ademas se me ocurre que no funciona debido a que el pin RA4 es tipo colector abierto,por lo cual el pin EN,no trabaja bien.
Trata de usar EN con otro pin ya sea del puerto A o B.
Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.
@ mentes:
Qué PIC estás usando??????
La serie 16F87X en el port_a tienen la posibilidad de ser entradas analógicas, y para utilizarlas como entradas o salidas digitales, debe de estar correctamente configurado el puerto. Puede que te esté pasando algo similar.
Saludos!
Qué PIC estás usando??????
La serie 16F87X en el port_a tienen la posibilidad de ser entradas analógicas, y para utilizarlas como entradas o salidas digitales, debe de estar correctamente configurado el puerto. Puede que te esté pasando algo similar.
Saludos!
aztk- Participante Activo
- Mensajes : 52
Fecha de inscripción : 08/06/2009
Edad : 36
Localización : Tenochtitlan
Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.
Estoy utilizando un 16F84A.
El problema debe ser el que me indica Risanti, que el RB4 es el mismo pin que el Timer0 ¿Cuál es la forma correcta de configurarlo como RB4?
Desviando un poco el tema. ¿Sabéis de algún ejemplo dónde pueda ver como se utiliza el Timer0?
Sobre el Timer0 he encontrado algo por aquí https://pic-linux.forosactivos.net/sdcc-f1/duda-sobre-las-interrupciones-en-sdcc-t135.htm
El problema debe ser el que me indica Risanti, que el RB4 es el mismo pin que el Timer0 ¿Cuál es la forma correcta de configurarlo como RB4?
Desviando un poco el tema. ¿Sabéis de algún ejemplo dónde pueda ver como se utiliza el Timer0?
Sobre el Timer0 he encontrado algo por aquí https://pic-linux.forosactivos.net/sdcc-f1/duda-sobre-las-interrupciones-en-sdcc-t135.htm
mentes- Nuevo Usuario
- Mensajes : 9
Fecha de inscripción : 01/10/2010
Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.
Mira aquí: http://www.iearobotics.com/wiki/index.php?title=Programaci%C3%B3n_del_PIC16_en_C
Hay varios ejemplos, alguno para Timer0.
Hay varios ejemplos, alguno para Timer0.
Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.
He cambiado EN a RA0 y tampoco inicia.
Ahora lo tengo así:
Respecto al Timer, he visto los ejemplos pero no veo como hacer lo que yo quiero.
Mi idea es hacer una cuenta atrás desde 10 segundos hasta 0, si activo determinada puerta, el contador vuelve a 10 segundos, si el contador llega a 0 que ejecute una función.
Y aquí el código
Lo he sacado de aquí http://code.google.com/p/picrobotcode/source/browse/trunk/isr.c?spec=svn4&r=4
Lo que está comentado en inglés lo he copiado directamente, aún no sé como funciona
Ahora lo tengo así:
- Código:
#define RS RA2
#define RW RA3
#define EN RA0
Mi idea es hacer una cuenta atrás desde 10 segundos hasta 0, si activo determinada puerta, el contador vuelve a 10 segundos, si el contador llega a 0 que ejecute una función.
Y aquí el código
- Código:
#include <pic16f84a.h>
typedef unsigned int word;
word at 0x2007 CONFIG = _XT_OSC & _WDT_OFF & _PWRTE_ON & _CP_OFF;
unsigned int c = 0;
void isr() interrupt 0 {
T0IF = 0; /* Clear timer interrupt flag */
c++;
if (c>150){
RA1=1;
}
}
void main() {
TRISA=0; // Puerto A como salida
PORTA=0; // Puerto A desactivado
TRISB=1; // Puerto B como entrada
PORTB=0; // Puerto B desactivado
T0CS=0; // 0 TMR0 temporizador; 1 TMR0 contador
PSA=0; // 0 Prescaler a TMR0; 1 Postcaler a WDT
PS2=1; PS1=1; PS0=1; // Prescaler a 256
INTCON = 0; /* clear interrupt flag bits */
GIE = 1; /* global interrupt enable */
T0IE = 1; /* TMR0 overflow interrupt enable */
TMR0 = 0; /* clear the value in TMR0 */
while(1){
if (RB3 == 1){
c = 0;
}
}
}
Lo he sacado de aquí http://code.google.com/p/picrobotcode/source/browse/trunk/isr.c?spec=svn4&r=4
Lo que está comentado en inglés lo he copiado directamente, aún no sé como funciona
mentes- Nuevo Usuario
- Mensajes : 9
Fecha de inscripción : 01/10/2010
Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.
Bueno reportando el funcionamiento de la libreria de Risanti sobre el manejo de la LCD.
Esta ocación he usado un pic16f819 con clk interno a 8Mhz y pues funciona perfecto!
Felicitaciones Risanti.
Aquí el código probado
Solo como nota al simular con proteus no funca su habilito los bits IRFC2,1,0 pero físicamente si lo hace.
Por lo que respecta tus dudas mentes:
tal ves te falte el archivo delay.h, hace rato no lo tenia incluido y aunque me compilaba bien, la LCD no inicializaba.
y por tu duda con respecto a los timers, pues bien, revisando el datasheet del f84
El bit T0CS sirve para seleccionar la fuente de señales que escogeras para tu timer 0
en este caso como esta a 0 usas el la fuente de tu cristal
Debido a que el codigo interrumpe siempre y cuando haya un desborde debes habilitar dos bits mas
GIE Interrupciones generales habilitadas
T0IE Interrupcion por desborde habilitada
y con TMR0 = 0 estas declarando que el TMR se va a desbordar cada 255 ticks, cada tick lo podrás calcular de la siguiente manera
Tick= (1/Fclk)*4*Preescaler
Asi que en el código que tienes sería:
Tick = (1/4000000) * 4 * 256 = 25.6 us
así que tu desborde sera de
Tiempo de interrupcion = 255 * 25.6us = 65.28 ms aproximadamente
Ahora bien en
esta rutina entrará cada 65.28ms e incrementará una variable "c", la cual si es mayor a 150 pone en alto el pin 18 del PIC (RA1). y hasta ahi.
para ponerlo mas sencillo despues de este choro.
al encender al pic un led conectado entre RA1 y GND encenderá despueś de (65.28ms * 150) = 9.792s.
Espero haber sido claro y sobre todo que te sirva
Esta ocación he usado un pic16f819 con clk interno a 8Mhz y pues funciona perfecto!
Felicitaciones Risanti.
Aquí el código probado
- Código:
/* ----------------------------------------------------------------------- */
/* Ejemplo LCD 4Bit Con Pic16f84a, RiSanti*/
#include <pic16f819.h>
#define FREQ 8000
#include <delay.h>
//***************LCD Definiciones*****
#define RS RA0
#define RW RA1
#define EN RA2
#define lcdPort TRISB
#define lcdDato PORTB
#include <lcd4.h>
//**************************************
typedef unsigned int word;
word at 0x2007 CONFIG = _WDT_OFF & _PWRTE_ON & _INTRC_IO & _MCLR_OFF & _BODEN_ON & _LVP_OFF & _CPD_OFF & _WRT_ENABLE_OFF & _DEBUG_OFF & _CCP1_RB2 & _CP_OFF;
void main() {
ADCON1=0x06; //poner a digitales
TRISB=0;
TRISA=0;
PORTB=0;
IRCF2=1; //bits para configurar el postescaler del clk interno a 8MHZ
IRCF1=1; // pagina 38 del datasheet
IRCF0=1;
lcd_Iniciar();
lcd_comando(linea1);
lcd_Imprimir("Hola");
lcd_posicion(1,2); //Posicion (x,Y)
lcd_Imprimir("Mundo");
while (1)
{
}
}
Solo como nota al simular con proteus no funca su habilito los bits IRFC2,1,0 pero físicamente si lo hace.
Por lo que respecta tus dudas mentes:
tal ves te falte el archivo delay.h, hace rato no lo tenia incluido y aunque me compilaba bien, la LCD no inicializaba.
y por tu duda con respecto a los timers, pues bien, revisando el datasheet del f84
El bit T0CS sirve para seleccionar la fuente de señales que escogeras para tu timer 0
en este caso como esta a 0 usas el la fuente de tu cristal
Debido a que el codigo interrumpe siempre y cuando haya un desborde debes habilitar dos bits mas
GIE Interrupciones generales habilitadas
T0IE Interrupcion por desborde habilitada
y con TMR0 = 0 estas declarando que el TMR se va a desbordar cada 255 ticks, cada tick lo podrás calcular de la siguiente manera
Tick= (1/Fclk)*4*Preescaler
Asi que en el código que tienes sería:
Tick = (1/4000000) * 4 * 256 = 25.6 us
así que tu desborde sera de
Tiempo de interrupcion = 255 * 25.6us = 65.28 ms aproximadamente
Ahora bien en
- Código:
void isr() interrupt 0 {
T0IF = 0; /* Clear timer interrupt flag */
c++;
if (c>150){
RA1=1;
}
}
esta rutina entrará cada 65.28ms e incrementará una variable "c", la cual si es mayor a 150 pone en alto el pin 18 del PIC (RA1). y hasta ahi.
para ponerlo mas sencillo despues de este choro.
al encender al pic un led conectado entre RA1 y GND encenderá despueś de (65.28ms * 150) = 9.792s.
Espero haber sido claro y sobre todo que te sirva
Última edición por maigke el Miér 6 Oct 2010 - 16:34, editado 1 vez
maigke- Asiduo del Foro
- Mensajes : 210
Fecha de inscripción : 12/04/2009
Edad : 47
Localización : Mexico
Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.
Ya me va quedando más claro lo del Timer.
Cuando declaro TMR0, si pongo por ejemplo TMR0=100 ¿Contará 155 ticks en cada vuelta o sólo en la primera?
Voy a volver a al protoboard para probar bien las librerías.
Cuando declaro TMR0, si pongo por ejemplo TMR0=100 ¿Contará 155 ticks en cada vuelta o sólo en la primera?
Voy a volver a al protoboard para probar bien las librerías.
mentes- Nuevo Usuario
- Mensajes : 9
Fecha de inscripción : 01/10/2010
Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.
Hola a todos...
Me da gusto que la libreria funcione, aunque aun falta mejorar algunas cosas mas..
tengo una acotación..
Para definir el puerto del a usar el lcd,se debe puede definir directamente, con
si D4-D7 estan el el PortB
Saludos
RiSanti
Me da gusto que la libreria funcione, aunque aun falta mejorar algunas cosas mas..
tengo una acotación..
Para definir el puerto del a usar el lcd,se debe puede definir directamente, con
si D4-D7 estan el el PortB
- Código:
#define lcdPortB
- Código:
#define lcdPortC
- Código:
//***************LCD Definiciones*****
#define RS RA0
#define RW RA1
#define EN RA2
#define lcdPortB
#include <lcd4.h>
//**************************************
Saludos
RiSanti
Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.
Ke tal Risanti!
No al contrario y gracias a ti, mira pues he probado la libreria con algunos otros códigos y funcan muy bien, solo con algunas adaptaciones (no en la libreria), pero espero el hilo que pongas y si me das chance aporto ahi los codigos que he adaptado, aunque son sencillos, pero estan buenos.
No al contrario y gracias a ti, mira pues he probado la libreria con algunos otros códigos y funcan muy bien, solo con algunas adaptaciones (no en la libreria), pero espero el hilo que pongas y si me das chance aporto ahi los codigos que he adaptado, aunque son sencillos, pero estan buenos.
maigke- Asiduo del Foro
- Mensajes : 210
Fecha de inscripción : 12/04/2009
Edad : 47
Localización : Mexico
Página 2 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 2 de 2.
Permisos de este foro:
No puedes responder a temas en este foro.