01-BH1750驱动开发

  • 1、BH1750基础知识
    • 1.1、模块工作原理图
    • 1.2、原理图
    • 1.3、常用的地址寄存器
    • 1.4、获取光照度值
    • 1.5、程序开发流程图
  • 2、代码编写
    • 2.1修改内核的dts源文件
    • 2.2、编写驱动文件
      • 2.2.1、I^2^C读写接口
      • 2.2.2、BH1750光照度读写函数
      • 2.2.3、BH1750的初始化入口函数
      • 2.2.4、文件探索
      • 2.2.5、杂项设备
      • 2.2.6、文件操作集
    • 2.3、测试程序
    • 2.4、Makefile文件
  • 3、测试步骤
    • 3.1、编译源码
    • 3.2、加载驱动
    • 3.3、执行测试程序
  • 4、实验现象

1、BH1750基础知识

BH1750是数字光照度传感器,IIC总线接口,常用于手机的LCD的背光中,取值范围1-65535lx

1.1、模块工作原理图

  1. PD,感光材料
  2. AMP,运放电路转换为当前的电压值
  3. ADC,AD转换为16位的数值
  4. Logic+I2C接口,IIC接口,如果ADDR接高电平则从机地址为1011100+0/1,低电平则从机地址为0100011+0/1
  5. OSC,内部逻辑的CLK

1.2、原理图


通过原理图,确定ADDR地址为0x46+1/0

1.3、常用的地址寄存器

Instruction Opecode Comments
Power On 0000_0001 等待测量指令
Continuously H-Resolution Mode 0001_0000 测量的精确到1lx,转换时间120ms
Continuously H-Resolution Mode2 0001_0001 测量的精确到0.5lx,转换时间120ms
Continuously L-Resolution Mode 0001_0011 测量的精确到4lx,转换时间16ms

1.4、获取光照度值

当ADDR=L的时候
写寄存器指令-工作模式H-resolution

等待一会儿,时间不要超过180ms

从模块读数据指令

1.5、程序开发流程图

Created with Raphaël 2.3.0开始打开电源:Power ON设置模式:H-Resolution Mode数据读取数据正确?反馈给上层应用结束yesno

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 = &reg;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 = &reg;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) = %d\nsizeof(light() = %d\n",sizeof(data_buf),sizeof(value));ret = i2c_write_byte(bh1750_client,RDADDR,PWON);if(ret ==0 ){printk("PWON i2c_write_byte error\r\n");}ret = i2c_write_byte(bh1750_client,RDADDR,CH_RM);if(ret ==0 ){printk("CH_RM i2c_write_byte error\r\n");}msleep(250);ret = i2c_read_byte(bh1750_client,RDADDR,data_buf,2);if(ret != 1){printk("<0>""%s %d i2c read byte data err\n",__FUNCTION__,__LINE__);return -1;}value = (data_buf[0]<<8) | (data_buf[1]<<0);printk("<0>""value = %d\n",value);ret = copy_to_user(buf, &value, sizeof(value));if(ret < 0){printk("<0>""%s %d err copy light value to user\n",__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 = %x\n",client->addr);ret = misc_register(&gec3399_bh1750_misc);   //×¢2á×?·?éè±?if(ret < 0){printk("misc register error\n");goto err_register_error;      }bh1750_node = of_find_compatible_node(NULL, NULL,"bh1750");if(bh1750_node == NULL){printk("not node of compatible is bh1750\n");ret = -ENODEV;goto err_gpio_request;}printk("bh1750 dirve install succee\n");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 <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <poll.h>int fd_light = 0;short light_value;  int main(void)
{int ret;//打开光照度设备节点1fd_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 error\n");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、实验现象

读取到光照度数据

基于RK3399Pro的BH1750驱动开发相关推荐

  1. 基于MTD的NAND驱动开发(二)

    基于MTD的NAND驱动开发(二) 基于MTD的NAND驱动开发(三) http://blog.csdn.net/leibniz_zsu/article/details/4977853 http:// ...

  2. 基于V4L2的视频驱动开发(2) 华清远见 刘洪涛

    基于V4L2的视频驱动开发(2) 华清远见 刘洪涛 三.            V4L2 API及数据结构 V4L2是V4L的升级版本,为linux下视频设备程序提供了一套接口规范.包括一套数据结构和 ...

  3. 基于V4L2的视频驱动开发

    基于V4L2的视频驱动开发 编写基于V4L2视频驱动主要涉及到以下几个知识点: ●摄像头方面的知识 要了解选用的摄像头的特性,包括访问控制方法.各种参数的配置方法.信号输出类型等. ●Camera解码 ...

  4. 分享自清客 《基于MTD的NAND驱动开发(完) (转)》

    url:http://blog.csdn.net/mianyy/article/details/6712631 六.NAND驱动中的坏块管理 由 于NAND Flash的现有工艺不能保证NAND的Me ...

  5. 基于V4L2的视频驱动开发(1)

    编写基于V4L2视频驱动主要涉及到以下几个知识点: l         摄像头方面的知识 要了解选用的摄像头的特性,包括访问控制方法.各种参数的配置方法.信号输出类型等. l         Came ...

  6. 基于V4L2的视频驱动开发(1)---Camera

    编写基于V4L2视频驱动主要涉及到以下几个知识点: ●    摄像头方面的知识                 要了解选用的摄像头的特性,包括访问控制方法.各种参数的配置方法.信号输出类型等. ●   ...

  7. vxWorks6.6下基于vxBus的以太网驱动开发

    最近更换mpc8313的phy芯片,由原来的lxt972Phy更换为DP83849I,在此记录下本人在驱动开发过程中的点滴记录,以备日后查询,基于vxbus的网络驱动,vxBus驱动的注册遵循一致的方 ...

  8. 基于RK3399Pro的USB驱动-鼠标键值获取

    目录 USB协议简介 USB 设备基础概念 设备描述符 配置描述符 接口描述符 端点描述符 字符串描述符 管道 USB 端点分类 USB 总线驱动概念 驱动程序讲解 代码编写: 函数入口 probe函 ...

  9. 基于arm-linux的防火墙设计,基于ARM9的Linux驱动开发及防火墙设计

    摘要: 随着通信与信息科技.数字与IC设计技术在我们的日常生活及工作中的的迅猛普及,嵌入式系统设计正在成为现代信息技术中的主流技术.本文主要阐述了嵌入式Linux的概念.基础.网络结构.网络设备驱动程 ...

  10. 基于RK3399的LED驱动开发

    1.添加设备树 在设备树 arch/arm64/boot/dts/rockchip/rk3399-firefly-linux.dts 中添加 gpio-led{status = "okay& ...

最新文章

  1. 挨踢人生路--记我的10年18家工作经历 - 后记
  2. Swift之SDWebImage第三方框架
  3. PAT计算出2~N所有素数
  4. java_eclipse_maven_svn_主题彩色插件_全屏插件
  5. 字体大小自适应屏幕分辨率 CSS解决方案
  6. cass插件_第009期分享:Cass插件合集
  7. Xgboost版本对比(原生版与sklearn接口版)
  8. caffe的caffe.proto
  9. 超详细 CSS动画-animation
  10. 单片机c语言 课程设计报告,51单片机课程设计报告.doc
  11. 极坐标格式下的二维傅里叶变换与逆变换推导
  12. matlab 水文断面,基于MATLAB的河道横断面的绘制
  13. flutter 上滑悬浮吸顶
  14. 3、HeidiSQL数据库管理工具下载与安装
  15. 奔腾处理器_编号和非编号的奔腾处理器之间有什么区别?
  16. 网络营销推广怎么做 一封神奇的文案策划背后的真相
  17. 关于js数组方法的题目整理 6.24更新至题目5
  18. 如何用redis设计一个运动步数排行榜?
  19. js正则表达式(2)
  20. 文献综述怎么写 ,一直没头绪写不出来怎么办?

热门文章

  1. Eclipse下找不到“新建Web项目”
  2. 形式语言与自动机 3.正则表达式
  3. BioPython安装与入门
  4. 查看Linux服务器内存情况
  5. 小程序注册开发全流程
  6. Windows的隐藏分区
  7. python3爬取网易云歌单数据清洗_网易云音乐爬虫 数据可视化分析
  8. springboot嘉应房地产公司质量管理系统毕业设计源码453100
  9. 饮食结构思维导图模板
  10. 基于Xposed修改微信运动步数