1.设备树添加
上期介绍过,大部分的设备节点内容都在/home/cisjy/linux/tool/linux-imx/arch/arm/boot/dts/imx6ull-14x14-evk.dts这个中
添加BH1750节点 0x23是设备地址
pinctrl_i2c1: i2c1grp { fsl,pins = < MX6UL_PAD_UART4_TX_DATA__I2C1_SCL 0x4001b8b0 MX6UL_PAD_UART4_RX_DATA__I2C1_SDA 0x4001b8b0 >; };
这里我不太理解,17-31位不是保留吗,为什么还要在30位上添加一个1.麻烦如果有知道指导一下.
2.驱动编写
1.misc注册
这里使用misc杂项注册.
添加i2c_driver的 probe,匹配表格
和设备树中的compatible匹配
匹配成功进入probe函数
misc结构体只需要添加子设备号就可以,主设备号都为10
2.i2c读写寄存器
写寄存器: BH1750不需要写入具体的寄存器地址只需要写入相关指令就可,所以参数没有添加reg地址
flag=0 标记为写数据
读寄存器:flag为标记为读取数据
open之后上电,设置精准度
#ifndef __BH1750_H__ #define __BH1750_H__ #define BH1750_ADDR 0x23 // BH1750器件地址 // BH1750指令码 #define POWER_OFF 0x00 #define POWER_ON 0x01 #define H_RESOLUTION_MODE 0x10 #define MODULE_RESET 0x07 #define CONTINUE_H_MODE 0x10 #define CONTINUE_H_MODE2 0x11 #define CONTINUE_L_MODE 0x13 #define ONE_TIME_H_MODE 0x20 #define ONE_TIME_H_MODE2 0x21 #define ONE_TIME_L_MODE 0x23 #endif
读取16位寄存器值 结果准备到应用程序处理
3.应用程序
光照强度 =(寄存器值[15:0] * 分辨率) / 1.2 (单位:勒克斯lx)
#include "stdio.h" #include "unistd.h" #include "sys/types.h" #include "sys/stat.h" #include "sys/ioctl.h" #include "fcntl.h" #include "stdlib.h" #include "string.h" #include <sys/select.h> #include <sys/time.h> #include <signal.h> #include <fcntl.h> #include <poll.h> int main(int argc, char *argv[]) { int fd; char *filename; unsigned char databuf[2]; unsigned short dis_data; float true_data; int ret = 0; if (argc != 2) { printf("Error Usage!\r\n"); return -1; } filename = argv[1]; fd = open(filename, O_RDWR); if (fd < 0) { printf("can't open file %s\r\n", filename); return -1; } while (1) { ret = read(fd, databuf, sizeof(databuf)); if (ret == 0) { printf("databuf[0]: %d,databuf[1]:%d\r\n", databuf[0], databuf[1]); dis_data = (databuf[0] << 8) + databuf[1]; true_data = dis_data * 10 / 12; printf("光照强度为: %.3flx\r\n", true_data); } usleep(2000000); } close(fd); return 0; }