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

Publicar nuevo tema   Responder al tema

Ver el tema anterior Ver el tema siguiente Ir abajo

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

Mensaje  arcachofo el Jue 27 Nov 2008 - 5:24

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):

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
Participante Activo

Cantidad de envíos: 90
Fecha de inscripción: 26/11/2008

Volver arriba Ir abajo

Rutina de LDC hd44780

Mensaje  pentax33 el Lun 29 Dic 2008 - 1:46

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.

pentax33
Nuevo Usuario
Nuevo Usuario

Cantidad de envíos: 9
Fecha de inscripción: 28/11/2008

Volver arriba Ir abajo

Ver el tema anterior Ver el tema siguiente Volver arriba


Publicar nuevo tema   Responder al tema
Permiso de este foro:
No puedes responder a temas en este foro.