i2c undefinierte Symbole beim Kompilieren von MPLab XC8

Ich versuche, ein einfaches I2C-Programm für einen PIC18F45K22 mit dem MPLab XC8-Compiler zu kompilieren. Ich bekomme den Fehler:

:0: Fehler: (500) undefinierte Symbole:

offenbar im Zusammenhang mit _WriteI2C1, _ReadI2C1 und _OpenI2C1 in der production.obj-Phase des Projektaufbaus.

Ich bin nicht neu in der Codierung, aber ich bin neu in der PIC-Codierung. Ich verstehe nicht, warum das passiert. Ich rufe diese Funktionen auf - siehe Code unten - und habe plib.h korrekt eingefügt, was wiederum i2c.h enthält. WriteI2C1, ReadI2C1 und OpenI2C1 sind alle in i2c.h definiert. Ich verweise nirgendwo auf die Versionen mit vorangestelltem Unterstrich, was mich denken lässt, dass der Compiler es tut. Ich verstehe nicht, warum der Compiler es falsch macht.

Kann jemand bitte dabei helfen?

    #include <xc.h>
    #include <stdint.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <plib.h>
    #include <i2c.h>


    // PIC18F45K22 Configuration Bit Settings
    // #pragma config statements should precede project file includes.
    // Use project enums instead of #define for ON and OFF.

    // CONFIG1H
    #pragma config FOSC = INTIO67   // Oscillator Selection bits (Internal oscillator clock)
    #pragma config PLLCFG = OFF     // 4X PLL Enable (Oscillator used directly)
    #pragma config PRICLKEN = ON    // Primary clock enable bit (Primary  clock is always enabled)
    #pragma config FCMEN = OFF      // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor disabled)
    #pragma config IESO = OFF       // Internal/External Oscillator Switchover bit (Oscillator Switchover mode disabled)

    // CONFIG2L
    #pragma config PWRTEN = ON      // Power-up Timer Enable bit (Power up timer enabled)
    #pragma config BOREN = OFF      // Brown-out Reset Enable bits (Brown-out Reset disabled in hardware and software)

    // CONFIG2H
    #pragma config WDTEN = OFF      // Watchdog Timer Enable bits (Watch dog timer is always disabled. SWDTEN has no effect.)

    // CONFIG3H
    #pragma config MCLRE = EXTMCLR  // MCLR Pin Enable bit (MCLR pin enabled, RE3 input pin disabled)
    #pragma config PBADEN = OFF     // PORTB A/D Enable bit (PORTB<5:0> pins are configured as digital I/O on Reset)


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




    void main(void) 
    {

       //***  I2C stuff
       // vars
       char address_w = 0xA6;   // address bits plus trailing zero
       char address_r = 0xA7;   // address bits plus trailing one
       char data;               // var to hold the data
       int result;              // result of the write function
       char temp;               // somewhere to store junk data from the buffers
       unsigned char I2C_Recv;  // to store received data

       // ports setup. SDA is on RC3, SCL on RA0
       TRISCbits.RC3 = 1;       // set RC3 to be input
       ANSELCbits.ANSC3 = 1;    // set RC3 to be analogue.

       TRISAbits.RA0 = 1;       // set RA0 to be input
       ANSELAbits.ANSA0 = 1;     // set RA0 to be analogue

       // set up / initialise I2C
       CloseI2C1();                  // definitively closed for start
       OpenI2C1(MASTER, SLEW_OFF);   // PIC is master, SLEW_OFF for 100 kHz comms
       SSP1ADD = 0x27;                 // Baud rate generator value.            

       while(1)
       {

           // using MSSP1
           IdleI2C1();      // Wait til bus is idle
           StartI2C1();     // Send START condition onto bus
           IdleI2C1();      // Wait for START condition to be implemented

           temp = SSP1BUF;  // Clear write buffer to ensure no unknown content

           // First, send Slave Address and Write
           do
           {
               result = putcI2C1(address_w);

               if (result == -1)  // write collision handler
               {
                   temp = SSP1BUF;          // clear junk out of buffer
                   SSP1CON1bits.WCOL = 0;   // clear write collision flag               
               }
           } while (result != 0);           // repeat this transmission until ACK is received. What about upper limit on this loop?


           // Now send details of the slave register we want to read...
           while(putcI2C1(0x0) !=0);        // Write char of data that's to be written to slave

           // Terminate communication from master side
           IdleI2C1();

           // Restart communication
           RestartI2C1();
           IdleI2C1();

           // clear any old data out of buffer
           temp = SSP1BUF;

           // Now send Slave Address and Read
           do
           {
               result = putcI2C1(address_r);

               if (result == -1)  // write collision handler
               {
                   temp = SSP1BUF;          // clear junk out of buffer
                   SSP1CON1bits.WCOL = 0;   // clear write collision flag               
               }
           } while (result != 0);           // repeat this transmission until ACK is received. What about upper limit on this loop?

           // now get the data
           I2C_Recv = getcI2C1();

           // Finish of data communication
           NotAckI2C1();                        // Send end of transmission please signal
           while (SSP1CON2bits.ACKEN != 0);     // Wait for ACK from slave

           // Close I2C 
           CloseI2C1();

           printf("%c",I2C_Recv);
       }

        return;  // just for C syntax best practice. No O/S to 'return' to
    }  // end of --> void main()

Der Fehler, den ich beim Build sehe, ist:

:0: Fehler: (500) undefinierte Symbole: _WriteI2C1(dist/default/production\foo.production.obj) _ReadI2C1(dist/default/production\foo.production.obj) _OpenI2C1(dist/default/production\foo.production .obj) (908) Ausgangsstatus = 1

Welche Version von XC8 und welche Version von MPLAB X?
XC8: V1.36, MPLab X: V3.25 Danke!
Schnelle zusätzliche Notiz. Nur um den roten Hering von printf zu entfernen, weiß ich, dass printf eine putch () -Definition haben sollte. Ich habe den Code sowohl damit als auch ohne das printf darin ausprobiert. Dies macht keinen Unterschied - wie Sie erwarten würden, konzentrieren sich die Build-Time-Fehler auf I2C-Funktionen.
Ein weiteres Detail: Ich habe versucht, WriteI2C1 & ReadI2C1 im obigen Code anstelle von putcI2C1 und getcI2C1 zu verwenden, aber das macht auch keinen Unterschied.

Antworten (1)

Lösung gefunden. Das lag daran, dass die Linker-Optionen nicht auf Link in der Peripheriebibliothek eingestellt waren.

Projekteigenschaften > XC8-Linker > Optionsbereich, Laufzeitauswahl > Option „Link in Peripheral Library“ muss aktiviert sein.