Retardos en MPLAB C18 Compiler para PIC18F4550

Buenas a todos, quisiera saber si alguien ha trabajado con retardos en MPLAB HI-TECH COMPILER C18. Cuando coloco un retado de 2000 mseg= 2 seg me genera un error en compilación. Alguien me puede orientar que solucion puedo hacer.

El error es el siguiente:

main.c:52: error: inline delay argument too large

y el código es el siguiente:

Código:
/*Configuración del Oscilador Interno del Pic para efectos del Delay*/
//Configuración del Oscilador Interno del Pic
#ifndef _XTAL_FREQ
 // Unless specified elsewhere, 4MHz system frequency is assumed
 #define _XTAL_FREQ 20000000
#endif


//Librería del Microcontrolador
#include <stdio.h>
#include <stdlib.h>
#include <pic18.h>
#include <pic18f4550.h>
#include <htc.h>
#include <hitech.h>
#include "lcd.h"
#include "configuracion.h"
#include "entorno.h"
#include "always.h"
#include "clk_freq.h"
#include "delay.h"



//Configuramos los FUSES
#pragma config CPUDIV=OSC1_PLL2, PLLDIV=6, USBDIV=2, IESO=ON, FOSC=HSPLL_HS, FCMEN=OFF, VREGEN=ON, BOR=SOFT, BORV=3, PWRT=OFF, WDT=OFF, CCP2MX=OFF, PBADEN=OFF, LPT1OSC= OFF, MCLRE=ON, DEBUG=OFF, STVREN=OFF, ICPRT=ON, XINST=OFF, LVP=OFF, CP0=OFF, CP1=OFF, CP2=OFF, CP3=OFF, CPD=OFF, CPB=OFF, WRT0=OFF, WRT1=OFF, WRT2=OFF, WRT3=OFF, WRTB=OFF, WRTC=OFF, WRTD=OFF, EBTR0=OFF, EBTR1=OFF, EBTR2=OFF, EBTR3=OFF, EBTRB=OFF

//Declaración de Variables*
int apagado, menu, posicion, temp;

//Declaracion de las Interrupciones del MCU
void interrupt isr(void){
    //Manejo de las Interrupciones
    //Ha ocurrido una Interrupcion Externa por el Puerto B2/INT2
    if (INTCON3bits.INT2IF==1){
        //Se ha presionado el pulsador de encender
        switch(apagado){
            case 0:
                //Esta Apagado el MCU
                lcd_clear();    //Limpiamos Pantalla
                lcd_init();     //Iniciamos el Mod. LCD
                menu=0;         //Inicializamos el Menu
                posicion=2;     //Establecemos la Posicion del Puntero
                entorno(menu,posicion);     //Cargamos la primera Pantalla
                __delay_ms(5000);           //Esperamos 5 segundos
                menu++;                     //Precargamos la siguiente Pantalla
                entorno(menu,posicion);     //Cargamos la siguiente Pantalla
                apagado=1;                  //Demostramos que el MCU se encuentra encendido
                INTCON3bits.INT2IF=0;       //Limpiamos la Bandera
                break;
            case 1:
                //Esta Encendido el MCU
                temp=menu;                  //Guardamos la Pantalla
                menu=2;                     //Cargamos la Pantalla
                posicion=2;                 //Cargamos la Posicion
                INTCON3bits.INT2IF=0;       //Limpiamos la Bandera
                entorno(menu,posicion);     //Cargamos la Pantalla asignada
                break;
        }
    }
}
//Declaración de Main
void main() {
    apagado=0;
    configuracion_inicial();

}

Agradecería su ayuda ...
 
Última edición por un moderador:
Hola.
Hi-tech indica que el valor es muy grande, para largos delays se puede usar la función delay dentro de un blucle.
Has probado por ejemplo, colocando un valor de 255 y 256? hasta 255 va bien pero para 256 da error, esto indica que el delay solo soporta valores del tipo byte. Prueba eso o los bucles.

Que versión tienes?, ya que el actual HiTech creo que tiene soporte directo de Microchip y revisa el manual de usuario que está en la carpeta de instalación.

Saludos.
 
Hola gracias por responder, fijate yo descargue el MPLAB X 1.85 con el compilador HI-TECH COMPILER C 18 VER. 9.80, fijate probe lo que me comentaste y sigue dando el mismo error. De verdad que he revisado el manual y me habla de una funcion llamada _delay(), pero dice que esta funcion se encarga de realizar un ciclo de retardo. De verdad nose que hacer.
 
En todo caso usa las funciones delay como macro, es algo que no entiendo el porque pero a otros les a resultado usar la función como tu la haces... pero para el caso desde el princípio las declaro como por ejemplo:

#define MyDelay(x) __delay_ms(x)
o
#define Delay10ms() __delay_ms(10)

Eso si me ha funcionado directamente...
 
:cry: No tampoco me funciono. Te cuento algo una de las librerías usa __delay_ms y __delay_us. Me explico mejor con códigos:

este código es lcd.h
Código:
#define    LCD_RS PORTDbits.RD0    //RD0
#define    LCD_RW PORTDbits.RD1    //RD1
#define LCD_EN PORTDbits.RD2    //RD2
#define LCD_DATA PORTD      //PORTD
#define    LCD_STROBE()    ((LCD_EN = 1),(LCD_EN=0))

unsigned char lcd_line;

//write a byte to the LCD in 4 bit mode
void lcd_write(unsigned char rs_bit, unsigned char c){
    LCD_RS = rs_bit;
    __delay_us(50);
    LCD_DATA = (c & 0xF0) | (LCD_DATA & 0x0F);
    LCD_STROBE();
    LCD_DATA = ( ( c << 4 ) & 0xF0 ) | (LCD_DATA & 0x0F);
    LCD_STROBE();
    __delay_us(50);
}

//Clear and home the LCD
void lcd_clear(void){
    lcd_line=1;
    lcd_write(0,0x1);
    __delay_ms(2);
}

//Backspace
void lcd_back(void){
    lcd_write(0,0b00010011);
}

//write one character to the LCD
void lcd_putch(unsigned char c){
    lcd_write(1, c ); // write characters
    //LCD_RS = 1;    // write characters
    //lcd_write(c);
}

//Go to the specified position
void lcd_goto(unsigned char pos_x,unsigned char pos_y){
    pos_y--;
    lcd_line = pos_x;
    lcd_write(0, 0b00000010);    //1.1: CURSOR RETURN
    __delay_ms(2);
    if(pos_x==1){
        lcd_write(0, 0x80+pos_y);
    }else if(pos_x==2){
        lcd_write(0, 0xC0+pos_y);
    }else if(pos_x==3){
        lcd_write(0, 0x94+pos_y);
    }else if(pos_x==4){
        lcd_write(0, 0xD4+pos_y);
    }
}

//write a string of chars to the LCD
void lcd_puts(const char * s){
    while(*s){
        switch (*s) {
            case '\b':  lcd_write(0,0x10);  break; //backspace
                        case '\f':  lcd_write(0,0x1); //clear display
                __delay_ms(2);
                           break;
                        case '\n': lcd_goto(lcd_line++,1);  break; //newline
                        default  : lcd_write(1,*s);     // write characters
                        break;
           }
        *s++;
    }
}

//initialise the LCD - put into 4 bit mode
void lcd_init(){
    LCD_RS = 0;
    LCD_EN = 0;
    LCD_RW = 0;
    
    __delay_ms(15);    // wait 15mSec after power applied,
    LCD_DATA = (LCD_DATA & 0x0F) | ( ( 0x3 << 4 ) & 0xF0 );    //Reset
    LCD_STROBE();
    __delay_ms(5);
    LCD_STROBE();
    __delay_us(200);
    LCD_STROBE();
    __delay_us(200);
    LCD_DATA = (LCD_DATA & 0x0F) | ( ( 0x2 << 4 ) & 0xF0 );    // Four bit mode
    LCD_STROBE();

    lcd_write(0, 0x28); // Set interface length
    //lcd_write(0, 0b00001100);  // Display On, Cursor Off, Cursor Blink Off
    lcd_clear();         // Clear screen
        lcd_write(0,0xF);       //Activamos el cursor y el Blink
    lcd_write(0, 0x6);      // Set entry Mode
}

y este es main.c

Código:
#ifndef _XTAL_FREQ
 // Unless specified elsewhere, 4MHz system frequency is assumed
 #define _XTAL_FREQ 20000000
#endif

//Declaramos Macro de Retardos
#define Delay2S() __delay_ms(2000)

//Libreria del Microcontrolador
#include <stdio.h>
#include <stdlib.h>
#include <pic18.h>
#include <pic18f4550.h>
#include <htc.h>
#include <hitech.h>
#include "lcd.h"
#include "configuracion.h"
#include "entorno.h"
#include "always.h"
#include "clk_freq.h"
#include "delay.h"



//Configuramos los FUSES
#pragma config CPUDIV=OSC1_PLL2, PLLDIV=6, USBDIV=2, IESO=ON, FOSC=HSPLL_HS, FCMEN=OFF, VREGEN=ON, BOR=SOFT, BORV=3, PWRT=OFF, WDT=OFF, CCP2MX=OFF, PBADEN=OFF, LPT1OSC= OFF, MCLRE=ON, DEBUG=OFF, STVREN=OFF, ICPRT=ON, XINST=OFF, LVP=OFF, CP0=OFF, CP1=OFF, CP2=OFF, CP3=OFF, CPD=OFF, CPB=OFF, WRT0=OFF, WRT1=OFF, WRT2=OFF, WRT3=OFF, WRTB=OFF, WRTC=OFF, WRTD=OFF, EBTR0=OFF, EBTR1=OFF, EBTR2=OFF, EBTR3=OFF, EBTRB=OFF

//Declaración de Variables*
int apagado, menu, posicion, temp;

//Declaracion de las Interrupciones del MCU
void interrupt isr(void){
    //Manejo de las Interrupciones
    //Ha ocurrido una Interrupcion Externa por el Puerto B2/INT2
    if (INTCON3bits.INT2IF==1){
        //Se ha presionado el pulsador de encender
        switch(apagado){
            case 0:
                //Esta Apagado el MCU
                lcd_clear();    //Limpiamos Pantalla
                lcd_init();     //Iniciamos el Mod. LCD
                menu=0;         //Inicializamos el Menu
                posicion=2;     //Establecemos la Posicion del Puntero
                entorno(menu,posicion);     //Cargamos la primera Pantalla
                Delay2S();                  //Esperamos 5 segundos
                menu++;                     //Precargamos la siguiente Pantalla
                entorno(menu,posicion);     //Cargamos la siguiente Pantalla
                apagado=1;                  //Demostramos que el MCU se encuentra encendido
                INTCON3bits.INT2IF=0;       //Limpiamos la Bandera
                break;
            case 1:
                //Esta Encendido el MCU
                temp=menu;                  //Guardamos la Pantalla
                menu=2;                     //Cargamos la Pantalla
                posicion=2;                 //Cargamos la Posicion
                INTCON3bits.INT2IF=0;       //Limpiamos la Bandera
                entorno(menu,posicion);     //Cargamos la Pantalla asignada
                break;
        }
    }
}
//Declaración de Main
void main() {
    apagado=0;
    configuracion_inicial();

}

De verdad nose que hacer... :confused::confused::confused::cry:
 
Última edición por un moderador:
Hola.
Pero cambia el delay de 2000ms, (error) indica que eso es un valor muy largo. Intenta con bucles y delays de menor valor.

En los foros de hitech hablan del mismo inconveniente y algunos lo han solucionado cambiando de versión pero esto es del año 2009, parece que ya no actualizan el compilador y si no lo tienes pro te sugiero usar el XC8, con este no he notado inconvenientes pero claro tendrás que cambiar algunas cosas.

Saludos.
 
Hola a todos, te comento que me cambie a XC8 y me persiste el mismo error. No coloque ningún otra libreria. Te muestro el código que coloque:

Código:
#include <stdio.h>
#include <stdlib.h>
#include <pic18f4550.h>
#include <xc.h>


//Definimos la Frecuencia del Oscilador Interno
#define _XTAL_FREQ 40000000

//Configuramos los Fuses del MCU 18F4550
#pragma config CPUDIV=OSC1_PLL2
/*
 * 
 */
//Declaracion de Variables

//Módulo Principal del Programa
void main() {
    __delay_ms(20);
}
 
Última edición por un moderador:
Hola:
Para salir de dudas cree un proyecto "Standalone" con MPLABX, CX8 V1.12 y un unico archivo llamado "main". Ya entendí el problema... y parece que se aplica al Hi-Tech.

Sucede que las macro Delay tiene un límite de ciclos, que se calculan con la frecuencia del oscilador y el valor del delay que se requiere. Según el manual indica que los ciclos para un PIC18 debe ser menor a 179,200 ciclos y 50,659,000 ciclos para otros PIC.

Haz la prueba reduciendo el valor oscilador (_XTAL_FREQ) a 4Mhz y compila... no habran errores porque la cantidad de ciclos está dentro del límite pero a 40Mhz sobrepasa el cálculo. Todo esto lo han puesto por defecto así que no se puede hacer nada...

No tienes más remedio que crear por ejemplo una funcion donde se realice el bucle con un delay corto y llamar a la funcion tantas veces lo nececites.

Código:
#include <xc.h>
#define _XTAL_FREQ 40000000 // 40Mhz

void MyDelay100(){
    volatile char i;
    for(i=0 ; i<100 ; i++){
        __delay_ms(1);  
    }
}

void main(void){
    TRISB = 0;

    while(1){
        MyDelay100();
        PORTBbits.RB0 = ~PORTBbits.RB0;
    }
}
Bueno nunca e aplicado delays grandes a frecuencias altas, no lo sabia :D
Saludos.
 
Última edición:
(y) Ok muchas gracias, lo probe y funciono. (y) :aplauso:



Hola de nuevo, tengo el siguiente inconveniente. Aprovechando de sus conocimientos en XC8. Baje una libreria para LCD, ya que voy a usar uno de 20x4. La libreria la descargue de este link:
https://github.com/armandas/Yet-Another-LCD-Library/blob/master/HD44780.c
se ve interesante, copie y pegue todos los header pero me genera el siguiente error:

descargado/HD44780.h:95: error: "," expected

El código que estoy usando es el siguiente.

Main.c

PHP:
/* Proyecto: GPS_DGPS_GPR
 * Detalles del Proyecto: Se encarga de administrar varias funciones del sistema
 * el cual 
 *
 * ----------------------------------------------------------------------------
 * File:   main.c
 * Author: Willian Sánchez
 * Creado el 19 de agosto de 2013, 09:10 AM
 * ----------------------------------------------------------------------------
 *
 */

#include <stdio.h>
#include <stdlib.h>
#include <pic18f4550.h>
#include <xc.h>
#include <pic18.h>
#include <delays.h>
#include "configuracion.h"
#include "descargado/HD44780.h"

//Definimos la Frecuencia del Oscilador Interno
#define _XTAL_FREQ 40000000

//Configuramos los Fuses del MCU 18F4550
// CONFIG1L
#pragma config PLLDIV = 1       // PLL Prescaler Selection bits (No prescale (4 MHz oscillator input drives PLL directly))
#pragma config CPUDIV = OSC1_PLL2// System Clock Postscaler Selection bits ([Primary Oscillator Src: /1][96 MHz PLL Src: /2])
#pragma config USBDIV = 1       // USB Clock Selection bit (used in Full-Speed USB mode only; UCFG:FSEN = 1) (USB clock source comes directly from the primary oscillator block with no postscale)

// CONFIG1H
#pragma config FOSC = HSPLL_HS  // Oscillator Selection bits (HS oscillator PLL (HS))
#pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
#pragma config IESO = OFF       // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)

// CONFIG2L
#pragma config PWRT = OFF       // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOR = OFF        // Brown-out Reset Enable bits (Brown-out Reset disabled in hardware and software)
#pragma config BORV = 3         // Brown-out Reset Voltage bits (Minimum setting)
#pragma config VREGEN = OFF     // USB Voltage Regulator Enable bit (USB voltage regulator disabled)

// CONFIG2H
#pragma config WDT = OFF        // Watchdog Timer Enable bit (WDT disabled (control is placed on the SWDTEN bit))
#pragma config WDTPS = 32768    // Watchdog Timer Postscale Select bits (1:32768)

// CONFIG3H
#pragma config CCP2MX = OFF     // CCP2 MUX bit (CCP2 input/output is multiplexed with RB3)
#pragma config PBADEN = OFF     // PORTB A/D Enable bit (PORTB<4:0> pins are configured as digital I/O on Reset)
#pragma config LPT1OSC = OFF    // Low-Power Timer 1 Oscillator Enable bit (Timer1 configured for higher power operation)
#pragma config MCLRE = ON       // MCLR Pin Enable bit (MCLR pin enabled; RE3 input pin disabled)

// CONFIG4L
#pragma config STVREN = OFF     // Stack Full/Underflow Reset Enable bit (Stack full/underflow will not cause Reset)
#pragma config LVP = ON         // Single-Supply ICSP Enable bit (Single-Supply ICSP enabled)
#pragma config XINST = OFF      // Extended Instruction Set Enable bit (Instruction set extension and Indexed Addressing mode disabled (Legacy mode))

// CONFIG5L
#pragma config CP0 = OFF        // Code Protection bit (Block 0 (000800-001FFFh) is not code-protected)
#pragma config CP1 = OFF        // Code Protection bit (Block 1 (002000-003FFFh) is not code-protected)
#pragma config CP2 = OFF        // Code Protection bit (Block 2 (004000-005FFFh) is not code-protected)
#pragma config CP3 = OFF        // Code Protection bit (Block 3 (006000-007FFFh) is not code-protected)

// CONFIG5H
#pragma config CPB = OFF        // Boot Block Code Protection bit (Boot block (000000-0007FFh) is not code-protected)
#pragma config CPD = OFF        // Data EEPROM Code Protection bit (Data EEPROM is not code-protected)

// CONFIG6L
#pragma config WRT0 = OFF       // Write Protection bit (Block 0 (000800-001FFFh) is not write-protected)
#pragma config WRT1 = OFF       // Write Protection bit (Block 1 (002000-003FFFh) is not write-protected)
#pragma config WRT2 = OFF       // Write Protection bit (Block 2 (004000-005FFFh) is not write-protected)
#pragma config WRT3 = OFF       // Write Protection bit (Block 3 (006000-007FFFh) is not write-protected)

// CONFIG6H
#pragma config WRTC = OFF       // Configuration Register Write Protection bit (Configuration registers (300000-3000FFh) are not write-protected)
#pragma config WRTB = OFF       // Boot Block Write Protection bit (Boot block (000000-0007FFh) is not write-protected)
#pragma config WRTD = OFF       // Data EEPROM Write Protection bit (Data EEPROM is not write-protected)

// CONFIG7L
#pragma config EBTR0 = OFF      // Table Read Protection bit (Block 0 (000800-001FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR1 = OFF      // Table Read Protection bit (Block 1 (002000-003FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR2 = OFF      // Table Read Protection bit (Block 2 (004000-005FFFh) is not protected from table reads executed in other blocks)
#pragma config EBTR3 = OFF      // Table Read Protection bit (Block 3 (006000-007FFFh) is not protected from table reads executed in other blocks)

// CONFIG7H
#pragma config EBTRB = OFF      // Boot Block Table Read Protection bit (Boot block (000000-0007FFh) is not protected from table reads executed in other blocks)


/*
 * 
 */
//Declaracion de Variables
int menu, apagado, posicion,temp;


//Modulo Multiplicador de los Retardos
void delay_msx10(unsigned int retardo){
    unsigned int i;
    for (i=0;i<retardo;i++){
        __delay_ms(10);
    }
}
//Modulo de Interrupciones
void interrupt isr(){
    //Verificamos si se ha encendido el MCU
    if(INTCON3bits.INT2IF==1){
        //Se ha presionado el botón Encender
        switch(apagado){
            case 0:
                apagado=1;          //Indicamos que el MCU se encuentra encendido
                posicion=2;         //Señalamos que las Posiciones
                lcd_initialize(); //Iniciamos el Módulo LCD
                //Iniciamos la Limpieza de Pantalla
                //Cargamos la Pantalla Inicial
                delay_msx10(2);   //Generamos un retardo de 2seg.
                test_led();         //Cargamos el Test de Led's
                menu++;//Pre-cargamos la siguiente Pantalla
                //Cargamos la Pantalla Siguiente
                INTCON3bits.INT2IF=0;   //Limpiamos las Banderas
                break;
            case 1:
                temp=menu;
                menu=2;
                posicion=2;
                INTCON3bits.INT2IF=0;
                //Cargamos la Pantalla de Apagado
                break;
        }
    }
}

//Módulo Principal del Programa
void main() {
    //Iniciamos las Variables
    apagado=0;
    menu=0;
    configuracion_inicial();      //Iniciamos Configuraciones
}

HD44780.h
PHP:
/**
 * Driver library for HD44780-compatible LCD displays.
 * [url]https://github.com/armandas/Yet-Another-LCD-Library[/url]
 *
 * Author: Armandas Jarusauskas ([url]http://projects.armandas.lt[/url])
 *
 * Contributors:
 *    Sylvain Prat ([url]https://github.com/sprat[/url])
 *
 * This work is licensed under a
 * Creative Commons Attribution 3.0 Unported License.
 * [url]http://creativecommons.org/licenses/by/3.0/[/url]
 *
 */

/******************************* CONFIG ***************************************/

// number of lines on the LCD
#define LCD_LINES           4
#define LCD_CHARACTERS      20
//#define LCD_HAS_BACKLIGHT

// data mask
// this must match the data pins on the port
// this program uses 4 lower bits of PORT D
#define DATA_MASK 0b00001111
// if you don't use the lower four pins
// for your data port, your data will have
// to be shifted.
// number of left shifts to do:
#define DATA_SHIFT 0

// pins
#define LCD_DATA        LATD
#define LCD_DATA_DDR    TRISD

#define LCD_RS          LATDbits.LATD0
#define LCD_RS_DDR      TRISDbits.TRISD0

#define LCD_RW          LATDbits.LATD2
#define LCD_RW_DDR      TRISDbits.TRISD2

#define LCD_EN          LATDbits.LATD1
#define LCD_EN_DDR      TRISDbits.TRISD1

/*#ifdef LCD_HAS_BACKLIGHT
#define LCD_BL_DDR    TRISGbits.TRISG4
#define LCD_BL        LATGbits.LATG4
#endif*/

// timings: depend on the instruction clock speed
// these are values for a 48 MHz CPU clock
#define LCD_ADDRESS_SETUP_DELAY() Nop()           // >40 ns
#define LCD_ENABLE_PULSE_DELAY()  Delay10TCYx(1)  // >250 ns
#define LCD_EXECUTION_DELAY()     Delay100TCYx(6) // >50 us
#define LCD_HOME_CLEAR_DELAY()    Delay10KTCYx(2) // >1.6 ms

/******************************* END OF CONFIG ********************************/

// commands
#define CLEAR_DISPLAY           0x01
#define RETURN_HOME             0x02
#define ENTRY_MODE              0x04
#define DISPLAY_CONTROL         0x08
#define CURSOR_DISPLAY_SHIFT    0x10
#define FUNCTION_SET            0x20
#define SET_CGRAM_ADDR          0x40
#define SET_DDRAM_ADDR          0x80

// ENTRY_MODE flags
#define CURSOR_INCREMENT        0x02
#define ENABLE_SHIFTING         0x01

// DISPLAY_CONTROL flags
#define DISPLAY_ON              0x04
#define CURSORS_ON               0x02
#define BLINKING_ON             0x01

// CURSOR_DISPLAY_SHIFT flags
#define DISPLAY_SHIFT           0x08
#define SHIFT_RIGHT             0x04

// FUNCTION_SET flags
#define DATA_LENGTH             0x10
#define DISPLAY_LINES           0x08
#define CHAR_FONT               0x04


// function prototypes
void lcd_flags_set(unsigned char, unsigned char, unsigned char);
void lcd_initialize(void);
void lcd_command(unsigned char);
void lcd_data(unsigned char);
void lcd_write(char *);
void lcd_write_pgm(const rom char *);
void lcd_goto(unsigned char, unsigned char);
void lcd_add_character(unsigned char, unsigned char *);

// inline functions
#define lcd_clear()         lcd_command(CLEAR_DISPLAY); LCD_HOME_CLEAR_DELAY()
#define lcd_return_home()   lcd_command(RETURN_HOME); LCD_HOME_CLEAR_DELAY()

#define lcd_display_on()    lcd_flags_set(DISPLAY_CONTROL, DISPLAY_ON, 1)
#define lcd_display_off()   lcd_flags_set(DISPLAY_CONTROL, DISPLAY_ON, 0)
#define lcd_cursor_on()     lcd_flags_set(DISPLAY_CONTROL, CURSOR_ON, 1)
#define lcd_cursor_off()    lcd_flags_set(DISPLAY_CONTROL, CURSOR_ON, 0)
#define lcd_blinking_on()   lcd_flags_set(DISPLAY_CONTROL, BLINKING_ON, 1)
#define lcd_blinking_off()  lcd_flags_set(DISPLAY_CONTROL, BLINKING_ON, 0)

/*#ifdef LCD_HAS_BACKLIGHT
#define lcd_backlight_on()  LCD_BL = 1
#define lcd_backlight_off() LCD_BL = 0
#endif*/

y tiene uno que se llama HD44780.c:

PHP:
/**
 * Driver library for HD44780-compatible LCD displays.
 * [url]https://github.com/armandas/Yet-Another-LCD-Library[/url]
 *
 * Author: Armandas Jarusauskas ([url]http://projects.armandas.lt[/url])
 *
 * Contributors:
 *    Sylvain Prat ([url]https://github.com/sprat[/url])
 *
 * This work is licensed under a
 * Creative Commons Attribution 3.0 Unported License.
 * [url]http://creativecommons.org/licenses/by/3.0/[/url]
 *
 */

#include <delays.h>
#include "HD44780.h"

// private function prototypes
static void _send_nibble(unsigned char);
static void _send_byte(unsigned char);
static void _set_4bit_interface();

// global variables
unsigned char display_config[6];

// private utility functions
static void _send_nibble(unsigned char data) {
    data <<= DATA_SHIFT;          // shift the data as required
    LCD_DATA &= ~DATA_MASK;       // clear old data bits
    LCD_DATA |= DATA_MASK & data; // put in new data bits

    LCD_EN = 1;
    LCD_ENABLE_PULSE_DELAY();
    LCD_EN = 0;
    LCD_ENABLE_PULSE_DELAY();
}

static void _send_byte(unsigned char data) {
    _send_nibble(data >> 4);
    _send_nibble(data & 0x0F);
}

static void _set_4bit_interface() {
    LCD_RS = 0;
    LCD_RW = 0;
    LCD_ADDRESS_SETUP_DELAY();
    _send_nibble(0b0010);
    LCD_EXECUTION_DELAY();
}

/**
 * Display string stored in RAM
 *
 * Usage:
 *     char message[10] = "Hello";
 *     lcd_write(message);
 */
void lcd_write(char * str) {
    unsigned char i = 0;

    while (str[i] != '\0')
        lcd_data(str[i++]);
}

/**
 * Display string stored in program memory
 *
 * Usage:
 *     lcd_write_pgm("Hello");
 */
void lcd_write_pgm(const rom char * str) {
    unsigned char i = 0;

    while (str[i] != '\0')
        lcd_data(str[i++]);
}

/**
 * Move cursor to a given location
 */
void lcd_goto(unsigned char row, unsigned char col) {
    unsigned char addr;

    switch (row) {
        case 3:
            // fall through
        case 4:
            addr = ((row - 3) * 0x40) + 0x14 + col - 1;
            break;
        default:
            // rows 1 and 2
            addr = ((row - 1) * 0x40) + col - 1;
            break;
    }

    lcd_command(SET_DDRAM_ADDR | addr);
}

/**
 * Add a custom character
 */
void lcd_add_character(unsigned char addr, unsigned char * pattern) {
    unsigned char i;

    lcd_command(SET_CGRAM_ADDR | addr << 3);
    for (i = 0; i < 8; i++)
        lcd_data(pattern[i]);
}

/**
 * Lousy function for automatic LCD initialization
 */
void lcd_initialize(void) {
    unsigned char i;

    // set relevant pins as outputs
    LCD_DATA_DDR = ~DATA_MASK;
    LCD_RS_DDR = 0;
    LCD_RW_DDR = 0;
    LCD_EN_DDR = 0;

    #ifdef LCD_HAS_BACKLIGHT
    LCD_BL_DDR = 0;
    #endif

    // initialize the display_config
    for (i = 0; i < 6; i++) {
        display_config[i] = 0x00;
    }

    _set_4bit_interface();

    // function set
    lcd_flags_set(FUNCTION_SET, DATA_LENGTH | CHAR_FONT, 0);
    lcd_flags_set(FUNCTION_SET, DISPLAY_LINES, 1);

    #ifdef LCD_HAS_BACKLIGHT
    lcd_backlight_on();
    #endif
    lcd_display_on();
    lcd_cursor_off();
    lcd_blinking_off();

    lcd_flags_set(ENTRY_MODE, CURSOR_INCREMENT, 1);
    lcd_flags_set(ENTRY_MODE, ENABLE_SHIFTING, 0);

    lcd_clear();
    lcd_return_home();
}

void lcd_command(unsigned char command) {
    LCD_RS = 0;
    LCD_RW = 0;
    LCD_ADDRESS_SETUP_DELAY();
    _send_byte(command);
    LCD_EXECUTION_DELAY();
}

void lcd_data(unsigned char data) {
    LCD_RS = 1;
    LCD_RW = 0;
    LCD_ADDRESS_SETUP_DELAY();
    _send_byte(data);
    LCD_EXECUTION_DELAY();
}

void lcd_flags_set(unsigned char instruction,
                   unsigned char flags,
                   unsigned char value)
{
    unsigned char index;

    switch (instruction) {
        case ENTRY_MODE:
            index = 0;
            break;
        case DISPLAY_CONTROL:
            index = 1;
            break;
        case CURSOR_DISPLAY_SHIFT:
            index = 2;
            break;
        case FUNCTION_SET:
            index = 3;
            break;
        case SET_CGRAM_ADDR:
            index = 4;
            break;
        case SET_DDRAM_ADDR:
            index = 5;
            break;
    }

    if (value == 0)
        display_config[index] &= ~flags; // reset flags
    else
        display_config[index] |= flags; // set flags

    lcd_command(instruction | display_config[index]);
}

Ahora nose en que puede estar fallando, ya que revise y volvi a revisar y veo que todo esta excelente.

Agradeceria su ayuda de como solucionar este problema. De verdad que me han asistido y me ha funcionado.

Gracias



acoto que el error me lo indica en la línea 95 que contiene este código:
void lcd_write_pgm(const rom char *);



acoto que el error me lo indica en la línea 95 que contiene este código:
void lcd_write_pgm(const rom char *);

:cry::confused::confused:
 
Última edición por un moderador:
Hola a todos, tengo 2 dudas en C18, uso un 18f4550 y un cristal de 8Mhz
1) como hago para poner mas de 1 segundo de retardo con la libreria delay.h? usando el maximo rango que es Delay1oKTCYx(i); (Retardos en múltiplos de 10000) donde i tiene que tomar valores hasta 255
usando mi cristal de 8Mhz llego al calculo de 1 segundo con i=200, si yo quiero poner mas segundos, por ejemplo 3 segundos, tengo que poner 3 veces Delay10KTCYx(200);?
2) otra duda, no se si esto es multihilos pero no se como resolverlo, imagínense que quiero hacer parpadear un led y a la vez hacer funcionar un motor paso a paso(al mismo tiempo) el codigo quedaria algo asi

void main(){
while(1){
parpadear led
}
while(1){
girar continuamente paso a paso
}
}
el codigo ejecuta de arriba a abajo y ese es mi problema, yo no encuentro la forma de que los codigos se ejecuten simultáneamente, que parpadee el led y que tambien gire el paso a paso a tiempos distintos,el problema es que hay 1 solo timer que es el delay, como hago para agregar mas timers en C? en delphi(pascal) los timers pueden ejecutarse al mismo tiempo, como lo hago aca? tendria que ser algo como esto?
574.bmp

desde ya gracias, saludos
 
Atrás
Arriba