How to properly use __delay_ms() in libraries in MICROCHIP XC8?

11.3k views Asked by At

I'm facing some trouble trying to create a library that calls "__delay_ms()" inside a function. Made extensive search but couldn't find the solution, nor some other explanations. I'm using XC8 v2.30 MPLAB 5.45.

I have a main function that includes the header "qc3.h":

#include <xc.h> // include standard header file

// set Config bits
#pragma config FOSC=INTOSC, PLLEN=OFF, WDTE=OFF, MCLRE=ON,
#pragma config CLKOUTEN=OFF, IESO=OFF, FCMEN=OFF,CP=OFF, CPD=OFF,BOREN=OFF
#pragma config WRT=OFF,STVREN=ON,BORV=LO,LVP=OFF

// Definitions
#define _XTAL_FREQ 500000 // this is used by the __delay_ms(xx) and __delay_us(xx) functions

#include "qc3.h"

#define LED PORTAbits.RA2




//**********************************************************************************
//***************** main routine ***********************************************
//**********************************************************************************
void main ( ) 
{
    // set up oscillator control register
    OSCCONbits.SPLLEN=0; // PLL is disabled
    OSCCONbits.IRCF=0x07; //set OSCCON IRCF bits to select OSC frequency=500Khz
    OSCCONbits.SCS=0x02; //set the SCS bits to select internal oscillator block
    // OSCON should be 0x7Ah now.

    // Set up I/O pins
    ANSELAbits.ANSELA=0; // set all analog pins to digital I/O
    ADCON0bits.ADON=0; // turn ADC off
    DACCON0bits.DACEN=0; // turn DAC off

    // PORT A Assignments (0 = OUTPUT, 1 = INPUT)
    TRISAbits.TRISA0 = 0; // RA0 = nc
    TRISAbits.TRISA1 = 0; // RA1 = nc
    TRISAbits.TRISA2 = 0; // RA2 = nc
    TRISAbits.TRISA3 = 0; // RA3 = nc (MCLR)
    TRISAbits.TRISA4 = 0; // RA4 = nc
    TRISAbits.TRISA5 = 0; // RA5 = nc
    
    
    QC3_Initialize(); // incia protocolo para handshake
         
    while(1)
    {
        __delay_ms(100);
        LED = 1;
        __delay_ms(100);
        LED = 0; 
    } 
}

qc3.h:

#ifndef QC3_H_ /* Include guard */
#define QC3_H_

/**
  Section: Included Files
*/

#include <xc.h>
#include <stdint.h>
#include <stdbool.h>

#ifdef __cplusplus // Provide C++ Compatibility

    extern "C" {

#endif

//Quick Charge 3 Pin defines
#define DP_HIGH PORTAbits.RA0
#define DM_HIGH PORTAbits.RA1

#define DP_LOW PORTAbits.RA5
#define DM_LOW PORTAbits.RA4

void QC3_Initialize(void);

//void onewireWriteBit(int b);
//unsigned char onewireReadBit();
//unsigned char onewireInit();
//unsigned char onewireReadByte();
//void onewireWriteByte(char data);
//unsigned char onewireCRC(unsigned char* addr, unsigned char len);

#ifdef __cplusplus // Provide C++ Compatibility

    }

#endif

#endif

qc3.c:

#include "qc3.h"


void QC3_Initialize(void) {
  __delay_ms(150);
 DP_HIGH = 0;
  
}

Error:

make -f nbproject/Makefile-default.mk SUBPROJECTS= .build-conf
make[1]: Entering directory 'D:/Google Drive/Projetos/Pedais/Fonte para pedais isolada/QUICK CHARGE/PIC'
make -f nbproject/Makefile-default.mk dist/default/production/PIC.production.hex
make[2]: Entering directory 'D:/Google Drive/Projetos/Pedais/Fonte para pedais isolada/QUICK CHARGE/PIC'
"D:\Program Files\Microchip\xc8\v2.30\bin\xc8-cc.exe" -mcpu=12F1840 -c -mdfp="D:/Program Files/Microchip/MPLABX/v5.45/packs/Microchip/PIC12-16F1xxx_DFP/1.2.63/xc8" -fno-short-double -fno-short-float -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -I"head_and_lib" -mwarn=-3 -Wa,-a -DXPRJ_default=default -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-osccal -mno-resetbits -mno-save-resetbits -mno-download -mno-stackcall -std=c99 -gdwarf-3 -mstack=compiled:auto:auto -o build/default/production/head_and_lib/qc3.p1 head_and_lib/qc3.c 
"D:\Program Files\Microchip\xc8\v2.30\bin\xc8-cc.exe" -mcpu=12F1840 -c -mdfp="D:/Program Files/Microchip/MPLABX/v5.45/packs/Microchip/PIC12-16F1xxx_DFP/1.2.63/xc8" -fno-short-double -fno-short-float -O0 -fasmfile -maddrqual=ignore -xassembler-with-cpp -I"head_and_lib" -mwarn=-3 -Wa,-a -DXPRJ_default=default -msummary=-psect,-class,+mem,-hex,-file -ginhx032 -Wl,--data-init -mno-keep-startup -mno-osccal -mno-resetbits -mno-save-resetbits -mno-download -mno-stackcall -std=c99 -gdwarf-3 -mstack=compiled:auto:auto -o build/default/production/source/ISOPOWER.p1 source/ISOPOWER.c 
make[2]: *** [build/default/production/head_and_lib/qc3.p1] Error 1
make[2]: *** Waiting for unfinished jobs....
head_and_lib/qc3.c:6:3: error: use of undeclared identifier '_XTAL_FREQ'
  __delay_ms(150);
  ^
D:/Program Files/Microchip/MPLABX/v5.45/packs/Microchip/PIC12-16F1xxx_DFP/1.2.63/xc8\pic\include\pic.h:101:51: note: expanded from macro '__delay_ms'
#define __delay_ms(x) _delay((unsigned long)((x)*(_XTAL_FREQ/4000.0)))
                                                  ^
1 error generated.
(908) exit status = 1
nbproject/Makefile-default.mk:123: recipe for target 'build/default/production/head_and_lib/qc3.p1' failed
make[1]: *** [.build-conf] Error 2
make: *** [.build-impl] Error 2
make[2]: Leaving directory 'D:/Google Drive/Projetos/Pedais/Fonte para pedais isolada/QUICK CHARGE/PIC'
nbproject/Makefile-default.mk:91: recipe for target '.build-conf' failed
make[1]: Leaving directory 'D:/Google Drive/Projetos/Pedais/Fonte para pedais isolada/QUICK CHARGE/PIC'
nbproject/Makefile-impl.mk:39: recipe for target '.build-impl' failed

BUILD FAILED (exit value 2, total time: 913ms)

The compiler complains (use of undeclared identifier '_XTAL_FREQ') but the header in declared AFTER the #define _XTAL_FREQ 500000. Why?

If i remove the delay of the function:

void QC3_Initialize(void) {
  __delay_ms(150);
 DP_HIGH = 0;

it builds successfully

So. "when" the QC3.c is "called" if it's never declared (even in the ".h" header)?

Why I should declare the ".h" if is the ".c" that includes the ".h"? Shouldn't it be the other way around? Or at least the ".h" to contain the ".c"?

Seems basic stuff but it's blowing my mind

Thank You

2

There are 2 answers

0
paxdiablo On

You define _XTAL_FREQ in your C source file containing main() but, since you're calling __delay_ms() in qc3.c (a separate translation unit), that's where that definition needs to exist.

The easiest fix is probably to define it in qc3.h.

0
saidasaradha On

you must give _XTAL_FREQ inside the .c file then you may get.