2013-02-21 705 views
0

我試圖編譯一些代碼,我收到這個響應,同時試圖編譯:致命錯誤:i2c/smbus.h:沒有這樣的文件或目錄?

./smbus.c:26:23: fatal error: i2c/smbus.h: No such file or directory

compilation terminated. ./altitude_ai.c: In function

‘bmp085_Altitude’: ./altitude_ai.c:207:4: warning: implicit

declaration of function ‘pow’ [-Wimplicit-function-declaration]

./altitude_ai.c:207:14: warning: incompatible implicit declaration of

built-in function ‘pow’ [enabled by default]

這是我試圖編譯代碼:

smbus.c

/* 
    smbus.c - SMBus level access helper functions 

    Copyright (C) 1995-97 Simon G. Vogl 
    Copyright (C) 1998-99 Frodo Looijaard <[email protected]> 
    Copyright (C) 2012 Jean Delvare <[email protected]> 
    Copyright (C) 2012-2013 Donovan Roudabush <[email protected]> 

    This program is free software; you can redistribute it and/or modify 
    it under the terms of the GNU General Public License as published by 
    the Free Software Foundation; either version 2 of the License, or 
    (at your option) any later version. 

    This program is distributed in the hope that it will be useful, 
    but WITHOUT ANY WARRANTY; without even the implied warranty of 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
    GNU General Public License for more details. 

    You should have received a copy of the GNU General Public License 
    along with this program; if not, write to the Free Software 
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
    MA 02110-1301 USA. 
*/ 

#include <errno.h> 
#include <i2c/smbus.h> 
#include <sys/ioctl.h> 
#include <linux/types.h> 
#include <linux/i2c.h> 
#include <linux/i2c-dev.h> 
#include "smbus.h" 
#define NULL 0 

/* Compatibility defines */ 
#ifndef I2C_SMBUS_I2C_BLOCK_BROKEN 
#define I2C_SMBUS_I2C_BLOCK_BROKEN I2C_SMBUS_I2C_BLOCK_DATA 
#endif 
#ifndef I2C_FUNC_SMBUS_PEC 
#define I2C_FUNC_SMBUS_PEC I2C_FUNC_SMBUS_HWPEC_CALC 
#endif 

__s32 i2c_smbus_access(int file, char read_write, __u8 command, 
      int size, union i2c_smbus_data *data) 
{ 
    struct i2c_smbus_ioctl_data args; 
    __s32 err; 

    args.read_write = read_write; 
    args.command = command; 
    args.size = size; 
    args.data = data; 

    err = ioctl(file, I2C_SMBUS, &args); 
    if (err == -1) 
     err = -errno; 
    return err; 
} 


__s32 i2c_smbus_write_quick(int file, __u8 value) 
{ 
    return i2c_smbus_access(file, value, 0, I2C_SMBUS_QUICK, NULL); 
} 

__s32 i2c_smbus_read_byte(int file) 
{ 
    union i2c_smbus_data data; 
    int err; 

    err = i2c_smbus_access(file, I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &data); 
    if (err < 0) 
     return err; 

    return 0x0FF & data.byte; 
} 

__s32 i2c_smbus_write_byte(int file, __u8 value) 
{ 
    return i2c_smbus_access(file, I2C_SMBUS_WRITE, value, 
       I2C_SMBUS_BYTE, NULL); 
} 

__s32 i2c_smbus_read_byte_data(int file, __u8 command) 
{ 
    union i2c_smbus_data data; 
    int err; 

    err = i2c_smbus_access(file, I2C_SMBUS_READ, command, 
        I2C_SMBUS_BYTE_DATA, &data); 
    if (err < 0) 
     return err; 

    return 0x0FF & data.byte; 
} 

__s32 i2c_smbus_write_byte_data(int file, __u8 command, __u8 value) 
{ 
    union i2c_smbus_data data; 
    data.byte = value; 
    return i2c_smbus_access(file, I2C_SMBUS_WRITE, command, 
       I2C_SMBUS_BYTE_DATA, &data); 
} 

__s32 i2c_smbus_read_word_data(int file, __u8 command) 
{ 
    union i2c_smbus_data data; 
    int err; 

    err = i2c_smbus_access(file, I2C_SMBUS_READ, command, 
        I2C_SMBUS_WORD_DATA, &data); 
    if (err < 0) 
     return err; 

    return 0x0FFFF & data.word; 
} 

__s32 i2c_smbus_write_word_data(int file, __u8 command, __u16 value) 
{ 
    union i2c_smbus_data data; 
    data.word = value; 
    return i2c_smbus_access(file, I2C_SMBUS_WRITE, command, 
       I2C_SMBUS_WORD_DATA, &data); 
} 

__s32 i2c_smbus_process_call(int file, __u8 command, __u16 value) 
{ 
    union i2c_smbus_data data; 
    data.word = value; 
    if (i2c_smbus_access(file, I2C_SMBUS_WRITE, command, 
       I2C_SMBUS_PROC_CALL, &data)) 
     return -1; 
    else 
     return 0x0FFFF & data.word; 
} 

/* Returns the number of read bytes */ 
__s32 i2c_smbus_read_block_data(int file, __u8 command, __u8 *values) 
{ 
    union i2c_smbus_data data; 
    int i, err; 

    err = i2c_smbus_access(file, I2C_SMBUS_READ, command, 
        I2C_SMBUS_BLOCK_DATA, &data); 
    if (err < 0) 
     return err; 

    for (i = 1; i <= data.block[0]; i++) 
     values[i-1] = data.block[i]; 
    return data.block[0]; 
} 

__s32 i2c_smbus_write_block_data(int file, __u8 command, __u8 length, 
       const __u8 *values) 
{ 
    union i2c_smbus_data data; 
    int i; 
    if (length > I2C_SMBUS_BLOCK_MAX) 
     length = I2C_SMBUS_BLOCK_MAX; 
    for (i = 1; i <= length; i++) 
     data.block[i] = values[i-1]; 
    data.block[0] = length; 
    return i2c_smbus_access(file, I2C_SMBUS_WRITE, command, 
       I2C_SMBUS_BLOCK_DATA, &data); 
} 

/* Returns the number of read bytes */ 
/* Until kernel 2.6.22, the length is hardcoded to 32 bytes. If you 
    ask for less than 32 bytes, your code will only work with kernels 
    2.6.23 and later. */ 
__s32 i2c_smbus_read_i2c_block_data(int file, __u8 command, __u8 length, 
        __u8 *values) 
{ 
    union i2c_smbus_data data; 
    int i, err; 

    if (length > I2C_SMBUS_BLOCK_MAX) 
     length = I2C_SMBUS_BLOCK_MAX; 
    data.block[0] = length; 

    err = i2c_smbus_access(file, I2C_SMBUS_READ, command, 
        length == 32 ? I2C_SMBUS_I2C_BLOCK_BROKEN : 
       I2C_SMBUS_I2C_BLOCK_DATA, &data); 
    if (err < 0) 
     return err; 

    for (i = 1; i <= data.block[0]; i++) 
     values[i-1] = data.block[i]; 
    return data.block[0]; 
} 

__s32 i2c_smbus_write_i2c_block_data(int file, __u8 command, __u8 length, 
        const __u8 *values) 
{ 
    union i2c_smbus_data data; 
    int i; 
    if (length > I2C_SMBUS_BLOCK_MAX) 
     length = I2C_SMBUS_BLOCK_MAX; 
    for (i = 1; i <= length; i++) 
     data.block[i] = values[i-1]; 
    data.block[0] = length; 
    return i2c_smbus_access(file, I2C_SMBUS_WRITE, command, 
       I2C_SMBUS_I2C_BLOCK_BROKEN, &data); 
} 

/* Returns the number of read bytes */ 
__s32 i2c_smbus_block_process_call(int file, __u8 command, __u8 length, 
        __u8 *values) 
{ 
    union i2c_smbus_data data; 
    int i, err; 

    if (length > I2C_SMBUS_BLOCK_MAX) 
     length = I2C_SMBUS_BLOCK_MAX; 
    for (i = 1; i <= length; i++) 
     data.block[i] = values[i-1]; 
    data.block[0] = length; 

    err = i2c_smbus_access(file, I2C_SMBUS_WRITE, command, 
        I2C_SMBUS_BLOCK_PROC_CALL, &data); 
    if (err < 0) 
     return err; 

    for (i = 1; i <= data.block[0]; i++) 
     values[i-1] = data.block[i]; 
    return data.block[0]; 
} 

smbus.h

/* 
    smbus.h - SMBus level access helper functions 

    Copyright (C) 1995-97 Simon G. Vogl 
    Copyright (C) 1998-99 Frodo Looijaard <[email protected]> 
    Copyright (C) 2012-2013 Donovan Roudabush <[email protected]> 

    This program is free software; you can redistribute it and/or modify 
    it under the terms of the GNU General Public License as published by 
    the Free Software Foundation; either version 2 of the License, or 
    (at your option) any later version. 

    This program is distributed in the hope that it will be useful, 
    but WITHOUT ANY WARRANTY; without even the implied warranty of 
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
    GNU General Public License for more details. 

    This software has been distrobuted for the Gryphon 7i series, 
    maintained Jan 2013 by Donovan Roudabush at The Ballon Project 
    This falls under GPL and Copyleft, but is intended for 
    Research use. 

    You should have received a copy of the GNU General Public License 
    along with this program; if not, write to the Free Software 
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 
    MA 02110-1301 USA. 

*/ 

#ifndef LIB_I2C_SMBUS_H 
#define LIB_I2C_SMBUS_H 

#include <linux/types.h> 
#include <linux/i2c.h> 

extern __s32 i2c_smbus_access(int file, char read_write, __u8 command, 
       int size, union i2c_smbus_data *data); 

extern __s32 i2c_smbus_write_quick(int file, __u8 value); 
extern __s32 i2c_smbus_read_byte(int file); 
extern __s32 i2c_smbus_write_byte(int file, __u8 value); 
extern __s32 i2c_smbus_read_byte_data(int file, __u8 command); 
extern __s32 i2c_smbus_write_byte_data(int file, __u8 command, __u8 value); 
extern __s32 i2c_smbus_read_word_data(int file, __u8 command); 
extern __s32 i2c_smbus_write_word_data(int file, __u8 command, __u16 value); 
extern __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value); 

/* Returns the number of read bytes */ 
extern __s32 i2c_smbus_read_block_data(int file, __u8 command, __u8 *values); 
extern __s32 i2c_smbus_write_block_data(int file, __u8 command, __u8 length, 
        const __u8 *values); 

/* Returns the number of read bytes */ 
/* Until kernel 2.6.22, the length is hardcoded to 32 bytes. If you 
    ask for less than 32 bytes, your code will only work with kernels 
    2.6.23 and later. */ 
extern __s32 i2c_smbus_read_i2c_block_data(int file, __u8 command, __u8 length, 
         __u8 *values); 
extern __s32 i2c_smbus_write_i2c_block_data(int file, __u8 command, __u8 length, 
         const __u8 *values); 

/* Returns the number of read bytes */ 
extern __s32 i2c_smbus_block_process_call(int file, __u8 command, __u8 length, 
         __u8 *values); 

#endif /* LIB_I2C_SMBUS_H */ 

altitude_ai.c

#include <stdio.h> 
#include <stdint.h> 
#include <fcntl.h> 
#include <stdlib.h> 

#include <unistd.h> 
#include <linux/i2c-dev.h> 
#include <linux/i2c.h> 
#include <sys/ioctl.h> 
#include "smbus.h" 

#define BMP085_I2C_ADDRESS 0x77 

const unsigned char BMP085_OVERSAMPLING_SETTING = 3; 

// Calibration values - These are stored in the BMP085 
short int ac1; 
short int ac2; 
short int ac3; 
unsigned short int ac4; 
unsigned short int ac5; 
unsigned short int ac6; 
short int b1; 
short int b2; 
short int mb; 
short int mc; 
short int md; 

int b5; 

unsigned int temperature, pressure, altitude; 


// Open a connection to the bmp085 
// Returns a file id 
int bmp085_i2c_Begin() 
{ 
    int fd; 
    char *fileName = "/dev/i2c-0"; 

    // Open port for reading and writing 
    if ((fd = open(fileName, O_RDWR)) < 0) 
     exit(1); 

    // Set the port options and set the address of the device 
    if (ioctl(fd, I2C_SLAVE, BMP085_I2C_ADDRESS) < 0) {    
     close(fd); 
     exit(1); 
    } 

    return fd; 
} 

// Read two words from the BMP085 and supply it as a 16 bit integer 
__s32 bmp085_i2c_Read_Int(int fd, __u8 address) 
{ 
    __s32 res = i2c_smbus_read_word_data(fd, address); 
    if (res < 0) { 
     close(fd); 
     exit(1); 
    } 

    // Convert result to 16 bits and swap bytes 
    res = ((res<<8) & 0xFF00) | ((res>>8) & 0xFF); 

    return res; 
} 

//Write a byte to the BMP085 
void bmp085_i2c_Write_Byte(int fd, __u8 address, __u8 value) 
{ 
    if (i2c_smbus_write_byte_data(fd, address, value) < 0) { 
     close(fd); 
     exit(1); 
    } 
} 

// Read a block of data BMP085 
void bmp085_i2c_Read_Block(int fd, __u8 address, __u8 length, __u8 *values) 
{ 
    if(i2c_smbus_read_i2c_block_data(fd, address,length,values)<0) { 
     close(fd); 
     exit(1); 
    } 
} 


void bmp085_Calibration() 
{ 
    int fd = bmp085_i2c_Begin(); 
    ac1 = bmp085_i2c_Read_Int(fd,0xAA); 
    ac2 = bmp085_i2c_Read_Int(fd,0xAC); 
    ac3 = bmp085_i2c_Read_Int(fd,0xAE); 
    ac4 = bmp085_i2c_Read_Int(fd,0xB0); 
    ac5 = bmp085_i2c_Read_Int(fd,0xB2); 
    ac6 = bmp085_i2c_Read_Int(fd,0xB4); 
    b1 = bmp085_i2c_Read_Int(fd,0xB6); 
    b2 = bmp085_i2c_Read_Int(fd,0xB8); 
    mb = bmp085_i2c_Read_Int(fd,0xBA); 
    mc = bmp085_i2c_Read_Int(fd,0xBC); 
    md = bmp085_i2c_Read_Int(fd,0xBE); 
    close(fd); 
} 

// Read the uncompensated temperature value 
unsigned int bmp085_ReadUT() 
{ 
    unsigned int ut = 0; 
    int fd = bmp085_i2c_Begin(); 

    // Write 0x2E into Register 0xF4 
    // This requests a temperature reading 
    bmp085_i2c_Write_Byte(fd,0xF4,0x2E); 

    // Wait at least 4.5ms 
    usleep(5000); 

    // Read the two byte result from address 0xF6 
    ut = bmp085_i2c_Read_Int(fd,0xF6); 

    // Close the i2c file 
    close (fd); 

    return ut; 
} 

// Read the uncompensated pressure value 
unsigned int bmp085_ReadUP() 
{ 
    unsigned int up = 0; 
    int fd = bmp085_i2c_Begin(); 

    // Write 0x34+(BMP085_OVERSAMPLING_SETTING<<6) into register 0xF4 
    // Request a pressure reading w/ oversampling setting 
    bmp085_i2c_Write_Byte(fd,0xF4,0x34 + (BMP085_OVERSAMPLING_SETTING<<6)); 

    // Wait for conversion, delay time dependent on oversampling setting 
    usleep((2 + (3<<BMP085_OVERSAMPLING_SETTING)) * 1000); 

    // Read the three byte result from 0xF6 
    // 0xF6 = MSB, 0xF7 = LSB and 0xF8 = XLSB 
    __u8 values[3]; 
    bmp085_i2c_Read_Block(fd, 0xF6, 3, values); 

    up = (((unsigned int) values[0] << 16) | ((unsigned int) values[1] << 8) | (unsigned int) values[2]) >> (8-BMP085_OVERSAMPLING_SETTING); 

    return up; 
} 

// Calculate pressure given uncalibrated pressure 
// Value returned will be in units of XXXXX 
unsigned int bmp085_GetPressure(unsigned int up) 
{ 
    int x1, x2, x3, b3, b6, p; 
    unsigned int b4, b7; 

    b6 = b5 - 4000; 
    // Calculate B3 
    x1 = (b2 * (b6 * b6)>>12)>>11; 
    x2 = (ac2 * b6)>>11; 
    x3 = x1 + x2; 
    b3 = (((((int)ac1)*4 + x3)<<BMP085_OVERSAMPLING_SETTING) + 2)>>2; 

    // Calculate B4 
    x1 = (ac3 * b6)>>13; 
    x2 = (b1 * ((b6 * b6)>>12))>>16; 
    x3 = ((x1 + x2) + 2)>>2; 
    b4 = (ac4 * (unsigned int)(x3 + 32768))>>15; 

    b7 = ((unsigned int)(up - b3) * (50000>>BMP085_OVERSAMPLING_SETTING)); 
    if (b7 < 0x80000000) 
     p = (b7<<1)/b4; 
    else 
     p = (b7/b4)<<1; 

    x1 = (p>>8) * (p>>8); 
    x1 = (x1 * 3038)>>16; 
    x2 = (-7357 * p)>>16; 
    p += (x1 + x2 + 3791)>>4; 

    return p; 
} 

// Calculate temperature given uncalibrated temperature 
// Value returned will be in units of 0.1 deg C 
unsigned int bmp085_GetTemperature(unsigned int ut) 
{ 
    int x1, x2; 

    x1 = (((int)ut - (int)ac6)*(int)ac5) >> 15; 
    x2 = ((int)mc << 11)/(x1 + md); 
    b5 = x1 + x2; 

    unsigned int result = ((b5 + 8)>>4); 

    return result; 
} 

// This Altitude part is stolen from some some unknown 
// Arduino library. The number divided into pressure for 
// float A is derived from the local pressure as explained 
// at http://learn.adafruit.com/bmp085/using-the-bmp085. 
unsigned int bmp085_Altitude(float pressure) 
{ 
    float A = pressure/101794.58; 
    float B = 1/5.25588; 
    float C = pow(A,B); 
    C = 1 - C; 
    C = C/0.0000225577; 

    return C; 
} 

int main(int argc, char **argv) 

{ 

    bmp085_Calibration(); 

    temperature = bmp085_GetTemperature(bmp085_ReadUT()); 
    pressure = bmp085_GetPressure(bmp085_ReadUP()); 
     altitude = bmp085_Altitude(pressure); 

    printf("Temperature\t%0.1f *F\n", ((double)temperature)/10 * 1.8 + 32); 
    printf("Pressure\t%0.2f hPa\n", ((double)pressure)/100); 
     printf("Altitude\t%0.1f Feet\n\n", ((double)altitude)*3.280839895); 

    return 0; 
} 

你們可以幫我修復該錯誤消息?預先感謝您〜

+1

文件你是什麼包括路徑?你有Makefile嗎? – 2013-02-21 01:11:37

+0

我認爲像dev/i2c-0或類似的東西 – sharksfan98 2013-02-21 19:43:34

+1

你將不得不將該目錄添加到你的編譯路徑,以便它可以找到與文件smbus.h的目錄i2c。 – 2013-02-21 22:03:00

回答

1

我認爲代碼期望兩個文件都被稱爲smbus.h。一個在本地目錄中,另一個在系統中包含子目錄i2c中的目錄。您應該能夠搜索smbus.h的所有實例,使用如下命令: find/-name「smbus.h」2>/dev/null

可能需要一些時間,但值得等待,如果它解決了問題。

我懷疑你錯過了系統文件,你只有smbus.h的一個副本。 如果您確實找到了另一個smbus.h,那麼需要將包含i2c目錄的目錄添加到您的系統包含路徑中。我不確定這是如何完成的。我認爲它是一個環境變量。

是否有任何有關獲取i2c支持包的代碼說明?

sudo apt-get install <something> 

編輯: 其實你能欺騙了一下,如果你發現其他文件。更改

<i2c/smbus.h> 

"i2c/smbus.h" 

,並添加到編譯行make文件

-I/where/ever/the/file/was 

假設你發現

/where/ever/the/file/was/i2c/smbus.h 
相關問題