Linux i2c-dev驅動 用戶空間操作示例
測試芯片為at24c16
打開i2c總線節點
file = open("/dev/i2c-0", O_RDWR);
if(file < 0){
fprintf(stderr, "failed to open i2c bus\n");
return -1;
}
設置器件地址
I2C_SLAVE_FORCE 表示即使該地址的i2c設備已經有驅動程序,也強制其可用
ret = ioctl(file, force?I2C_SLAVE_FORCE:I2C_SLAVE, 0x50);
if(ret < 0){
fprintf(stderr, "failed to set slave addr\n");
return -1;
}
EEPROM AT24C02
以EEPROM AT24C02字節寫為例, 流程如下
S -> Daddr -> Waddr -> data -> T
起始 -> 器件地址 -> 目標地址 -> 數據 -> 結束
符合SMBus如下寫序列

使用I2C_SMBUS_WRITE寫2字節,詳見於linux/i2c.h中
__s32 smbus_access(int file, char read_write, __u8 Waddr, int size, union i2c_smbus_data *data)
{
struct i2c_smbus_ioctl_data msgs;
msgs.read_write = read_write;
msgs.command = Waddr;
msgs.size = size;
msgs.data = data;
if(ioctl(file, I2C_SMBUS, &msgs) < 0){
perror("error, failed to access smbus");
return -errno;
}
return 0;
}
__s32 write_byte_data(int file, __u32 Waddr, __u32 value)
{
union i2c_smbus_data data;
data.byte = value;
return smbus_access(file,I2C_SMBUS_WRITE, Waddr, I2C_SMBUS_BYTE_DATA, &data);
}
at24cxx每次寫后需要max 10ms時間處理內部寫循環
int waiting_write_cycle()
{
int ret;
struct timespec ts;
/* waiting for at24cxx internal write cycle. 10ms max */
ts.tv_sec =0;
ts.tv_nsec = 10 * 1000 * 1000;
ret = nanosleep(&ts, NULL);
if(ret < 0){
fprintf(stderr, "cannot sleep.\n");
perror("ERRNO: ");
return -errno;
}
return 0;
}
BH1750 光強傳感器
以 BH1750 光強傳感器為例
寫命令
int bh1750_write_cmd(int fd, __u8 cmd)
{
return smbus_access(fd, I2C_SMBUS_WRITE, cmd, I2C_SMBUS_BYTE, NULL);
}
讀雙字
int bh1750_read_word(int fd)
{
union i2c_smbus_data data;
struct i2c_smbus_ioctl_data msg;
msg.read_write = I2C_SMBUS_READ;
msg.size = I2C_SMBUS_WORD_DATA;
msg.data = &data;
if(ioctl(fd, I2C_SMBUS, &msg) < 0){
perror("error, failed to access smbus");
return -errno;
}
printf("raw data: %d\n", data.word);
return data.word;
}
低分辨率模式光強轉換
參考手冊如下部分

可知,單次低分辨率模式下,直接將雙字除以1.2即可
raw_data = bh1750_read_word(fd);
/* convert raw data to lux */
lux = raw_data / 1.2;
printf("lux: %f\n", lux);

包含如下頭文件
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <time.h>
