完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
1、BH1750基础知识
BH1750是数字光照度传感器,IIC总线接口,常用于手机的LCD的背光中,取值范围1-65535lx。 1.1、模块工作原理图
通过原理图,确定ADDR地址为0x46+1/0 1.3、常用的地址寄存器 [tr]InstructionOpecodeComments[/tr]
当ADDR=L的时候 写寄存器指令-工作模式H-resolution 等待一会儿,时间不要超过180ms 从模块读数据指令 1.5、程序开发流程图 2、代码编写 2.1修改内核的dts源文件 设备树路径: arch/arm64/boot/dts/rockchip/rk3399pro-toybrick-prop-linux.dts 添加设备节点 &i2c6 { status = "okay"; i2c-scl-rising-time-ns = <300>; i2c-scl-falling-time-ns = <15>; clock-frequency=<400000>; ina219x47c6: ina219@47 { status = "okay"; compatible = "ina219"; reg = <0x47>; }; bh1750:bh1750@46{ status = "okay"; compatible = "bh1750"; reg = <0x46> }; }; 2.2、编写驱动文件 2.2.1、I2C读写接口 static int i2c_read_byte(struct i2c_client * client, uint8_t reg, uint8_t * buf, int len) { struct i2c_msg msgs[2]; msgs[0].addr = client->addr; msgs[0].flags = 0; msgs[0].len = 1; msgs[0].buf = ® msgs[1].addr = client->addr; msgs[1].flags = I2C_M_RD; msgs[1].len = len; msgs[1].buf = buf; if(i2c_transfer(client->adapter, msgs, 2) != 2) return 0; return 1; } static int i2c_write_byte(struct i2c_client * client, uint8_t reg, uint8_t buf) { struct i2c_msg msgs[2]; msgs[0].addr = client->addr; msgs[0].flags = 0; msgs[0].len = 1; msgs[0].buf = ® msgs[1].addr = client->addr; msgs[1].flags = 0; msgs[1].len = 1; msgs[1].buf = &buf; if(i2c_transfer(client->adapter, msgs, 2) != 2) return 0; return 1; } 2.2.2、BH1750光照度读写函数 static ssize_t gec3399_light_read(struct file *filp, char __user *buf, size_t len, loff_t *off) { int ret; char data_buf[4]; short value; memset(data_buf, 0, sizeof(data_buf)); memset(&value, 0, sizeof(value)); //printk("<0>""sizeof(data_buf) = %dnsizeof(light() = %dn",sizeof(data_buf),sizeof(value)); ret = i2c_write_byte(bh1750_client,RDADDR,PWON); if(ret ==0 ) { printk("PWON i2c_write_byte errorrn"); } ret = i2c_write_byte(bh1750_client,RDADDR,CH_RM); if(ret ==0 ) { printk("CH_RM i2c_write_byte errorrn"); } msleep(250); ret = i2c_read_byte(bh1750_client,RDADDR,data_buf,2); if(ret != 1){ printk("<0>""%s %d i2c read byte data errn",__FUNCTION__,__LINE__); return -1; } value = (data_buf[0]<<8) | (data_buf[1]<<0); printk("<0>""value = %dn",value); ret = copy_to_user(buf, &value, sizeof(value)); if(ret < 0){ printk("<0>""%s %d err copy light value to usern",__FUNCTION__,__LINE__); return -EFAULT; } return ret; } 2.2.3、BH1750的初始化入口函数 static const struct i2c_device_id i2c_id[] = { { "bh1750", 0 }, { }, /* Terminating entry */ }; static struct of_device_id i2c_match[] = { {.compatible = "bh1750" }, { }, }; MODULE_DEVICE_TABLE(i2c, i2c_id); static struct i2c_driver i2c_driver = { .driver = { .name = "bh1750", .owner = THIS_MODULE, .of_match_table = of_match_ptr(i2c_match), }, .probe = i2c_probe, .remove = i2c_remove, .id_table = i2c_id, }; module_i2c_driver(i2c_driver); 2.2.4、文件探索 static int i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { int ret; struct device_node *bh1750_node = NULL; bh1750_client = client; printk("The match successful!n"); printk("client->addr = %xn",client->addr); ret = misc_register(&gec3399_bh1750_misc); //×¢2á×?·?éè±? if(ret < 0){ printk("misc register errorn"); goto err_register_error; } bh1750_node = of_find_compatible_node(NULL, NULL,"bh1750"); if(bh1750_node == NULL){ printk("not node of compatible is bh1750n"); ret = -ENODEV; goto err_gpio_request; } printk("bh1750 dirve install succeen"); return 0; err_gpio_request: misc_deregister(&gec3399_bh1750_misc); err_register_error: return 0; } 2.2.5、杂项设备 static struct miscdevice gec3399_bh1750_misc = { .minor = MISC_DYNAMIC_MINOR, .name = "light_drv", .fops = &gec3399_light_fops, }; 2.2.6、文件操作集 通过文件操作集初始化BH1750的入口函数 static const struct file_operations gec3399_light_fops = { .owner = THIS_MODULE, .read = gec3399_light_read, }; 2.3、测试程序 #include #include #include #include #include #include #include #include int fd_light = 0; short light_value; int main(void) { int ret; //打开光照度设备节点1 fd_light = open("/dev/light_drv", O_RDWR); if(fd_light < 0) { perror("open light_drv driver"); return -1; } while(1) { //读取光照度值 ret = read(fd_light,&light_value,2); if(ret<0) { perror("read errorn"); return -1; } printf("light_value = %d n",light_value); sleep(1); } close(fd_light); return 0; } 2.4、Makefile文件 obj-m += bh1750_drv.o KERNELDIR:=/file/RK3399Pro/rk3399pro_git_repo/kernel PWD:=$(shell pwd) default: $(MAKE) -C $(KERNELDIR) M=$(PWD) modules test: aarch64-linux-gnu-gcc bh1750_test.c -o bh1750_test clean: rm -rf *.o *.order .*.cmd *.ko *.mod.c *.symvers *.tmp_versions 3、测试步骤 3.1、编译源码 在ubuntu中输入: make 得到驱动目标文件bh1750_drv.ko 输入: make test 得到测试目标文件:bh1750_test 3.2、加载驱动 在开发板命令终端输入: insmod bh1750_drv.ko 3.3、执行测试程序 在开发板命令终端输入: chmod 777 bh1750_test ./bh1750_test 4、实验现象 读取到光照度数据。 |
||
|
||
你正在撰写答案
如果你是对答案或其他答案精选点评或询问,请使用“评论”功能。
1906 浏览 1 评论
synopsys 的design ware:DW_fpv_div,浮点数除法器,默认32位下,想提升覆盖率(TMAX),如果用功能case去提升覆盖率呢?
2382 浏览 1 评论
RK3588 GStreamer调试四路鱼眼摄像头四宫格显示报错
5175 浏览 1 评论
【飞凌嵌入式OK3576-C开发板体验】RKNN神经网络-YOLO图像识别
254 浏览 0 评论
【飞凌嵌入式OK3576-C开发板体验】SSH远程登录网络配置及CAN通讯
1336 浏览 0 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-22 07:44 , Processed in 0.610959 second(s), Total 71, Slave 54 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号