Arduino:未定义的对"I2CRW::readByte(unsigned char, unsigned char)"的引用

Arduino: Undefined reference to `I2CRW::readByte(unsigned char, unsigned char)'

本文关键字:char unsigned 引用 I2CRW 未定义 Arduino readByte      更新时间:2023-10-16

在为我的 IMU 代码制作更大的库之前,我一直在制作一个库作为测试。包含库时,出现以下错误。

> \uoa.auckland.ac.nzengdfsHomecjay511DocumentsArduinosketch_may19a/sketch_may19a.ino:303:
> undefined reference to `I2CRW::writeByte(unsigned char, unsigned char,
> unsigned char)'

每当我从自定义头文件调用函数时,它就会出现。我查看了堆栈溢出的解决方案,删除构建文件夹和重建之类的事情没有帮助。

代码(取出寄存器 #define,因为有堆)

 #include <Wire.h>
#include <i2crw.h>
// Specify sensor full scale
int Gscale = 0;
int Ascale = 0;
float AccelRes, GyroRes; // scale resolutions per LSB for the sensors
int16_t accelCount[3];  // Stores the 16-bit signed accelerometer sensor output
float ax, ay, az;       // Stores the real accel value in g's
int16_t gyroCount[3];   // Stores the 16-bit signed gyro sensor output
float gx, gy, gz;       // Stores the real gyro value in degrees per seconds
float gyroBias[3] = {0, 0, 0}, accelBias[3] = {0, 0, 0}; // Bias corrections for gyro and accelerometer
float SelfTest[6];
// parameters for 6 DoF sensor fusion calculations
float GyroMeasError = PI * (40.0f / 180.0f);     // gyroscope measurement error in rads/s (start at 60 deg/s), then reduce after ~10 s to 3
float beta = sqrt(3.0f / 4.0f) * GyroMeasError;  // compute beta
float GyroMeasDrift = PI * (2.0f / 180.0f);      // gyroscope measurement drift in rad/s/s (start at 0.0 deg/s/s)
float zeta = sqrt(3.0f / 4.0f) * GyroMeasDrift;  // compute zeta, the other free parameter in the Madgwick scheme usually set to a small or zero value
float deltat = 0.0f;                              // integration interval for both filter schemes
uint32_t lastUpdate = 0, firstUpdate = 0;         // used to calculate integration interval
uint32_t Now = 0;                                 // used to calculate integration interval
float angle;
uint32_t delt_t = 0; // used to control display output rate
uint32_t count = 0;  // used to control display output rate
I2CRW i2crw;
void setup() {
  // put your setup code here, to run once:
  //Wire.begin();
  Serial.begin(38400);
  uint8_t c = i2crw.readByte(MPU9150_ADDRESS, WHO_AM_I);
    // Get magnetometer calibration from AK8975A ROM
  if (c == 0x68) // WHO_AM_I should always be 0x68
  {  
    Serial.println("MPU9150 is online...");
    MPU9150SelfTest(SelfTest); 
    Serial.println("Senpai, My acceleration trim values");
    Serial.print("x-axis self test: acceleration trim within : "); 
    Serial.print(SelfTest[0],1); 
    Serial.println("% of factory value");
    Serial.print("y-axis self test: acceleration trim within : "); 
    Serial.print(SelfTest[1],1); 
    Serial.println("% of factory value");
    Serial.print("z-axis self test: acceleration trim within : "); 
    Serial.print(SelfTest[2],1); 
    Serial.println("% of factory value");
    Serial.println("Senpai, My gyration trim values");
    Serial.print("x-axis self test: gyration trim within : "); 
    Serial.print(SelfTest[3],1); 
    Serial.println("% of factory value");
    Serial.print("y-axis self test: gyration trim within : "); 
    Serial.print(SelfTest[4],1); 
    Serial.println("% of factory value");
    Serial.print("z-axis self test: gyration trim within : "); 
    Serial.print(SelfTest[5],1); 
    Serial.println("% of factory value");
     if(SelfTest[0] < 1.0f && SelfTest[1] < 1.0f && SelfTest[2] < 1.0f && SelfTest[3] < 1.0f && SelfTest[4] < 1.0f && SelfTest[5] < 1.0f) 
      {
        Serial.println("Senpai I have Passed my Selftest!!");
        delay(3000);
        calibrateMPU9150(gyroBias, accelBias); // Calibrate gyro and accelerometers, load biases in bias registers
        Serial.println("My biases, senpai");
        Serial.print("Acceleration bias X: ");
        Serial.println((int)(1000*accelBias[0]));
        Serial.print("Acceleration bias Y: ");
        Serial.println((int)(1000*accelBias[1]));
        Serial.print("Acceleration bias Z: ");
        Serial.println((int)(1000*accelBias[2]));
        Serial.print("Gyration bias X: ");
        Serial.println(gyroBias[0],1);
        Serial.print("Gyration bias Y: ");
        Serial.println(gyroBias[1],1);
        Serial.print("Gyration bias Z: ");
        Serial.println(gyroBias[2],1);  
        delay(3000);
        initMPU9150();
        Serial.println("Awaiting command from Senpai");
      }
      else
      {
        Serial.println("Senpai, You are wrong");
      }
   }
  }

void loop() 
{
 if(i2crw.readByte(MPU9150_ADDRESS, INT_STATUS) & 0x01)
  {
    Serial.println("Data read byte set");
  }
  else
  {
    Serial.println("Data read byte NOT SET");
  }
      readAccelData(accelCount);
      //getAccelRes();
      AccelRes = 2.0/32768.0;
      readGyroData(gyroCount);
      //getGyroRes();
      GyroRes = 250.0/32768.0;
      ax = (float)accelCount[0]*AccelRes;  
      ay = (float)accelCount[1]*AccelRes;  
      az = (float)accelCount[2]*AccelRes;  
      gx = (float)gyroCount[0]*GyroRes;  
      gy = (float)gyroCount[1]*GyroRes;  
      gz = (float)gyroCount[2]*GyroRes;  
      Now = micros();
      deltat = ((Now-lastUpdate)/1000000.0f);
      lastUpdate = Now;
      angle = gz*deltat;    

    Serial.print("average rate = "); Serial.print(1.0f/deltat, 2); Serial.println(" Hz");
      Serial.println("I bought Senpai the Acceleration and Gyration Values");
      Serial.println("");
      Serial.print("ax = "); Serial.print((int)1000*ax);  
      Serial.print(" ay = "); Serial.print((int)1000*ay); 
      Serial.print(" az = "); Serial.print((int)1000*az); Serial.println(" mg");
      Serial.print("gx = "); Serial.print( gx, 1); 
      Serial.print(" gy = "); Serial.print( gy, 1); 
      Serial.print(" gz = "); Serial.print( gz, 1); Serial.println(" deg/s");
      Serial.println("");
      Serial.print("angle = "); Serial.println(angle,1);
delay(1000);
}
void readAccelData(int16_t *acceldata)
{
  uint8_t rawdata[6];
  i2crw.readBytes(MPU9150_ADDRESS, ACCEL_XOUT_H, 6, &rawdata[0]);
  acceldata[0] = (int16_t)((rawdata[0]<<8)|(rawdata[1]));  
  acceldata[1] = (int16_t)((rawdata[2]<<8)|(rawdata[3])); 
  acceldata[2] = (int16_t)((rawdata[4]<<8)|(rawdata[5])); 
}

void readGyroData(int16_t *gyrodata)
{
  uint8_t rawdata[6];
  i2crw.readBytes(MPU9150_ADDRESS, GYRO_XOUT_H, 6, &rawdata[0]);
  gyrodata[0] = (int16_t)((rawdata[0]<<8)|(rawdata[1]));  
  gyrodata[1] = (int16_t)((rawdata[2]<<8)|(rawdata[3])); 
  gyrodata[2] = (int16_t)((rawdata[4]<<8)|(rawdata[5])); 
}
void initMPU9150()
{
  i2crw.writeByte(MPU9150_ADDRESS, PWR_MGMT_1, 0x01);
  i2crw.writeByte(MPU9150_ADDRESS, CONFIG, 0x03);
  i2crw.writeByte(MPU9150_ADDRESS, SMPLRT_DIV, 0x04);
  uint8_t c = i2crw.readByte(MPU9150_ADDRESS, GYRO_CONFIG);
   i2crw.writeByte(MPU9150_ADDRESS, GYRO_CONFIG, c & ~0xE0); 
  i2crw.writeByte(MPU9150_ADDRESS, GYRO_CONFIG, c & ~0x18); 
  i2crw.writeByte(MPU9150_ADDRESS, GYRO_CONFIG, c | Gscale << 3);
  c =  i2crw.readByte(MPU9150_ADDRESS, ACCEL_CONFIG);
  i2crw.writeByte(MPU9150_ADDRESS, ACCEL_CONFIG, c & ~0xE0); // Clear self-test bits [7:5] 
  i2crw.writeByte(MPU9150_ADDRESS, ACCEL_CONFIG, c & ~0x18); // Clear AFS bits [4:3]
  i2crw.writeByte(MPU9150_ADDRESS, ACCEL_CONFIG, c | Ascale << 3);
   i2crw.writeByte(MPU9150_ADDRESS, INT_PIN_CFG, 0x22);    
   i2crw.writeByte(MPU9150_ADDRESS, INT_ENABLE, 0x01); 
}
void calibrateMPU9150(float * dest1, float * dest2)
{
  uint8_t data[12];
  uint16_t ii, packet_count, fifo_count;
  int32_t gyro_bias[3] = {0,0,0}, accel_bias[3] = {0,0,0};
  i2crw.writeByte(MPU9150_ADDRESS, PWR_MGMT_1, 0x80);
  delay(100);
  i2crw.writeByte(MPU9150_ADDRESS, PWR_MGMT_1, 0x01);  
  i2crw.writeByte(MPU9150_ADDRESS, PWR_MGMT_2, 0x00); 
  delay(200);
// Configure device for bias calculation
  i2crw.writeByte(MPU9150_ADDRESS, INT_ENABLE, 0x00);   // Disable all interrupts
  i2crw.writeByte(MPU9150_ADDRESS, FIFO_EN, 0x00);      // Disable FIFO
  i2crw.writeByte(MPU9150_ADDRESS, PWR_MGMT_1, 0x00);   // Turn on internal clock source
  i2crw.writeByte(MPU9150_ADDRESS, I2C_MST_CTRL, 0x00); // Disable I2C master
  i2crw.writeByte(MPU9150_ADDRESS, USER_CTRL, 0x00);    // Disable FIFO and I2C master modes
  i2crw.writeByte(MPU9150_ADDRESS, USER_CTRL, 0x0C);    // Reset FIFO and DMP
  delay(15);
// Configure MPU9150 gyro and accelerometer for bias calculation
  i2crw.writeByte(MPU9150_ADDRESS, CONFIG, 0x01);      // Set low-pass filter to 188 Hz
  i2crw.writeByte(MPU9150_ADDRESS, SMPLRT_DIV, 0x00);  // Set sample rate to 1 kHz
  i2crw.writeByte(MPU9150_ADDRESS, GYRO_CONFIG, 0x00);  // Set gyro full-scale to 250 degrees per second, maximum sensitivity
  i2crw.writeByte(MPU9150_ADDRESS, ACCEL_CONFIG, 0x00); // Set accelerometer full-scale to 2 g, maximum sensitivity
  uint16_t  gyrosensitivity  = 131;   // = 131 LSB/degrees/sec
  uint16_t  accelsensitivity = 16384;  // = 16384 LSB/g
  // Configure FIFO to capture accelerometer and gyro data for bias calculation
  i2crw.writeByte(MPU9150_ADDRESS, USER_CTRL, 0x40);   // Enable FIFO  
  i2crw.writeByte(MPU9150_ADDRESS, FIFO_EN, 0x78);     // Enable gyro and accelerometer sensors for FIFO  (max size 1024 bytes in MPU-9150)
  delay(80); // accumulate 80 samples in 80 milliseconds = 960 bytes
// At end of sample accumulation, turn off FIFO sensor read
  i2crw.writeByte(MPU9150_ADDRESS, FIFO_EN, 0x00);        // Disable gyro and accelerometer sensors for FIFO
  i2crw.readBytes(MPU9150_ADDRESS, FIFO_COUNTH, 2, &data[0]); // read FIFO sample count
  fifo_count = ((uint16_t)data[0] << 8) | data[1];
  packet_count = fifo_count/12;// How many sets of full gyro and accelerometer data for averaging
  for (ii = 0; ii < packet_count; ii++) {
    int16_t accel_temp[3] = {0, 0, 0}, gyro_temp[3] = {0, 0, 0};
    i2crw.readBytes(MPU9150_ADDRESS, FIFO_R_W, 12, &data[0]); // read data for averaging
    accel_temp[0] = (int16_t) (((int16_t)data[0] << 8) | data[1]  ) ;  // Form signed 16-bit integer for each sample in FIFO
    accel_temp[1] = (int16_t) (((int16_t)data[2] << 8) | data[3]  ) ;
    accel_temp[2] = (int16_t) (((int16_t)data[4] << 8) | data[5]  ) ;    
    gyro_temp[0]  = (int16_t) (((int16_t)data[6] << 8) | data[7]  ) ;
    gyro_temp[1]  = (int16_t) (((int16_t)data[8] << 8) | data[9]  ) ;
    gyro_temp[2]  = (int16_t) (((int16_t)data[10] << 8) | data[11]) ;
    accel_bias[0] += (int32_t) accel_temp[0]; // Sum individual signed 16-bit biases to get accumulated signed 32-bit biases
    accel_bias[1] += (int32_t) accel_temp[1];
    accel_bias[2] += (int32_t) accel_temp[2];
    gyro_bias[0]  += (int32_t) gyro_temp[0];
    gyro_bias[1]  += (int32_t) gyro_temp[1];
    gyro_bias[2]  += (int32_t) gyro_temp[2];
}
    accel_bias[0] /= (int32_t) packet_count; // Normalize sums to get average count biases
    accel_bias[1] /= (int32_t) packet_count;
    accel_bias[2] /= (int32_t) packet_count;
    gyro_bias[0]  /= (int32_t) packet_count;
    gyro_bias[1]  /= (int32_t) packet_count;
    gyro_bias[2]  /= (int32_t) packet_count;
  if(accel_bias[2] > 0L) {accel_bias[2] -= (int32_t) accelsensitivity;}  // Remove gravity from the z-axis accelerometer bias calculation
  else {accel_bias[2] += (int32_t) accelsensitivity;}
// Construct the gyro biases for push to the hardware gyro bias registers, which are reset to zero upon device startup
  data[0] = (-gyro_bias[0]/4  >> 8) & 0xFF; // Divide by 4 to get 32.9 LSB per deg/s to conform to expected bias input format
  data[1] = (-gyro_bias[0]/4)       & 0xFF; // Biases are additive, so change sign on calculated average gyro biases
  data[2] = (-gyro_bias[1]/4  >> 8) & 0xFF;
  data[3] = (-gyro_bias[1]/4)       & 0xFF;
  data[4] = (-gyro_bias[2]/4  >> 8) & 0xFF;
  data[5] = (-gyro_bias[2]/4)       & 0xFF;
// Push gyro biases to hardware registers
  i2crw.writeByte(MPU9150_ADDRESS, XG_OFFS_USRH, data[0]);// might not be supported in MPU9150
  i2crw.writeByte(MPU9150_ADDRESS, XG_OFFS_USRL, data[1]);
  i2crw.writeByte(MPU9150_ADDRESS, YG_OFFS_USRH, data[2]);
  i2crw.writeByte(MPU9150_ADDRESS, YG_OFFS_USRL, data[3]);
  i2crw.writeByte(MPU9150_ADDRESS, ZG_OFFS_USRH, data[4]);
  i2crw.writeByte(MPU9150_ADDRESS, ZG_OFFS_USRL, data[5]);
  dest1[0] = (float) gyro_bias[0]/(float) gyrosensitivity; // construct gyro bias in deg/s for later manual subtraction
  dest1[1] = (float) gyro_bias[1]/(float) gyrosensitivity;
  dest1[2] = (float) gyro_bias[2]/(float) gyrosensitivity;
// Construct the accelerometer biases for push to the hardware accelerometer bias registers. These registers contain
// factory trim values which must be added to the calculated accelerometer biases; on boot up these registers will hold
// non-zero values. In addition, bit 0 of the lower byte must be preserved since it is used for temperature
// compensation calculations. Accelerometer bias registers expect bias input as 2048 LSB per g, so that
// the accelerometer biases calculated above must be divided by 8.
  int32_t accel_bias_reg[3] = {0, 0, 0}; // A place to hold the factory accelerometer trim biases
  i2crw.readBytes(MPU9150_ADDRESS, XA_OFFSET_H, 2, &data[0]); // Read factory accelerometer trim values
  accel_bias_reg[0] = (int16_t) ((int16_t)data[0] << 8) | data[1];
  i2crw.readBytes(MPU9150_ADDRESS, YA_OFFSET_H, 2, &data[0]);
  accel_bias_reg[1] = (int16_t) ((int16_t)data[0] << 8) | data[1];
  i2crw.readBytes(MPU9150_ADDRESS, ZA_OFFSET_H, 2, &data[0]);
  accel_bias_reg[2] = (int16_t) ((int16_t)data[0] << 8) | data[1];
  uint32_t mask = 1uL; // Define mask for temperature compensation bit 0 of lower byte of accelerometer bias registers
  uint8_t mask_bit[3] = {0, 0, 0}; // Define array to hold mask bit for each accelerometer bias axis
  for(ii = 0; ii < 3; ii++) {
    if(accel_bias_reg[ii] & mask) mask_bit[ii] = 0x01; // If temperature compensation bit is set, record that fact in mask_bit
  }
  // Construct total accelerometer bias, including calculated average accelerometer bias from above
  accel_bias_reg[0] -= (accel_bias[0]/8); // Subtract calculated averaged accelerometer bias scaled to 2048 LSB/g (16 g full scale)
  accel_bias_reg[1] -= (accel_bias[1]/8);
  accel_bias_reg[2] -= (accel_bias[2]/8);
  data[0] = (accel_bias_reg[0] >> 8) & 0xFF;
  data[1] = (accel_bias_reg[0])      & 0xFF;
  data[1] = data[1] | mask_bit[0]; // preserve temperature compensation bit when writing back to accelerometer bias registers
  data[2] = (accel_bias_reg[1] >> 8) & 0xFF;
  data[3] = (accel_bias_reg[1])      & 0xFF;
  data[3] = data[3] | mask_bit[1]; // preserve temperature compensation bit when writing back to accelerometer bias registers
  data[4] = (accel_bias_reg[2] >> 8) & 0xFF;
  data[5] = (accel_bias_reg[2])      & 0xFF;
  data[5] = data[5] | mask_bit[2]; // preserve temperature compensation bit when writing back to accelerometer bias registers
  // Push accelerometer biases to hardware registers
  i2crw.writeByte(MPU9150_ADDRESS, XA_OFFSET_H, data[0]); // might not be supported in MPU9150
  i2crw.writeByte(MPU9150_ADDRESS, XA_OFFSET_L_TC, data[1]);
  i2crw.writeByte(MPU9150_ADDRESS, YA_OFFSET_H, data[2]);
  i2crw.writeByte(MPU9150_ADDRESS, YA_OFFSET_L_TC, data[3]);  
  i2crw.writeByte(MPU9150_ADDRESS, ZA_OFFSET_H, data[4]);
  i2crw.writeByte(MPU9150_ADDRESS, ZA_OFFSET_L_TC, data[5]);
// Output scaled accelerometer biases for manual subtraction in the main program
   dest2[0] = (float)accel_bias[0]/(float)accelsensitivity; 
   dest2[1] = (float)accel_bias[1]/(float)accelsensitivity;
   dest2[2] = (float)accel_bias[2]/(float)accelsensitivity;
}
void MPU9150SelfTest(float * testdata)
{
  uint8_t rawData[4];
  uint8_t selfTest[6];
  float factoryTrim[6];
  i2crw.writeByte(MPU9150_ADDRESS, ACCEL_CONFIG, 0xF0);
  i2crw.writeByte(MPU9150_ADDRESS, GYRO_CONFIG, 0xE0);
  delay(250);
  rawData[0] = i2crw.readByte(MPU9150_ADDRESS, SELF_TEST_X);
  rawData[1] = i2crw.readByte(MPU9150_ADDRESS, SELF_TEST_Y);
  rawData[2] = i2crw.readByte(MPU9150_ADDRESS, SELF_TEST_Z);
  rawData[3] = i2crw.readByte(MPU9150_ADDRESS, SELF_TEST_A);
 // Extract the acceleration test results first
   selfTest[0] = (rawData[0] >> 3) | (rawData[3] & 0x30) >> 4 ; // XA_TEST result is a five-bit unsigned integer
   selfTest[1] = (rawData[1] >> 3) | (rawData[3] & 0x0C) >> 2 ; // YA_TEST result is a five-bit unsigned integer
   selfTest[2] = (rawData[2] >> 3) | (rawData[3] & 0x03) ; // ZA_TEST result is a five-bit unsigned integer
   // Extract the gyration test results first
   selfTest[3] = rawData[0]  & 0x1F ; // XG_TEST result is a five-bit unsigned integer
   selfTest[4] = rawData[1]  & 0x1F ; // YG_TEST result is a five-bit unsigned integer
   selfTest[5] = rawData[2]  & 0x1F ; // ZG_TEST result is a five-bit unsigned integer    
  // Process results to allow final comparison with factory set values
   factoryTrim[0] = (4096.0*0.34)*(pow( (0.92/0.34) , (((float)selfTest[0] - 1.0)/30.0))); // FT[Xa] factory trim calculation
   factoryTrim[1] = (4096.0*0.34)*(pow( (0.92/0.34) , (((float)selfTest[1] - 1.0)/30.0))); // FT[Ya] factory trim calculation
   factoryTrim[2] = (4096.0*0.34)*(pow( (0.92/0.34) , (((float)selfTest[2] - 1.0)/30.0))); // FT[Za] factory trim calculation
   factoryTrim[3] =  ( 25.0*131.0)*(pow( 1.046 , ((float)selfTest[3] - 1.0) ));             // FT[Xg] factory trim calculation
   factoryTrim[4] =  (-25.0*131.0)*(pow( 1.046 , ((float)selfTest[4] - 1.0) ));             // FT[Yg] factory trim calculation
   factoryTrim[5] =  ( 25.0*131.0)*(pow( 1.046 , ((float)selfTest[5] - 1.0) ));             // FT[Zg] factory trim calculation
    for (int i = 0; i < 6; i++) {
     testdata[i] = 100.0 + 100.0*((float)selfTest[i] - factoryTrim[i])/factoryTrim[i]; // Report percent differences
   }
}

页眉 (.h)

/* I2C library to read and Write Bytes from MPU 9150*/
#ifndef I2CRW_h
#define I2CRW_h
#include "Arduino.h"
#include <Wire.h>
class I2CRW
{
public:
    I2CRW();
    void writeByte(uint8_t address, uint8_t subAddress, uint8_t data);
    uint8_t readByte(uint8_t address, uint8_t subAddress);
    void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest);
private:
};
#endif

。.cpp

#include "Arduino.h"
#include "i2crw.h"
#include <Wire.h>
I2CRW::I2CRW(){
}
void writeByte(uint8_t address, uint8_t subAddress, uint8_t data)
 {
     Wire.beginTransmission(address);  // Initialize the Tx buffer
    Wire.write(subAddress);           // Put slave register address in Tx buffer
    Wire.write(data);                 // Put data in Tx buffer
    Wire.endTransmission();           // Send the Tx buffer
 }
 uint8_t readByte(uint8_t address, uint8_t subAddress)
{
  uint8_t data; // `data` will store the register data   
  Wire.beginTransmission(address);         // Initialize the Tx buffer
  Wire.write(subAddress);                  // Put slave register address in Tx buffer
  Wire.endTransmission(false);             // Send the Tx buffer, but send a restart to keep connection alive
  Wire.requestFrom(address, (uint8_t) 1);  // Read one byte from slave register address 
  data = Wire.read();                      // Fill Rx buffer with result
  return data;                             // Return data read from slave register
}
void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest)
{  
  Wire.beginTransmission(address);   // Initialize the Tx buffer
  Wire.write(subAddress);            // Put slave register address in Tx buffer
  Wire.endTransmission(false);       // Send the Tx buffer, but send a restart to keep connection alive
  uint8_t i = 0;
        Wire.requestFrom(address, count);  // Read bytes from slave register address 
  while (Wire.available()) {
        dest[i++] = Wire.read(); }         // Put read results in the Rx buffer
}

任何帮助将不胜感激。不要以为你需要我的整个草图,但我把它放起来以防万一。谢谢萨汉

我想

问题是你已经用一些方法(writeByte()和两个不同的readBytes())在"i2crw.h"中声明了一个类IWCRW,但你还没有实现它们。

如果你看一下cpp文件("i2crw.cpp",我想),你已经实现了构造函数

I2CRW::I2CRW()

和三个与类无关I2CRW函数

void writeByte(uint8_t address, uint8_t subAddress, uint8_t data)
uint8_t readByte(uint8_t address, uint8_t subAddress)
void readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest)

我想您的意图是实现三IWCRW方法,但您忘记了函数名称之前的I2CRW::部分。

解决方案:在 cpp 类文件中更正方法实现中的函数实现

void IWCRW::writeByte(uint8_t address, uint8_t subAddress, uint8_t data)
uint8_t IWCRW::readByte(uint8_t address, uint8_t subAddress)
void IWCRW::readBytes(uint8_t address, uint8_t subAddress, uint8_t count, uint8_t * dest)

PS:对不起,我的英语不好。