Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
I2C_IIC
RT-Thread Studio
软件i2c库
i2c总线使用中,i2c write failed(err: -8),i2c总线被找到注册了,后面就是write和read都失败err:-8
发布于 2024-03-06 17:06:45 浏览:577
订阅该版
[tocm] ```c #include
#include
#include "VL6180.h" #include "bsp_include.h" #define DBG_LEVEL DBG_LOG #include
#define LOG_TAG "sensor.VL6180" #ifndef MIN #define MIN(a, b) ((a) < (b) ? (a) : (b)) #endif #ifndef ARRAY_SIZE #define ARRAY_SIZE(array) \ ((unsigned long)(sizeof(array) / sizeof((array)[0]))) #endif #define VL6180X_DEFAULT_ID 0xB4 #define VL6180_ADDR 0x29 // 7-bit version of the above static struct rt_i2c_bus_device *i2c_bus; static rt_uint32_t g_distance; static void VL6180_thread_entry(void *args); /** * \brief Write a value to a VL6180 register * \par Details * This function writes a value to a VL6180 register * * \param[in] uch_addr - register address * \param[in] uch_data - register data * * \retval true on success * **/ static rt_bool_t Vl6180_write_reg(uint16_t uch_addr,uint8_t uch_data) { uint8_t buf[3]; struct rt_i2c_msg msg; rt_size_t err; buf[0] = uch_addr >> 8; //获取地址高8位,存储到buf[0] buf[1] = uch_addr & 0xFF; //获取地址低8位,存储到buf[1] buf[2] = uch_data; msg.addr = VL6180_ADDR; msg.flags = RT_I2C_WR; msg.buf = buf; msg.len = ARRAY_SIZE(buf); if ((err = rt_i2c_transfer(i2c_bus, &msg, 1)) != 1) { LOG_E("i2c write failed(err: %d).",err); return RT_FALSE; } return RT_EOK; } /** * \brief Read a VL6180 register * \par Details * This function reads a VL6180 register * * \param[in] uch_addr - register address * \param[out] puch_data - pointer that stores the register data * * \retval true on success */ static rt_bool_t VL6180_read_reg(uint16_t uch_addr, uint8_t *data, uint16_t len) { RT_ASSERT(data); uint8_t buf[2]; struct rt_i2c_msg msg_buf[2]; rt_size_t err; buf[0] = uch_addr >> 8; //获取地址高8位,存储到buf[0] buf[1] = uch_addr & 0xFF; //获取地址低8位,存储到buf[1] msg_buf[0].addr = VL6180_ADDR; msg_buf[0].flags = RT_I2C_WR; msg_buf[0].buf = buf; msg_buf[0].len = 1; msg_buf[1].addr = VL6180_ADDR; msg_buf[1].flags = RT_I2C_RD; msg_buf[1].buf = data; msg_buf[1].len = len; if ((err = rt_i2c_transfer(i2c_bus, msg_buf, 2)) != 2) { LOG_E("i2c read failed (err: %d).",err); return RT_FALSE; } return RT_EOK; } /* 开始测量模式选择 选择单次测量模式 */ uint8_t VL6180_Start_Range(void) { Vl6180_write_reg(0x018, 0x01); return 0; } /*poll for new sample ready */ uint8_t VL6180X_Poll_Range(void) { uint8_t status; uint8_t range_status; VL6180_read_reg(0x04f, &status, 1); range_status=status&0x07; while(range_status!=0x04) { VL6180_read_reg(0x04f, &status, 1); range_status=status&0x07; rt_thread_mdelay(1000); } return 0; } /*clear interrupt*/ void VL6180_Clear_Interrupt(void) { Vl6180_write_reg(0x015, 0x07); } uint8_t VL6180_Read_ID(void) { uint8_t res; VL6180_read_reg(VL6180X_REG_IDENTIFICATION_MODEL_ID, &res, 1); return res; } /** * \brief Initialize the VL6180 * \par Details * This function initializes the VL6180 * * \param None * * \retval true on success */ static rt_bool_t VL6180_init() { if (VL6180_Read_ID() == VL6180X_DEFAULT_ID) { Vl6180_write_reg(0x0207, 0x01); Vl6180_write_reg(0x0208, 0x01); Vl6180_write_reg(0x0096, 0x00); Vl6180_write_reg(0x0097, 0xfd); Vl6180_write_reg(0x00e3, 0x00); Vl6180_write_reg(0x00e4, 0x04); Vl6180_write_reg(0x00e5, 0x02); Vl6180_write_reg(0x00e6, 0x01); Vl6180_write_reg(0x00e7, 0x03); Vl6180_write_reg(0x00f5, 0x02); Vl6180_write_reg(0x00d9, 0x05); Vl6180_write_reg(0x00db, 0xce); Vl6180_write_reg(0x00dc, 0x03); Vl6180_write_reg(0x00dd, 0xf8); Vl6180_write_reg(0x009f, 0x00); Vl6180_write_reg(0x00a3, 0x3c); Vl6180_write_reg(0x00b7, 0x00); Vl6180_write_reg(0x00bb, 0x3c); Vl6180_write_reg(0x00b2, 0x09); Vl6180_write_reg(0x00ca, 0x09); Vl6180_write_reg(0x0198, 0x01); Vl6180_write_reg(0x01b0, 0x17); Vl6180_write_reg(0x01ad, 0x00); Vl6180_write_reg(0x00ff, 0x05); Vl6180_write_reg(0x0100, 0x05); Vl6180_write_reg(0x0199, 0x05); Vl6180_write_reg(0x01a6, 0x1b); Vl6180_write_reg(0x01ac, 0x3e); Vl6180_write_reg(0x01a7, 0x1f); Vl6180_write_reg(0x0030, 0x00); // Recommended : Public registers - See data sheet for more detail Vl6180_write_reg(0x0011, 0x10); // Enables polling for 'New Sample ready' when measurement completes //该值为读取平均采集数据周期,默认48,周期为 1300us+(64.5us * 48)= 4300us Vl6180_write_reg(0x010a, 0x04); // Set the averaging sample period(compromise between lower noise andincreased execution time) 采集平均次数,默认0x30,48次。修改为0x04 //配置ALS测试增益,默认0x46为1.0 Vl6180_write_reg(0x003f, 0x46); // Sets the light and dark gain (uppernibble). Dark gain should not bechanged. Vl6180_write_reg(0x0031, 0xFF); // sets the # of range measurements after which auto calibration of system isperformed Vl6180_write_reg(0x0040, 0x63); // Set ALS integration time to 100ms ALS积分周期 Vl6180_write_reg(0x002e, 0x01); // perform a single temperature calibrationof the ranging sensor //Optional: Public registers - See data sheet for more detail Vl6180_write_reg(0x001b, 0x09); //测量间隔 轮询模式 period to 100ms 每步10ms->0-10ms Vl6180_write_reg(0x001c, 0x06); //测距模式下运行的最大时间,可配置1-63ms。该视觉取决于实际收敛时间和采集平均数据周期(0x10a) Vl6180_write_reg(0x003e, 0x31); //测量周期 ALS模式 to 500ms Vl6180_write_reg(0x0014, 0x24); // Configures interrupt on 'New Sample Ready threshold event' 读数的中断模式源都是“新样本就绪” return 0; } else { return 1; } } static rt_size_t Vl6180_fetch_data(struct rt_sensor_device *sensor, void *buf, rt_size_t len) { RT_ASSERT(sensor); RT_ASSERT(buf); RT_ASSERT(len = sizeof(struct rt_sensor_data)); struct rt_sensor_data *data = buf; data->timestamp = rt_tick_get(); data->type = RT_SENSOR_UNIT_MM; data->data.proximity = g_distance; return len; } static rt_err_t VL6180_control(struct rt_sensor_device *sensor, int cmd, void *arg) { RT_ASSERT(sensor); RT_ASSERT(arg); if (cmd == RT_SENSOR_CTRL_SET_MODE || cmd ==RT_SENSOR_CTRL_SET_POWER) { return RT_EOK; } rt_kprintf("Now support command: (%d).", cmd); return RT_ERROR; } static struct rt_sensor_ops VL6180_ops = { .fetch_data = Vl6180_fetch_data, .control = VL6180_control, }; int rt_hw_VL6180_init(struct rt_sensor_config *cfg) { RT_ASSERT(cfg); RT_ASSERT(cfg->mode == RT_SENSOR_MODE_POLLING); char *err_msg = RT_NULL; rt_thread_t tid; rt_sensor_t sensor = RT_NULL; do { i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(cfg->intf.dev_name); if(i2c_bus == RT_NULL) { err_msg = "Not find i2c bus (cfg->intf.dev_name)."; LOG_E(err_msg); break; } sensor = rt_calloc(1, sizeof(struct rt_sensor_device)); if (sensor == RT_NULL) { err_msg = "rt_calloc error."; rt_kprintf(err_msg); break; } struct rt_sensor_info info = { .type = RT_SENSOR_CLASS_PROXIMITY, .vendor = RT_SENSOR_VENDOR_TI, .model = "VL6180", .unit = RT_SENSOR_UNIT_MM, .intf_type = RT_SENSOR_INTF_I2C, .range_max = 255, // 255mm .range_min = 0, // 0mm .period_min = 1, }; rt_memcpy(&sensor->info, &info, sizeof(struct rt_sensor_info)); rt_memcpy(&sensor->config, cfg, sizeof(struct rt_sensor_config)); sensor->ops = &VL6180_ops; if (rt_hw_sensor_register(sensor, "VL6180", RT_DEVICE_FLAG_RDONLY, RT_NULL) != RT_EOK) { err_msg = "Register VL6180 sensor device error."; LOG_E(err_msg); break; } //VL6180 Init rt_thread_mdelay(1000); VL6180_Clear_Interrupt(); // interrupt clear VL6180_init(); // initialize the VL6180 tid = rt_thread_create("Vl6180", VL6180_thread_entry, sensor, 1024, 15, 20); if(tid == RT_NULL) { err_msg = "Create VL6180 thread error."; LOG_E(err_msg); break; } rt_thread_startup(tid); } while (0); if (err_msg) { if (sensor) rt_free(sensor); if (tid) rt_thread_delete(tid); LOG_E(err_msg); return RT_ERROR; } return RT_EOK; } static void VL6180_thread_entry(void *args) { rt_sensor_t sensor = args; uint8_t distance; rt_pin_mode(sensor->config.irq_pin.pin, PIN_MODE_INPUT_PULLUP); while(1) { Vl6180_write_reg(VL6180X_REG_SYSRANGE_START, 0x01); //单次触发模式 if (rt_pin_read(sensor->config.irq_pin.pin) == 0) //中断信号(新样本就绪) { VL6180_read_reg(0x0062, &distance, 1); } VL6180_Clear_Interrupt(); //清除中断 rt_thread_mdelay(2000); rt_kprintf("distance is %d\n", distance); } } int VL6180_port_init(void) { struct rt_sensor_config cfg = { .intf.dev_name = "i2c1", // i2c bus name .irq_pin.pin = 85, // interrupt pin 1 .mode = RT_SENSOR_MODE_POLLING, // must have }; if (rt_hw_VL6180_init(&cfg) != RT_EOK) { return RT_ERROR; } return RT_EOK; } INIT_APP_EXPORT(VL6180_port_init); ```
查看更多
2
个回答
默认排序
按发布时间排序
xiaorui
认证专家
2024-03-06
小睿手办 https://item.taobao.com/item.htm?id=674889867009
接上逻辑分析仪看看啥情况?
shenzhihao
2024-03-06
这家伙很懒,什么也没写!
接上了逻辑分析仪,都没有电平信号
撰写答案
登录
注册新账号
关注者
0
被浏览
577
关于作者
shenzhihao
这家伙很懒,什么也没写!
提问
1
回答
2
被采纳
0
关注TA
发私信
相关问题
1
NXP的I2C应该比ST的好用吧
2
Use of I2C device driver
3
关于I2C 驱动问题请教
4
我如何知道这个iic的io配置和我电路设计的是一致的?
5
I2C模拟读操作失败,不知道问什么进不去读函数
6
RTT的I2C有官方文档资料没有
7
求 STM32F103 IIC 自定义IO初始化 代码
8
报一个LPC4008代码中I2C的bug
9
RTOS IIC总线使用
10
关于在RTT中使用STM32 I2C的疑问
推荐文章
1
RT-Thread应用项目汇总
2
玩转RT-Thread系列教程
3
国产MCU移植系列教程汇总,欢迎查看!
4
机器人操作系统 (ROS2) 和 RT-Thread 通信
5
五分钟玩转RT-Thread新社区
6
【技术三千问】之《玩转ART-Pi》,看这篇就够了!干货汇总
7
关于STM32H7开发板上使用SDIO接口驱动SD卡挂载文件系统的问题总结
8
STM32的“GPU”——DMA2D实例详解
9
RT-Thread隐藏的宝藏之completion
10
【ART-PI】RT-Thread 开启RTC 与 Alarm组件
最新文章
1
RTT 源码分析笔记——互斥量篇
2
[E/app.filesystem] SD card mount to '/sdcard' failed!
3
单片机也能聊天?RT-Thread上跑通大语言模型
4
【RT-Thread】【ci】【scons】将ci.attachconfig.yml和scons结合使用
5
Rt-thread中OTA下载后,bootloader不搬程序
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
DMA
USB
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
I2C_IIC
ESP8266
UART
WIZnet_W5500
ota在线升级
cubemx
PWM
flash
freemodbus
BSP
packages_软件包
潘多拉开发板_Pandora
定时器
ADC
flashDB
GD32
socket
编译报错
中断
Debug
rt_mq_消息队列_msg_queue
SFUD
msh
keil_MDK
ulog
C++_cpp
MicroPython
本月问答贡献
出出啊
1518
个答案
343
次被采纳
小小李sunny
1444
个答案
290
次被采纳
张世争
813
个答案
177
次被采纳
crystal266
549
个答案
161
次被采纳
whj467467222
1222
个答案
149
次被采纳
本月文章贡献
出出啊
1
篇文章
3
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
3
次点赞
crystal266
2
篇文章
2
次点赞
whj467467222
2
篇文章
2
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部