完善资料让更多小伙伴认识你,还能领取20积分哦, 立即完善>
经过一段时间试用,决定将气压传感器应用到我们Android产品上,成为电子产品的一个实用功能。 程序实现方面,Android系统内核是Linux Kernel,常规做法是写一个新I2C设备驱动用来驱动气压传感器,重新编译内核后内核就可以支持气压传感器。 不过,这次我决定尝试一种新的做法:从用户空间访问I2C总线,直接和I2C器件进行通讯。这样做的好处显而易见,不需要改kernel代码且无需编译和更新固件,应用程序里就能直接操作I2C设备:气压传感器,编程难度大为降低,代码灵活性大大提高。话不多说,直接上代码: 1. 在用户空间里进行I2C通讯 static char i2c_bus[] = "/dev/i2c-3"; //我的PCBA板子上接的是i2c-3这个总线 static jint i2c_write(uint8_t reg, uint8_t *data, int32_t size){ int fd; int ret; unsigned char buf[64]; fd = open(i2c_bus, O_RDWR); LOGI("[i2c_write] Open i2c BUS: %sn", i2c_bus); if (fd < 0) { LOGI("open i2c dev error!n"); return -1; } ret = ioctl(fd, I2C_SLAVE_FORCE, BM1390GLV_DEVICE_ADDRESS); if (ret < 0) { LOGI("set dev error!n"); close(fd); return ret; } memset(buf, 0, 64); write(fd, buf, 10); buf[0] = reg; memcpy(&buf[1], data, size); ret = write(fd, buf, size + 1); if (ret < 0) { LOGI("I2C write error!n"); close(fd); return -1; } close(fd); usleep(1000); return 0; } static jint i2c_read(uint8_t reg, uint8_t *data, int32_t size) { int fd; int ret; unsigned char buf[64] = { 0 }; fd = open(i2c_bus, O_RDWR); LOGI("[i2c_read] Open i2c BUS: %sn", i2c_bus); if (fd < 0) { LOGI("open i2c dev error!n"); return BM1390GLV_COMM_ERROR; } ret = ioctl(fd, I2C_SLAVE_FORCE, BM1390GLV_DEVICE_ADDRESS); if (ret < 0) { LOGI("set dev error!n"); close(fd); return ret; } i2c_write(reg, data, size); ret = read(fd, buf, size); if (ret < 0) { LOGI(" I2C read error!n"); close(fd); return BM1390GLV_COMM_ERROR; } memcpy(data, buf, size); close(fd); usleep(1000); return BM1390GLV_COMM_OK; } 2. 初始化传感器 JNIEXPORT jint JNICALL Init(JNIEnv *env, jobject thiz) { env->GetJavaVM(&gJavaVM); gJavaObj = env->NewGlobalRef(thiz); int32_t result; result = init_check(); LOGI("Init %d",result); if (result == BM1390GLV_COMM_OK) { (void)init_setting(); } return (result); } static jint init_check(void) { int32_t result; uint8_t id[BM1390GLV_ALL_ID_SIZE]; result = i2c_read(BM1390GLV_MANUFACTURER_ID_PART_ID, id, BM1390GLV_ALL_ID_SIZE); LOGI("init_check %d",result); if (result == BM1390GLV_COMM_OK) { LOGI("id1 %d", id[BM1390GLV_MANUFACTURER_ID]); LOGI("id2 %d", id[BM1390GLV_PART_ID]); if ((id[BM1390GLV_MANUFACTURER_ID] != BM1390GLV_MANUFACTURER_ID_VAL) || (id[BM1390GLV_PART_ID] != BM1390GLV_PART_ID_VAL)) { result = BM1390GLV_WAI_ERROR; } } return (result); } static jint init_setting(void) { int32_t result; uint8_t val; val = BM1390GLV_POWER_DOWN_VAL; result = i2c_write(BM1390GLV_POWER_DOWN, &val, sizeof(val)); if (result == BM1390GLV_COMM_OK) { val = BM1390GLV_RESET_VAL; (void)i2c_write(BM1390GLV_RESET, &val, sizeof(val)); val = BM1390GLV_MODE_CONTROL_VAL; (void)i2c_write(BM1390GLV_MODE_CONTROL, &val, sizeof(val)); ModeCtlVal = val; } return (result); } 3. 读取传感器采集到的气压、温度 static float convert_hpa(uint32_t raw_press) { float press; press = (float)raw_press / BM1390GLV_COUNTS_PER_HPA; return (press); } static jfloat convert_degree_celsius(int16_t raw_temp) { float temp; temp = (float)raw_temp / BM1390GLV_COUNTS_PER_DEGREE_CELSIUS; return (temp); } static jint get_value(uint8_t *raw) { int32_t result; result = i2c_read(BM1390GLV_PRESSURE_TEMPERATURE, raw, BM1390GLV_ALL_OUT_SIZE); return (result); } JNIEXPORT jint JNICALL get_val(JNIEnv *env, jobject thi) { int32_t result; uint8_t raw_data[BM1390GLV_ALL_OUT_SIZE]; uint32_t raw_press; uint16_t raw_temp; result = get_value(raw_data); if (result == BM1390GLV_COMM_OK) { raw_press = (uint32_t)raw_data[BM1390GLV_PRESS_OUT_MSB] << 16; raw_press |= (uint32_t)raw_data[BM1390GLV_PRESS_OUT_LSB] << 8; raw_press |= (uint32_t)raw_data[BM1390GLV_PRESS_OUT_XL]; raw_temp = (uint16_t)raw_data[BM1390GLV_TEMP_OUT_MSB] << 8; raw_temp |= (uint16_t)raw_data[BM1390GLV_TEMP_OUT_LSB]; jfloat press = convert_hpa(raw_press); jfloat temp = convert_degree_celsius(raw_temp); LOGI("Pressure(hPa): %f", press); LOGI("Temperature(degree Celsius): %f", temp); }; return (result); } 最后,来看一下效果。先来一张示波器量到的波形,证明用户空间直接通过I2C总线访问I2C器件是成功的: |
|
相关推荐
|
|
你正在撰写讨论
如果你是对讨论或其他讨论精选点评或询问,请使用“评论”功能。
1985 浏览 1 评论
8103 浏览 0 评论
1918 浏览 0 评论
VL53L5CX #高达 8x8 多区域测距和 63°对角线宽视场 飞行时间多区域测距传感器
17299 浏览 0 评论
【罗姆传感器评估板试用体验连载】罗姆传感器整合进同一个示例程序
21944 浏览 0 评论
小黑屋| 手机版| Archiver| 电子发烧友 ( 湘ICP备2023018690号 )
GMT+8, 2024-11-10 14:33 , Processed in 0.341495 second(s), Total 33, Slave 28 queries .
Powered by 电子发烧友网
© 2015 bbs.elecfans.com
关注我们的微信
下载发烧友APP
电子发烧友观察
版权所有 © 湖南华秋数字科技有限公司
电子发烧友 (电路图) 湘公网安备 43011202000918 号 电信与信息服务业务经营许可证:合字B2-20210191 工商网监 湘ICP备2023018690号