Microcontroladores PIC en Linux.
¿Quieres reaccionar a este mensaje? Regístrate en el foro con unos pocos clics o inicia sesión para continuar.

LCD 44780 4-bits para PIC16F, driver y ejemplo.

+3
Risanti
pentax33
arcachofo
7 participantes

Página 2 de 2. Precedente  1, 2

Ir abajo

LCD 44780 4-bits para PIC16F, driver y ejemplo. - Página 2 Empty Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.

Mensaje por Risanti Sáb 2 Oct 2010 - 17:40

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..

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..

LCD 44780 4-bits para PIC16F, driver y ejemplo. - Página 2 02102010857.th



Saludos
RiSanti
Risanti
Risanti
Asiduo del Foro
Asiduo del Foro

Mensajes : 172
Fecha de inscripción : 07/12/2008
Edad : 39
Localización : La Serena Chile

https://www.facebook.com/risanti.electronica

Volver arriba Ir abajo

LCD 44780 4-bits para PIC16F, driver y ejemplo. - Página 2 Empty Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.

Mensaje por mentes Dom 3 Oct 2010 - 12:43

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.
LCD 44780 4-bits para PIC16F, driver y ejemplo. - Página 2 LCD_co1
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
Nuevo Usuario

Mensajes : 9
Fecha de inscripción : 01/10/2010

Volver arriba Ir abajo

LCD 44780 4-bits para PIC16F, driver y ejemplo. - Página 2 Empty Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.

Mensaje por Risanti Dom 3 Oct 2010 - 17:43

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.
Risanti
Risanti
Asiduo del Foro
Asiduo del Foro

Mensajes : 172
Fecha de inscripción : 07/12/2008
Edad : 39
Localización : La Serena Chile

https://www.facebook.com/risanti.electronica

Volver arriba Ir abajo

LCD 44780 4-bits para PIC16F, driver y ejemplo. - Página 2 Empty Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.

Mensaje por aztk Dom 3 Oct 2010 - 22:04

@ 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!

aztk
Participante Activo
Participante Activo

Mensajes : 52
Fecha de inscripción : 08/06/2009
Edad : 36
Localización : Tenochtitlan

Volver arriba Ir abajo

LCD 44780 4-bits para PIC16F, driver y ejemplo. - Página 2 Empty Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.

Mensaje por mentes Dom 3 Oct 2010 - 22:20

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

mentes
Nuevo Usuario
Nuevo Usuario

Mensajes : 9
Fecha de inscripción : 01/10/2010

Volver arriba Ir abajo

LCD 44780 4-bits para PIC16F, driver y ejemplo. - Página 2 Empty Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.

Mensaje por Pikitin Lun 4 Oct 2010 - 2:28


Pikitin
veterano
veterano

Mensajes : 623
Fecha de inscripción : 26/11/2008

http://linuxmicros.blogspot.com/

Volver arriba Ir abajo

LCD 44780 4-bits para PIC16F, driver y ejemplo. - Página 2 Empty Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.

Mensaje por mentes Lun 4 Oct 2010 - 11:52

He cambiado EN a RA0 y tampoco inicia.

Ahora lo tengo así:

Código:
#define RS RA2
#define RW RA3
#define EN RA0

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 Very Happy

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 Smile

mentes
Nuevo Usuario
Nuevo Usuario

Mensajes : 9
Fecha de inscripción : 01/10/2010

Volver arriba Ir abajo

LCD 44780 4-bits para PIC16F, driver y ejemplo. - Página 2 Empty Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.

Mensaje por maigke Lun 4 Oct 2010 - 17:26

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

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
maigke
Asiduo del Foro
Asiduo del Foro

Mensajes : 210
Fecha de inscripción : 12/04/2009
Edad : 47
Localización : Mexico

Volver arriba Ir abajo

LCD 44780 4-bits para PIC16F, driver y ejemplo. - Página 2 Empty Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.

Mensaje por mentes Lun 4 Oct 2010 - 19:25

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.

mentes
Nuevo Usuario
Nuevo Usuario

Mensajes : 9
Fecha de inscripción : 01/10/2010

Volver arriba Ir abajo

LCD 44780 4-bits para PIC16F, driver y ejemplo. - Página 2 Empty Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.

Mensaje por Risanti Miér 6 Oct 2010 - 0:49

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
Código:

#define lcdPortB
O por ej. si D4-D7 están el el PortC
Código:

 #define lcdPortC
Osea la definiciones necesarias serian:
Código:

//***************LCD Definiciones*****
#define RS RA0
#define RW RA1
#define EN RA2
#define lcdPortB
#include <lcd4.h>
//**************************************
Gracias, Maigke por probar la libreria.... Voy a Crear un Tema con esta para llevar mejor el control de cambios y mejoras.

Saludos
RiSanti
Risanti
Risanti
Asiduo del Foro
Asiduo del Foro

Mensajes : 172
Fecha de inscripción : 07/12/2008
Edad : 39
Localización : La Serena Chile

https://www.facebook.com/risanti.electronica

Volver arriba Ir abajo

LCD 44780 4-bits para PIC16F, driver y ejemplo. - Página 2 Empty Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.

Mensaje por maigke Miér 6 Oct 2010 - 16:31

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. cheers
maigke
maigke
Asiduo del Foro
Asiduo del Foro

Mensajes : 210
Fecha de inscripción : 12/04/2009
Edad : 47
Localización : Mexico

Volver arriba Ir abajo

LCD 44780 4-bits para PIC16F, driver y ejemplo. - Página 2 Empty Re: LCD 44780 4-bits para PIC16F, driver y ejemplo.

Mensaje por Contenido patrocinado


Contenido patrocinado


Volver arriba Ir abajo

Página 2 de 2. Precedente  1, 2

Volver arriba

- Temas similares

 
Permisos de este foro:
No puedes responder a temas en este foro.