ROC-RK3308-CC开发实例总结--BH1750-GY30数字光照传感器模块调试
传感器介绍
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。这里选择了前者。
驱动编写
附上写寄存器时序图,下图以发送“连续高分辨率模式”指令为例:
PS:图中,0100011(即0x23)为slave地址;00010000为“连续高分辨率模式”指令码。
下面代码根据写寄存器时序图封装了写寄存器函数,参数opecode是所要写的指令。
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 = %d\n",ret); } return ret; }
附上读寄存器时序图:
下面代码根据读寄存器时序图封装了读寄存器函数,一次读操作会得到两个字节的数据,保存在buf中
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 = %d\n",ret); return ret; } return ret; }
有了上面两个函数之后,就可以操作传感器使其工作并获得数据,先附上一张传感器工作流程图,如下:
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); //发送“连续高分辨率模式”指令 mdelay(120); //等待传感器测量完成(该模式下测量时间一般为120ms,不同模式的测量时间不同,需调整延时的时间) 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 = 0.83(lx) /********正常光照********/ # /usr/bin/bh1750demo light data = 227.50(lx) /********高强光照********/ # /usr/bin/bh1750demo light data = 39234.17(lx)
进入Firefly开发者社区可下载驱动及测试程序