致命错误:i2c/smbus.h:没有这样的文件或目录?

sha*_*n98 7 c include raspberry-pi

我尝试编译一些代码,并在尝试编译时收到此响应:

\n
\n

./smbus.c:26:23:致命错误:i2c/smbus.h:没有这样的文件或目录

\n

编译终止。./altitude_ai.c:在函数中

\n

\xe2\x80\x98bmp085_Altitude\xe2\x80\x99:./altitude_ai.c:207:4:警告:隐式

\n

函数声明 \xe2\x80\x98pow\xe2\x80\x99 [-Wimplicit-function-declaration]

\n

./altitude_ai.c:207:14:警告:不兼容的隐式声明

\n

内置函数 \xe2\x80\x98pow\xe2\x80\x99 [默认启用]

\n
\n

这是我尝试编译的所有代码:

\n

smbus.c

\n
/*\n    smbus.c - SMBus level access helper functions\n\n    Copyright (C) 1995-97 Simon G. Vogl\n    Copyright (C) 1998-99 Frodo Looijaard <frodol@dds.nl>\n    Copyright (C) 2012    Jean Delvare <khali@linux-fr.org>\n    Copyright (C) 2012-2013 Donovan Roudabush <sharksfan98@gmail.com>\n\n    This program is free software; you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation; either version 2 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n\n    You should have received a copy of the GNU General Public License\n    along with this program; if not, write to the Free Software\n    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n    MA 02110-1301 USA.\n*/\n\n#include <errno.h>\n#include <i2c/smbus.h>\n#include <sys/ioctl.h>\n#include <linux/types.h>\n#include <linux/i2c.h>\n#include <linux/i2c-dev.h>\n#include "smbus.h"\n#define NULL 0\n\n/* Compatibility defines */\n#ifndef I2C_SMBUS_I2C_BLOCK_BROKEN\n#define I2C_SMBUS_I2C_BLOCK_BROKEN I2C_SMBUS_I2C_BLOCK_DATA\n#endif\n#ifndef I2C_FUNC_SMBUS_PEC\n#define I2C_FUNC_SMBUS_PEC I2C_FUNC_SMBUS_HWPEC_CALC\n#endif\n\n__s32 i2c_smbus_access(int file, char read_write, __u8 command,\n           int size, union i2c_smbus_data *data)\n{\n    struct i2c_smbus_ioctl_data args;\n    __s32 err;\n\n    args.read_write = read_write;\n    args.command = command;\n    args.size = size;\n    args.data = data;\n\n    err = ioctl(file, I2C_SMBUS, &args);\n    if (err == -1)\n        err = -errno;\n    return err;\n}\n\n\n__s32 i2c_smbus_write_quick(int file, __u8 value)\n{\n    return i2c_smbus_access(file, value, 0, I2C_SMBUS_QUICK, NULL);\n}\n\n__s32 i2c_smbus_read_byte(int file)\n{\n    union i2c_smbus_data data;\n    int err;\n\n    err = i2c_smbus_access(file, I2C_SMBUS_READ, 0, I2C_SMBUS_BYTE, &data);\n    if (err < 0)\n        return err;\n\n    return 0x0FF & data.byte;\n}\n\n__s32 i2c_smbus_write_byte(int file, __u8 value)\n{\n    return i2c_smbus_access(file, I2C_SMBUS_WRITE, value,\n                I2C_SMBUS_BYTE, NULL);\n}\n\n__s32 i2c_smbus_read_byte_data(int file, __u8 command)\n{\n    union i2c_smbus_data data;\n    int err;\n\n    err = i2c_smbus_access(file, I2C_SMBUS_READ, command,\n                   I2C_SMBUS_BYTE_DATA, &data);\n    if (err < 0)\n        return err;\n\n    return 0x0FF & data.byte;\n}\n\n__s32 i2c_smbus_write_byte_data(int file, __u8 command, __u8 value)\n{\n    union i2c_smbus_data data;\n    data.byte = value;\n    return i2c_smbus_access(file, I2C_SMBUS_WRITE, command,\n                I2C_SMBUS_BYTE_DATA, &data);\n}\n\n__s32 i2c_smbus_read_word_data(int file, __u8 command)\n{\n    union i2c_smbus_data data;\n    int err;\n\n    err = i2c_smbus_access(file, I2C_SMBUS_READ, command,\n                   I2C_SMBUS_WORD_DATA, &data);\n    if (err < 0)\n        return err;\n\n    return 0x0FFFF & data.word;\n}\n\n__s32 i2c_smbus_write_word_data(int file, __u8 command, __u16 value)\n{\n    union i2c_smbus_data data;\n    data.word = value;\n    return i2c_smbus_access(file, I2C_SMBUS_WRITE, command,\n                I2C_SMBUS_WORD_DATA, &data);\n}\n\n__s32 i2c_smbus_process_call(int file, __u8 command, __u16 value)\n{\n    union i2c_smbus_data data;\n    data.word = value;\n    if (i2c_smbus_access(file, I2C_SMBUS_WRITE, command,\n                 I2C_SMBUS_PROC_CALL, &data))\n        return -1;\n    else\n        return 0x0FFFF & data.word;\n}\n\n/* Returns the number of read bytes */\n__s32 i2c_smbus_read_block_data(int file, __u8 command, __u8 *values)\n{\n    union i2c_smbus_data data;\n    int i, err;\n\n    err = i2c_smbus_access(file, I2C_SMBUS_READ, command,\n                   I2C_SMBUS_BLOCK_DATA, &data);\n    if (err < 0)\n        return err;\n\n    for (i = 1; i <= data.block[0]; i++)\n        values[i-1] = data.block[i];\n    return data.block[0];\n}\n\n__s32 i2c_smbus_write_block_data(int file, __u8 command, __u8 length,\n                 const __u8 *values)\n{\n    union i2c_smbus_data data;\n    int i;\n    if (length > I2C_SMBUS_BLOCK_MAX)\n        length = I2C_SMBUS_BLOCK_MAX;\n    for (i = 1; i <= length; i++)\n        data.block[i] = values[i-1];\n    data.block[0] = length;\n    return i2c_smbus_access(file, I2C_SMBUS_WRITE, command,\n                I2C_SMBUS_BLOCK_DATA, &data);\n}\n\n/* Returns the number of read bytes */\n/* Until kernel 2.6.22, the length is hardcoded to 32 bytes. If you\n   ask for less than 32 bytes, your code will only work with kernels\n   2.6.23 and later. */\n__s32 i2c_smbus_read_i2c_block_data(int file, __u8 command, __u8 length,\n                    __u8 *values)\n{\n    union i2c_smbus_data data;\n    int i, err;\n\n    if (length > I2C_SMBUS_BLOCK_MAX)\n        length = I2C_SMBUS_BLOCK_MAX;\n    data.block[0] = length;\n\n    err = i2c_smbus_access(file, I2C_SMBUS_READ, command,\n                   length == 32 ? I2C_SMBUS_I2C_BLOCK_BROKEN :\n                I2C_SMBUS_I2C_BLOCK_DATA, &data);\n    if (err < 0)\n        return err;\n\n    for (i = 1; i <= data.block[0]; i++)\n        values[i-1] = data.block[i];\n    return data.block[0];\n}\n\n__s32 i2c_smbus_write_i2c_block_data(int file, __u8 command, __u8 length,\n                     const __u8 *values)\n{\n    union i2c_smbus_data data;\n    int i;\n    if (length > I2C_SMBUS_BLOCK_MAX)\n        length = I2C_SMBUS_BLOCK_MAX;\n    for (i = 1; i <= length; i++)\n        data.block[i] = values[i-1];\n    data.block[0] = length;\n    return i2c_smbus_access(file, I2C_SMBUS_WRITE, command,\n                I2C_SMBUS_I2C_BLOCK_BROKEN, &data);\n}\n\n/* Returns the number of read bytes */\n__s32 i2c_smbus_block_process_call(int file, __u8 command, __u8 length,\n                   __u8 *values)\n{\n    union i2c_smbus_data data;\n    int i, err;\n\n    if (length > I2C_SMBUS_BLOCK_MAX)\n        length = I2C_SMBUS_BLOCK_MAX;\n    for (i = 1; i <= length; i++)\n        data.block[i] = values[i-1];\n    data.block[0] = length;\n\n    err = i2c_smbus_access(file, I2C_SMBUS_WRITE, command,\n                   I2C_SMBUS_BLOCK_PROC_CALL, &data);\n    if (err < 0)\n        return err;\n\n    for (i = 1; i <= data.block[0]; i++)\n        values[i-1] = data.block[i];\n    return data.block[0];\n}\n
Run Code Online (Sandbox Code Playgroud)\n

smbus.h

\n
/*\n    smbus.h - SMBus level access helper functions\n\n    Copyright (C) 1995-97 Simon G. Vogl\n    Copyright (C) 1998-99 Frodo Looijaard <frodol@dds.nl>\n    Copyright (C) 2012-2013 Donovan Roudabush <sharksfan98@gmail.com>\n\n    This program is free software; you can redistribute it and/or modify\n    it under the terms of the GNU General Public License as published by\n    the Free Software Foundation; either version 2 of the License, or\n    (at your option) any later version.\n\n    This program is distributed in the hope that it will be useful,\n    but WITHOUT ANY WARRANTY; without even the implied warranty of\n    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n    GNU General Public License for more details.\n    \n    This software has been distrobuted for the Gryphon 7i series,\n    maintained Jan 2013 by Donovan Roudabush at The Ballon Project\n    This falls under GPL and Copyleft, but is intended for\n    Research use.\n\n    You should have received a copy of the GNU General Public License\n    along with this program; if not, write to the Free Software\n    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,\n    MA 02110-1301 USA.\n    \n*/\n\n#ifndef LIB_I2C_SMBUS_H\n#define LIB_I2C_SMBUS_H\n\n#include <linux/types.h>\n#include <linux/i2c.h>\n\nextern __s32 i2c_smbus_access(int file, char read_write, __u8 command,\n              int size, union i2c_smbus_data *data);\n\nextern __s32 i2c_smbus_write_quick(int file, __u8 value);\nextern __s32 i2c_smbus_read_byte(int file);\nextern __s32 i2c_smbus_write_byte(int file, __u8 value);\nextern __s32 i2c_smbus_read_byte_data(int file, __u8 command);\nextern __s32 i2c_smbus_write_byte_data(int file, __u8 command, __u8 value);\nextern __s32 i2c_smbus_read_word_data(int file, __u8 command);\nextern __s32 i2c_smbus_write_word_data(int file, __u8 command, __u16 value);\nextern __s32 i2c_smbus_process_call(int file, __u8 command, __u16 value);\n\n/* Returns the number of read bytes */\nextern __s32 i2c_smbus_read_block_data(int file, __u8 command, __u8 *values);\nextern __s32 i2c_smbus_write_block_data(int file, __u8 command, __u8 length,\n                    const __u8 *values);\n\n/* Returns the number of read bytes */\n/* Until kernel 2.6.22, the length is hardcoded to 32 bytes. If you\n   ask for less than 32 bytes, your code will only work with kernels\n   2.6.23 and later. */\nextern __s32 i2c_smbus_read_i2c_block_data(int file, __u8 command, __u8 length,\n                       __u8 *values);\nextern __s32 i2c_smbus_write_i2c_block_data(int file, __u8 command, __u8 length,\n                        const __u8 *values);\n\n/* Returns the number of read bytes */\nextern __s32 i2c_smbus_block_process_call(int file, __u8 command, __u8 length,\n                      __u8 *values);\n\n#endif /* LIB_I2C_SMBUS_H */\n
Run Code Online (Sandbox Code Playgroud)\n

海拔高度_ai.c

\n
#include <stdio.h>\n#include <stdint.h>\n#include <fcntl.h>\n#include <stdlib.h>\n\n#include <unistd.h>\n#include <linux/i2c-dev.h>\n#include <linux/i2c.h>\n#include <sys/ioctl.h>\n#include "smbus.h" \n\n#define BMP085_I2C_ADDRESS 0x77\n\nconst unsigned char BMP085_OVERSAMPLING_SETTING = 3;\n\n// Calibration values - These are stored in the BMP085\nshort int ac1;\nshort int ac2; \nshort int ac3; \nunsigned short int ac4;\nunsigned short int ac5;\nunsigned short int ac6;\nshort int b1; \nshort int b2;\nshort int mb;\nshort int mc;\nshort int md;\n\nint b5; \n\nunsigned int temperature, pressure, altitude;\n\n\n// Open a connection to the bmp085\n// Returns a file id\nint bmp085_i2c_Begin()\n{\n   int fd;\n   char *fileName = "/dev/i2c-0";\n   \n   // Open port for reading and writing\n   if ((fd = open(fileName, O_RDWR)) < 0)\n      exit(1);\n   \n   // Set the port options and set the address of the device\n   if (ioctl(fd, I2C_SLAVE, BMP085_I2C_ADDRESS) < 0) {               \n      close(fd);\n      exit(1);\n   }\n\n   return fd;\n}\n\n// Read two words from the BMP085 and supply it as a 16 bit integer\n__s32 bmp085_i2c_Read_Int(int fd, __u8 address)\n{\n   __s32 res = i2c_smbus_read_word_data(fd, address);\n   if (res < 0) {\n      close(fd);\n      exit(1);\n   }\n\n   // Convert result to 16 bits and swap bytes\n   res = ((res<<8) & 0xFF00) | ((res>>8) & 0xFF);\n\n   return res;\n}\n\n//Write a byte to the BMP085\nvoid bmp085_i2c_Write_Byte(int fd, __u8 address, __u8 value)\n{\n   if (i2c_smbus_write_byte_data(fd, address, value) < 0) {\n      close(fd);\n      exit(1);\n   }\n}\n\n// Read a block of data BMP085\nvoid bmp085_i2c_Read_Block(int fd, __u8 address, __u8 length, __u8 *values)\n{\n   if(i2c_smbus_read_i2c_block_data(fd, address,length,values)<0) {\n      close(fd);\n      exit(1);\n   }\n}\n\n\nvoid bmp085_Calibration()\n{\n   int fd = bmp085_i2c_Begin();\n   ac1 = bmp085_i2c_Read_Int(fd,0xAA);\n   ac2 = bmp085_i2c_Read_Int(fd,0xAC);\n   ac3 = bmp085_i2c_Read_Int(fd,0xAE);\n   ac4 = bmp085_i2c_Read_Int(fd,0xB0);\n   ac5 = bmp085_i2c_Read_Int(fd,0xB2);\n   ac6 = bmp085_i2c_Read_Int(fd,0xB4);\n   b1 = bmp085_i2c_Read_Int(fd,0xB6);\n   b2 = bmp085_i2c_Read_Int(fd,0xB8);\n   mb = bmp085_i2c_Read_Int(fd,0xBA);\n   mc = bmp085_i2c_Read_Int(fd,0xBC);\n   md = bmp085_i2c_Read_Int(fd,0xBE);\n   close(fd);\n}\n\n// Read the uncompensated temperature value\nunsigned int bmp085_ReadUT()\n{\n   unsigned int ut = 0;\n   int fd = bmp085_i2c_Begin();\n\n   // Write 0x2E into Register 0xF4\n   // This requests a temperature reading\n   bmp085_i2c_Write_Byte(fd,0xF4,0x2E);\n   \n   // Wait at least 4.5ms\n   usleep(5000);\n\n   // Read the two byte result from address 0xF6\n   ut = bmp085_i2c_Read_Int(fd,0xF6);\n\n   // Close the i2c file\n   close (fd);\n   \n   return ut;\n}\n\n// Read the uncompensated pressure value\nunsigned int bmp085_ReadUP()\n{\n   unsigned int up = 0;\n   int fd = bmp085_i2c_Begin();\n\n   // Write 0x34+(BMP085_OVERSAMPLING_SETTING<<6) into register 0xF4\n   // Request a pressure reading w/ oversampling setting\n   bmp085_i2c_Write_Byte(fd,0xF4,0x34 + (BMP085_OVERSAMPLING_SETTING<<6));\n\n   // Wait for conversion, delay time dependent on oversampling setting\n   usleep((2 + (3<<BMP085_OVERSAMPLING_SETTING)) * 1000);\n\n   // Read the three byte result from 0xF6\n   // 0xF6 = MSB, 0xF7 = LSB and 0xF8 = XLSB\n   __u8 values[3];\n   bmp085_i2c_Read_Block(fd, 0xF6, 3, values);\n\n   up = (((unsigned int) values[0] << 16) | ((unsigned int) values[1] << 8) | (unsigned int) values[2]) >> (8-BMP085_OVERSAMPLING_SETTING);\n\n   return up;\n}\n\n// Calculate pressure given uncalibrated pressure\n// Value returned will be in units of XXXXX\nunsigned int bmp085_GetPressure(unsigned int up)\n{\n   int x1, x2, x3, b3, b6, p;\n   unsigned int b4, b7;\n  \n   b6 = b5 - 4000;\n   // Calculate B3\n   x1 = (b2 * (b6 * b6)>>12)>>11;\n   x2 = (ac2 * b6)>>11;\n   x3 = x1 + x2;\n   b3 = (((((int)ac1)*4 + x3)<<BMP085_OVERSAMPLING_SETTING) + 2)>>2;\n  \n   // Calculate B4\n   x1 = (ac3 * b6)>>13;\n   x2 = (b1 * ((b6 * b6)>>12))>>16;\n   x3 = ((x1 + x2) + 2)>>2;\n   b4 = (ac4 * (unsigned int)(x3 + 32768))>>15;\n  \n   b7 = ((unsigned int)(up - b3) * (50000>>BMP085_OVERSAMPLING_SETTING));\n   if (b7 < 0x80000000)\n      p = (b7<<1)/b4;\n   else\n      p = (b7/b4)<<1;\n   \n   x1 = (p>>8) * (p>>8);\n   x1 = (x1 * 3038)>>16;\n   x2 = (-7357 * p)>>16;\n   p += (x1 + x2 + 3791)>>4;\n  \n   return p;\n}\n\n// Calculate temperature given uncalibrated temperature\n// Value returned will be in units of 0.1 deg C\nunsigned int bmp085_GetTemperature(unsigned int ut)\n{\n   int x1, x2;\n  \n   x1 = (((int)ut - (int)ac6)*(int)ac5) >> 15;\n   x2 = ((int)mc << 11)/(x1 + md);\n   b5 = x1 + x2;\n\n   unsigned int result = ((b5 + 8)>>4);  \n\n   return result;\n}\n\n// This Altitude part is stolen from some some unknown\n// Arduino library.  The number divided into pressure for\n// float A is derived from the local pressure as explained\n// at http://learn.adafruit.com/bmp085/using-the-bmp085.\nunsigned int bmp085_Altitude(float pressure)\n{\n   float A = pressure/101794.58;\n   float B = 1/5.25588;\n   float C = pow(A,B);\n   C = 1 - C;\n   C = C / 0.0000225577;\n\n   return C;\n}\n\nint main(int argc, char **argv)\n\n{\n\n   bmp085_Calibration();\n\n   temperature = bmp085_GetTemperature(bmp085_ReadUT());\n   pressure = bmp085_GetPressure(bmp085_ReadUP());\n        altitude = bmp085_Altitude(pressure);\n\n   printf("Temperature\\t%0.1f *F\\n", ((double)temperature)/10 * 1.8 + 32);\n   printf("Pressure\\t%0.2f hPa\\n", ((double)pressure)/100);\n        printf("Altitude\\t%0.1f Feet\\n\\n", ((double)altitude)*3.280839895);\n\n   return 0;\n}\n
Run Code Online (Sandbox Code Playgroud)\n

你们能帮我修复错误消息吗?先谢谢啦~

\n

Wil*_*haw 2

我认为代码需要两个文件,都名为 smbus.h。一个在本地目录,一个在系统include目录的子目录i2c中。您应该能够使用 find / -name "smbus.h" 2>/dev/null 等命令搜索 smbus.h 的所有实例

可能需要一些时间,但如果它解决了问题,那么等待是值得的。

我怀疑您丢失了系统文件,并且您只有 smbus.h 的一份副本。如果您确实发现另一个 smbus.h 是一个名为 i2c 的目录,您需要将包含 i2c 目录的目录添加到系统包含路径中。我不知道这是怎么做到的。我认为它是一个环境变量。

有没有关于获取 i2c 支持包的代码的说明?

sudo apt-get install <something>
Run Code Online (Sandbox Code Playgroud)

编辑:实际上,如果您确实找到了其他文件,您可能会作弊。改变

<i2c/smbus.h>
Run Code Online (Sandbox Code Playgroud)

到一个

"i2c/smbus.h"
Run Code Online (Sandbox Code Playgroud)

并添加到make文件中的编译行

-I/where/ever/the/file/was
Run Code Online (Sandbox Code Playgroud)

假设您在以下位置找到该文件

/where/ever/the/file/was/i2c/smbus.h
Run Code Online (Sandbox Code Playgroud)