Estoy intentando compilar un programa I2C simple para un PIC18F45K22 usando el compilador MPLab XC8. Estoy recibiendo el error:
: 0: error: (500) símbolos indefinidos:
aparentemente relacionado con _WriteI2C1, _ReadI2C1 y _OpenI2C1 en la etapa de producción.obj de la construcción del proyecto.
No soy nuevo en la codificación, pero soy nuevo en la codificación PIC. No entiendo por qué está sucediendo esto. Estoy haciendo llamadas a esas funciones (vea el código a continuación) y he incluido correctamente plib.h, que a su vez incluye i2c.h. WriteI2C1, ReadI2C1 y OpenI2C1 están definidos en i2c.h. No estoy haciendo referencia al subrayado de las versiones prefijadas de estos en ningún lugar, lo que me hace pensar que el compilador lo está haciendo. No entiendo por qué el compilador parece estar equivocado.
¿Puede alguien ayudarme con esto, por favor?
#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()
El error que estoy viendo en la compilación es:
: 0: error: (500) símbolos indefinidos: _WriteI2C1 (dist / default / production \ foo.production.obj) _ReadI2C1 (dist / default / production \ foo.production.obj) _OpenI2C1 (dist / default / production \ foo.production.obj) (908) exit status = 1