Libreria LCD 20 x 4 Flexible 4 bits SDCC PIC18F2550

Ir abajo

Libreria LCD 20 x 4 Flexible 4 bits SDCC PIC18F2550

Mensaje por maigke el Lun 24 Dic 2012 - 6:27

Bueno esta la hice un poco antes de la libreria de 3 bits Razz pero bueno les dejo el código y recuerden que deben agregar Non-free para SDCC 3.0 o superior y la opcion de libc18f.lib

Código:

/*
  File:  fLCDSDCC.h
  Author: Miguel
 * basado en la libreria publicada en el foro de ucontrol por Suky
 * y en la libreria publicada por Felixls en su blog
 * se requiere ademas de la libreria hecha por Junif para los retardos
 *
 * #define FOSC 48000000
 * #include "simple_delay.h"
 * esto en el main

  Created on 28 de agosto de 2012, 02:28 PM
 */

/**
 *  Esta libreria permite conectar cualquier pin del microcontrolador
 *  en interface con una pantalla LCD alfanumerica, dependiendo de las
 *  terminales a utilizar, se requiere que el usuario configure de forma
 *  digital las terminales a utlizar por la libreria
 */
#ifndef fLCDSDCC_h
#define fLCDSDCC_h


//Si no se utliza solo se debe comentar esta linea
#define USE_RW

/* Definición de las terminales a utilizar
 * LATxbits se usa para escribir al puerto x
 * PORTxbits se usa para leer el estado del puerto
 * TRISxbits se utliza para configurar el puerto
 */

#define DATA_PIN_7  LATBbits.LATB7
#define DATA_PIN_6  LATBbits.LATB6
#define DATA_PIN_5  LATBbits.LATB5
#define DATA_PIN_4  LATBbits.LATB4

#define READ_PIN_7  PORTBbits.RB7
#define READ_PIN_6  PORTBbits.RB6
#define READ_PIN_5  PORTBbits.RB5
#define READ_PIN_4  PORTBbits.RB4

#define TRIS_DATA_PIN_7    TRISBbits.TRISB7
#define TRIS_DATA_PIN_6    TRISBbits.TRISB6
#define TRIS_DATA_PIN_5    TRISBbits.TRISB5
#define TRIS_DATA_PIN_4    TRISBbits.TRISB4

#define E_PIN  LATBbits.LATB2
#define RS_PIN  LATBbits.LATB0
#ifdef USE_RW
    #define RW_PIN LATBbits.LATB1
#endif

#define TRIS_E  TRISBbits.TRISB2
#define TRIS_RS TRISBbits.TRISB0
#ifdef USE_RW
    #define TRIS_RW TRISBbits.TRISB1
#endif

/**
 * Definiciones para configurar el LCD
 *
 * Actualizacion: Esta actualizacion es
  19 de mayo de 2011, modifico la libreria para poder usarla con la de hunif
  simple_delay.h
  * Se agregan #define LCD_LINEA 3 y LCD_LINEA_4 para usar una lcd de 4 lineas
  * Se agrega la funcion lcd_gotoxy, adaptada de la version de CCS
  * El encabezado de tu archivo main debe ser el siguiente

  code char at __CONFIG1L CONFIG1L = _PLLDIV_DIVIDE_BY_5__20MHZ_INPUT__1L & _CPUDIV__OSC1_OSC2_SRC___1__96MHZ_PLL_SRC___2__1L & _USBPLL_CLOCK_SRC_FROM_96MHZ_PLL_2_1L;
code char at __CONFIG1H CONFIG1H = _OSC_HS__HS_PLL__USB_HS_1H & _FCMEN_ON_1H & _IESO_ON_1H;
code char at __CONFIG2L CONFIG2L = _PUT_ON_2L & _BODEN_ON_2L & _BODENV_4_2V_2L & _VREGEN_ON_2L;
code char at __CONFIG2H CONFIG2H = _WDT_DISABLED_CONTROLLED_2H & _WDTPS_1_32768_2H;
code char at __CONFIG3H CONFIG3H = _CCP2MUX_RC1_3H & _PBADEN_PORTB_4_0__CONFIGURED_AS_DIGITAL_I_O_ON_RESET_3H & _LPT1OSC_ON_3H & _MCLRE_MCLR_OFF_RE3_ON_3H;
code char at __CONFIG4L CONFIG4L = _STVR_ON_4L & _LVP_OFF_4L & _ENHCPU_OFF_4L & _BACKBUG_OFF_4L;
code char at __CONFIG5L CONFIG5L = _CP_0_OFF_5L & _CP_1_OFF_5L & _CP_2_OFF_5L & _CP_3_OFF_5L;
code char at __CONFIG5H CONFIG5H = _CPB_OFF_5H;
code char at __CONFIG6L CONFIG6L = _WRT_0_OFF_6L & _WRT_1_OFF_6L & _WRT_2_OFF_6L & _WRT_3_OFF_6L;
code char at __CONFIG6H CONFIG6H = _WRTC_OFF_6H & _WRTB_OFF_6H;
code char at __CONFIG7L CONFIG7L = _EBTR_0_OFF_7L & _EBTR_1_OFF_7L & _EBTR_2_OFF_7L & _EBTR_3_OFF_7L;
code char at __CONFIG7H CONFIG7H = _EBTRB_OFF_7H;


  --Autor: Miguel Montiel Martinez
 * Las lineas se agregan el 28 de agosto de 2012
 */

#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 1000 0000
#define LCD_LINE2                0xC0 // Linea 2 posicion 1 1010 0000
#define LCD_LINE3        0x94 //Linea 3 posicion  1
#define LCD_LINE4        0xD4 //Linea 4 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 //envia caracter
#define LCD_COMMANDMODE          0x00 //envia comando
#define LCD_CGRAM1        0x40 //primera direccion para CGRAM
#define LCD_CGRAM2        0x48 //segunda direccion para CGRAM


/** Seccion de funciones
 *  En esta seccion se encuentran las funciones necesarias para implementar
 *  la interfaz entre una pantalla LCD y un microcontrolador PIC18
 */

//Cadena para enviar la inicializacion de la LCD
const char LCD_INIT_STRING[]=
{
    LCD_D4_BIT, LCD_CLEAR, LCD_CURSOR_OFF, LCD_NORMAL,
    LCD_DIS_ON
};

/**
 *  void lcd_send quartet
 *  Esta función permite el envio de un nibble a través de las terminales
 *  definidas como salidas, requiere de los parametros
 * @param mode Se requiere indicar si es un comando o un caracter el que se
 *              envia
 * @param dato Aquí se coloca el dato a enviar a la LCD
 */

void lcd_send_quartet(char mode, char dato)
{
    unsigned char temp=0;
    RS_PIN = mode;


    temp = (dato & 0x10);
    DATA_PIN_4 = temp >> 4;
    temp = (dato & 0x20);
    DATA_PIN_5 = temp >> 5;
    temp = (dato & 0x40);
    DATA_PIN_6 = temp >> 6;
    temp = (dato & 0x80);
    DATA_PIN_7 = temp >> 7;

    E_PIN = 1;
    delay_ms(1);
    E_PIN = 0;
}


/**
 * unsigned lcd_read_nibble(void)
 *  Esta funcion permite leer un nibble a través de la unión conformada
 *  por la estructura retval_byte
 * @return ret_val_byte
 */
#ifdef USE_RW
unsigned char lcd_read_nibble(void)
{
    union{
        unsigned char retval_byte;
        struct{
            unsigned char ret_val_0:1;
            unsigned char ret_val_1:1;
            unsigned char ret_val_2:1;
            unsigned char ret_val_3:1;
        };
    }retval;

    retval.retval_byte=0;
    E_PIN = 1;
    delay_ms(1);
    retval.ret_val_0 = READ_PIN_4;
    retval.ret_val_1 = READ_PIN_5;
    retval.ret_val_2 = READ_PIN_6;
    retval.ret_val_3 = READ_PIN_7;
    E_PIN = 0;
    return (retval.retval_byte);
}
#endif  //lcd_read_nibble(void)

/**
 * unsigned char lcd_read_byte(void)
 * Esta funcion se habilita si se ha definido el utilizar el pinRW
 * leyendo dos nibbles y devolviendo la union de ambos nibbles
 * @return high<<4 | low
 */
#ifdef USE_RW
unsigned char lcd_read_byte(void)
{
    unsigned char low;
    unsigned char high;

    TRIS_DATA_PIN_4 = 1;
    TRIS_DATA_PIN_5 = 1;
    TRIS_DATA_PIN_6 = 1;
    TRIS_DATA_PIN_7 = 1;

    RW_PIN = 1;
    delay(1);
    high = lcd_read_nibble();
    low  = lcd_read_nibble();

    return ((high << 4) | low);
}
#endif //lcd_read_byte

/**
 * void lcd_send(char mode char dato)
 * @param mode parametro para diferenciar entre comando o dato
 * @param dato dato o comando a enviar
 */

void lcd_send(char mode, char dato)
{
    unsigned char temp = dato;
    RS_PIN = 0;

#ifdef USE_RW
    while((lcd_read_byte() & 0x80) == 0x80);
#else
            delay_ms(5);
#endif

            TRIS_DATA_PIN_4 = 0;
            TRIS_DATA_PIN_5 = 0;
            TRIS_DATA_PIN_6 = 0;
            TRIS_DATA_PIN_7 = 0;

            RS_PIN = mode;
            delay_ms(1);
            E_PIN = 0;
#ifdef USE_RW
            RW_PIN = 0;
            delay_ms(1);
#endif
            lcd_send_quartet(mode, temp & 0xf0);
            lcd_send_quartet(mode, (temp << 4) & 0xf0);

            E_PIN = 1;
            delay_ms(5);
            E_PIN = 0;
}
/**
 * lcd_init()  funcion para inicializar la LCD
 */
void lcd_init(void)
{
    unsigned char i;

    TRIS_RS = 0;
    TRIS_E = 0;

#ifdef USE_RW
    TRIS_RW = 0;
#endif

    RS_PIN = 0; E_PIN = 0;
#ifdef USE_RW
    RW_PIN = 0;
#endif

    TRIS_DATA_PIN_4 = 0; TRIS_DATA_PIN_5 = 0;
    TRIS_DATA_PIN_6 = 0; TRIS_DATA_PIN_6 = 0;

    delay_ms(15);

    for(i=0; i< 3; i++)
    {
        lcd_send_quartet(LCD_COMMANDMODE, LCD_RESET);
        delay_ms(5);
    }

    lcd_send_quartet(LCD_COMMANDMODE, LCD_D4_BIT);
    delay_ms(5);

    for(i=0; i < sizeof(LCD_INIT_STRING); i++)
    {
        lcd_send(LCD_COMMANDMODE, LCD_INIT_STRING[i]);
#ifndef USE_RW
        delay_ms(5);
#endif

    }
}

/**
 * funcion para posicionar el cursor del LCD en un localidad (x,y) particular
 * la funcion esta preparada para trabajar con una LCD de 20 x 4
 * @param x columna del lcd
 * @param y fila del LCD
 */
void lcd_gotoxy(unsigned char x, unsigned char y)
{
    unsigned char ADDRESS= 0x00;

    switch(y)
    {
        case 1:
            ADDRESS  = LCD_LINE1;
            break;
        case 2:
            ADDRESS = LCD_LINE2;
            break;
        case 3:
            ADDRESS = LCD_LINE3;
            break;
        case 4:
            ADDRESS = LCD_LINE4;
            break;
        default:
            ADDRESS = LCD_LINE1;
            break;

    }
    ADDRESS = (ADDRESS + x) -1;
    lcd_send(LCD_COMMANDMODE, ADDRESS);
}

/**
 * Funcion que envia un caracter a la lcd o puede enviar caracteres especiales
 * @param c caracter a enviar
 * Si \f se limpia la LCD
 * Si \n es avance de linea
 * Si \b se envia un retroceso
 */
void lcd_putc(unsigned char c)
{
    switch(c)
    {
        case '\f':
            lcd_send(LCD_COMMANDMODE, LCD_CLEAR);
            break;
        case '\n':
            lcd_send(LCD_COMMANDMODE, 2);
            break;
        case '\b':
            lcd_send(LCD_COMMANDMODE, LCD_CURSOR_IZQ);
            break;
        default:
            lcd_send(LCD_CHARMODE,c);
            break;
    }
}

/**
 * Funcion que devuelve un caracter impreso en la lcd en una posicion (x,y)
 * @param x
 * @param y
 * @return value
 */
#ifdef USE_RW
unsigned char lcd_getc(unsigned char x, unsigned char y)
{
    unsigned char value;
    lcd_gotoxy(x,y);
    while((lcd_read_byte() & 0x80)==0x80);
    RS_PIN = 1;
    value = lcd_read_byte();
    RS_PIN = 0;

    return (value);
}
#endif  //unsigned char lcd_getc(unsigned char x, unsigned char y)

/**
 * Funcion que permite personalizar la presntacion del cursor en el LCD
 * @param visible
 * @param blink
 *
 * Si visible  = 1, el cursor estará visible
 * Si blink = 1, el cursor estará parpadeante
 */
void lcd_setcursor_vb(unsigned char visible, unsigned char blink)
{
    lcd_send(LCD_COMMANDMODE, LCD_DIS_ON | (visible << 1) | blink);
}

/**
 * La funcion puts pone en cola de impresion a lcd una cadena de caracteres
 * @param ptr Puntero de la cadena, el cual va señalando el turno de caracter
 * para ser impreso
 */
void lcd_puts(char *ptr)
{
    while(*ptr)
    {
        lcd_putc(*ptr++);
    }
}

char lcd_hexa(char a)
{
    if(a > 9)
        a+= 55;
    else
        a+= 48;
    return a;
}

#endif // fLCDSDCC_h



y aqui un ejemplo de uso

Código:

/*
 * File:  PruebaLCA.c
 * Author: Miguel
 *
 * Created on 28 de agosto de 2012, 04:50 PM
 * En propiedades del proyecto se debe especificar el uso de librerias nonfree
 * y ademas en el linker agregar la linea libc18f.lib para que no marque
 * errores la libreria simple_delay.h
 */
#include
#include
#include

#define FOSC 48000000
#include "simple_delay.h"
#include "fLCDSDCC.h"

__code char __at __CONFIG1L CONFIG1L = _PLLDIV_DIVIDE_BY_5__20MHZ_INPUT__1L & _CPUDIV__OSC1_OSC2_SRC___1__96MHZ_PLL_SRC___2__1L & _USBPLL_CLOCK_SRC_FROM_96MHZ_PLL_2_1L;
__code char __at __CONFIG1H CONFIG1H = _OSC_HS__HS_PLL__USB_HS_1H & _FCMEN_ON_1H & _IESO_ON_1H;
__code char __at __CONFIG2L CONFIG2L = _PUT_ON_2L & _BODEN_ON_2L & _BODENV_4_2V_2L & _VREGEN_ON_2L;
__code char __at __CONFIG2H CONFIG2H = _WDT_DISABLED_CONTROLLED_2H & _WDTPS_1_32768_2H;
__code char __at __CONFIG3H CONFIG3H = _CCP2MUX_RC1_3H & _PBADEN_PORTB_4_0__CONFIGURED_AS_DIGITAL_I_O_ON_RESET_3H & _LPT1OSC_ON_3H & _MCLRE_MCLR_OFF_RE3_ON_3H;
__code char __at __CONFIG4L CONFIG4L = _STVR_ON_4L & _LVP_OFF_4L & _ENHCPU_OFF_4L & _BACKBUG_OFF_4L;
__code char __at __CONFIG5L CONFIG5L = _CP_0_OFF_5L & _CP_1_OFF_5L & _CP_2_OFF_5L & _CP_3_OFF_5L;
__code char __at __CONFIG5H CONFIG5H = _CPB_OFF_5H;
__code char __at __CONFIG6L CONFIG6L = _WRT_0_OFF_6L & _WRT_1_OFF_6L & _WRT_2_OFF_6L & _WRT_3_OFF_6L;
__code char __at __CONFIG6H CONFIG6H = _WRTC_OFF_6H & _WRTB_OFF_6H;
__code char __at __CONFIG7L CONFIG7L = _EBTR_0_OFF_7L & _EBTR_1_OFF_7L & _EBTR_2_OFF_7L & _EBTR_3_OFF_7L;
__code char __at __CONFIG7H CONFIG7H = _EBTRB_OFF_7H;
/*
 *
 */

//Zona de funciones prototipo
void init_board(void);

int main(void) {
    init_board();
    lcd_init();
    lcd_gotoxy(1,1);
    lcd_setcursor_vb(1,1);
    delay_ms(2000);
    lcd_setcursor_vb(1,0);
    delay_ms(1000);
    lcd_setcursor_vb(0,1);
    delay_ms(1000);
    lcd_puts("hola niño");
    delay_ms(1000);

    lcd_puts("\f");
    delay_ms(500);
    lcd_setcursor_vb(1,1);
    lcd_puts("  mensaje 1    º \n");
        delay_ms(2000);
        lcd_send(LCD_COMMANDMODE,LCD_LINE2);
    lcd_puts("  mensaje 2      \n");
        delay_ms(1000);
    lcd_puts("  mensaje 3        ");
        delay_ms(1000);
        delay_ms(1000);

    return (0);
}

void init_board(void)
{
        LATA=0;
    LATB=0;
    LATC=0;
    PORTA=0;
    PORTB=0;
    PORTC=0;
    //cofigurando los puerto analógicos a digitales
    ADCON1 = 0x0F;  //Las entradas son configuradas como digitales PoRTA
    CMCON = 0x07;    //los comparadores son configurados como digitales PORTA
    CVRCONbits.CVREN = 0;        //PORTA
    CVRCONbits.CVROE = 0;        //PORTA
    ADCON0bits.ADON = 0;    //Se deshabilita el módulo ADC  PORTA y PORTB
    UCONbits.USBEN = 0;    //Deshabilita el módulo USB    PORTC
    UCFGbits.UTRDIS = 1;    //On-chip transceiver disabled; digital
                                //transceiver interface enabled PORTC


}

pig
avatar
maigke
Asiduo del Foro
Asiduo del Foro

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

Volver arriba Ir abajo

Volver arriba

- Temas similares

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