BH1750FVI是一种用于两线式串行总线接口的数字型光强度传感器集成威廉希尔官方网站
。这种集成威廉希尔官方网站
可以根据收集的光线强度数据来调整液晶或者键盘背景灯的亮度。利用它的高分辨率可以探测较大范围的光强度变化(1lx-65535lx)。产品可应用于移动电话,液晶电视,笔记本电脑,便携式游戏机,数码相机,数码摄像机,汽车定位系统,液晶显示器等。
设备树编写
&i2c1 {
clock-frequency = <400000>;
status = "okay";
...
bh1750: bh1750@23 {
status = "okay";
compatible = "bh1750-sensor";
reg = <0x23>; //slave地址
};
};
在i2c1中声明设备节点,设备有两种可选的slave地址,由ADDR端口决定,ADDR为低电平时,slave地址是0x23;ADDR为高电平时,slave地址是0x5c。笔者选择前者。
驱动编写
static int bh1750_write_reg(struct i2c_client *client, unsigned char opecode)
{
unsigned char buf[1] = {opecode}; //所要写的指令
int ret;
ret = i2c_master_send(client,buf,1);
if(ret < 0) {
printk("write_reg failed! ret = %dn",ret);
}
return ret;
}
上述代码封装了写设备寄存器函数,参数opecode是所要写的指令。
static int bh1750_read_reg(struct i2c_client *client, char *buf)
{
int ret;
ret = i2c_master_recv(client,buf,2); //接收两个字节数据,先接收高八位,后接收低八位
if(ret < 0) {
printk("read_reg: recv failed! ret = %dn",ret);
return ret;
}
return ret;
}
上述代码封装了读设备寄存器函数,一次读操作会得到两个字节的数据,保存在buf中。
然后就可以操作传感器使其工作并获得数据值,如下:
static int bh1750_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val,
int *val2,
long mask)
{
char *data = kmalloc(2,GFP_KERNEL);
int ret;
bh1750_write_reg(bh1750.client,POWERON); //发送 通电 指令
bh1750_write_reg(bh1750.client,H_RESOLUTION_MODE); //发送 连续H分辨率模式 指令
mdelay(120); //等待传感器测量完成
bh1750_read_reg(bh1750.client,data); //读取测量结果
ret = IIO_VAL_INT;
if(chan->type == IIO_TEMP){
*val = *data;
*val = (*val << 8) + *(data + 1); //数据合成
} else{
ret = -EINVAL;
}
kfree(data);
return ret;
}
测试结果
笔者编写了一个测试程序,在串口调试终端中运行可执行程序,测试结果如下:
# /usr/bin/bh1750demo
light data = 164.17(lx)
驱动,测试程序。
BH1750FVI是一种用于两线式串行总线接口的数字型光强度传感器集成威廉希尔官方网站
。这种集成威廉希尔官方网站
可以根据收集的光线强度数据来调整液晶或者键盘背景灯的亮度。利用它的高分辨率可以探测较大范围的光强度变化(1lx-65535lx)。产品可应用于移动电话,液晶电视,笔记本电脑,便携式游戏机,数码相机,数码摄像机,汽车定位系统,液晶显示器等。
设备树编写
&i2c1 {
clock-frequency = <400000>;
status = "okay";
...
bh1750: bh1750@23 {
status = "okay";
compatible = "bh1750-sensor";
reg = <0x23>; //slave地址
};
};
在i2c1中声明设备节点,设备有两种可选的slave地址,由ADDR端口决定,ADDR为低电平时,slave地址是0x23;ADDR为高电平时,slave地址是0x5c。笔者选择前者。
驱动编写
static int bh1750_write_reg(struct i2c_client *client, unsigned char opecode)
{
unsigned char buf[1] = {opecode}; //所要写的指令
int ret;
ret = i2c_master_send(client,buf,1);
if(ret < 0) {
printk("write_reg failed! ret = %dn",ret);
}
return ret;
}
上述代码封装了写设备寄存器函数,参数opecode是所要写的指令。
static int bh1750_read_reg(struct i2c_client *client, char *buf)
{
int ret;
ret = i2c_master_recv(client,buf,2); //接收两个字节数据,先接收高八位,后接收低八位
if(ret < 0) {
printk("read_reg: recv failed! ret = %dn",ret);
return ret;
}
return ret;
}
上述代码封装了读设备寄存器函数,一次读操作会得到两个字节的数据,保存在buf中。
然后就可以操作传感器使其工作并获得数据值,如下:
static int bh1750_read_raw(struct iio_dev *indio_dev,
struct iio_chan_spec const *chan,
int *val,
int *val2,
long mask)
{
char *data = kmalloc(2,GFP_KERNEL);
int ret;
bh1750_write_reg(bh1750.client,POWERON); //发送 通电 指令
bh1750_write_reg(bh1750.client,H_RESOLUTION_MODE); //发送 连续H分辨率模式 指令
mdelay(120); //等待传感器测量完成
bh1750_read_reg(bh1750.client,data); //读取测量结果
ret = IIO_VAL_INT;
if(chan->type == IIO_TEMP){
*val = *data;
*val = (*val << 8) + *(data + 1); //数据合成
} else{
ret = -EINVAL;
}
kfree(data);
return ret;
}
测试结果
笔者编写了一个测试程序,在串口调试终端中运行可执行程序,测试结果如下:
# /usr/bin/bh1750demo
light data = 164.17(lx)
驱动,测试程序。
举报