Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
DIY综合交流区
I2C 驱动代码的疑问--I2C_BIT_OPS
发布于 2013-06-23 11:11:44 浏览:7605
订阅该版
我们先看一个I2C 驱动的时序要求: ![i2c.png](/uploads/4024_ea1c3c14aba05a21f9ebc1c15959a924.png) 读取操作中,需要发送寄存器地址和启动。 ST->DEVICEID+W->REGADRESS->ST->DEVICEID+R->DATA ...->STOP 下面我们来看一下驱动代码,读取内容: step 1: i2c_start(ops); 就是发送启动信号。 step 2: ret = i2c_bit_send_address(bus, msg); 发送设备地址附加R/W 信号,这里区分10bit 地址还是7bit地址。 step 3: ret = i2c_recv_bytes(bus, msg); 读取数据。 可见该时序不符合I2C 的时序要求的。 缺点: 1) 设备的寄存器地址没有显示的定义变量。 2) 缺少第二次启动操作。 这里,我们来看一下数据传递的方法和解析: 例如: off = ADXL345_I2C_SAD ||(ADXL345_DEVID_ADR<<16); tmp=pdev->read(pdev,off,&adxl_Buffer[0],1); 数据传递到下级函数: addr = pos & 0xffff; flags = (pos >> 16) & 0xffff; rt_i2c_master_recv(bus, addr, flags, buffer, count); 再下一级函数数据传递: msg.addr = addr; msg.flags = flags & RT_I2C_ADDR_10BIT; msg.flags |= RT_I2C_RD; msg.len = count; msg.buf = buf; ret = rt_i2c_transfer(bus, &msg, 1); ``` static rt_size_t i2c_bit_xfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num) { struct rt_i2c_msg *msg; struct rt_i2c_bit_ops *ops = bus->priv; rt_int32_t i, ret; rt_uint16_t ignore_nack; bit_dbg("send start condition "); i2c_start(ops); for (i = 0; i < num; i++) { msg = &msgs*; ignore_nack = msg->flags & RT_I2C_IGNORE_NACK; if (!(msg->flags & RT_I2C_NO_START)) { if (i) { i2c_restart(ops); } ret = i2c_bit_send_address(bus, msg); if ((ret != RT_EOK) && !ignore_nack) { bit_dbg("receive NACK from device addr 0x%02x msg %d ", msgs*.addr, i); goto out; } } if (msg->flags & RT_I2C_RD) { ret = i2c_recv_bytes(bus, msg); if (ret >= 1) bit_dbg("read %d byte%s ", ret, ret == 1 ? "" : "s"); if (ret < msg->len) { if (ret >= 0) ret = -RT_EIO; goto out; } } else { ret = i2c_send_bytes(bus, msg); if (ret >= 1) bit_dbg("write %d byte%s ", ret, ret == 1 ? "" : "s"); if (ret < msg->len) { if (ret >= 0) ret = -RT_ERROR; goto out; } } } ret = i; out: bit_dbg("send stop condition "); i2c_stop(ops); return ret; } ```
查看更多
5
个回答
默认排序
按发布时间排序
weety
2013-06-23
这家伙很懒,什么也没写!
“ST->DEVICEID+W->REGADRESS->ST->DEVICEID+R->DATA ...->STOP”这个操作需要多条msg才能够做到,这样是为了灵活和通用,例子: ``` char data; struct rt_i2c_msg msg[2]; data = REGADRESS; msg[0].addr = DEVICEID; msg[0].flags = RT_I2C_WR; msg[0].len = 1; msg[0].buf = &data; msg[1].addr = DEVICEID; msg[1].flags = RT_I2C_RD; msg[1].len = 1; msg[1].buf = &data; i2c_bit_xfer(bus, msg, 2); ``` 执行完上面的代码data返回值就是要读取的I2C器件寄存器值。 你按照上面的顺序再分析下是否符合I2C时序规范呢?
taurus3g
2013-06-24
这家伙很懒,什么也没写!
谢谢你的回复! 根据你的提示,我稍微补充一下: 如果根据这样的操作: 1)需要修改I2C_core.c 文件的函数: ``` rt_size_t rt_i2c_master_recv(struct rt_i2c_bus_device *bus, rt_uint16_t addr, rt_uint16_t flags, rt_uint8_t *buf, rt_uint32_t count) { rt_size_t ret; struct rt_i2c_msg msg[2]; RT_ASSERT(bus != RT_NULL); msg[0].addr = addr; msg[0].flags = flags & RT_I2C_ADDR_10BIT; msg[0].flags = RT_I2C_WR; msg[0].len = 1; msg[0].buf = buf; msg[1].addr = addr; msg[1].flags = flags & RT_I2C_ADDR_10BIT; msg[1].flags = RT_I2C_RD; msg[1].len = count; msg[1].buf = buf; ret = rt_i2c_transfer(bus, &msg, 2); return (ret > 0) ? count : ret; } ``` >“ST->DEVICEID+W->REGADRESS->ST->DEVICEID+R->DATA ...->STOP”这个操作需要多条msg才能够做到,这样是为了灵活和通用,例子: > > >``` >char data; >struct rt_i2c_msg msg[2]; >data = REGADRESS; >msg[0].addr = DEVICEID; >msg[0].flags = RT_I2C_WR; >msg[0].len = 1; >msg[0].buf = &data; >msg[1].addr = DEVICEID; >msg[1].flags = RT_I2C_RD; >msg[1].len = 1; >msg[1].buf = &data; >i2c_bit_xfer(bus, msg, 2); > >``` > > >执行完上面的代码data返回值就是要读取的I2C器件寄存器值。 > >你按照上面的顺序再分析下是否符合I2C时序规范呢? ---
weety
2013-06-25
这家伙很懒,什么也没写!
这里的rt_i2c_master_recv只是用于连续读取一段数据,只能实现特定的时序,如果要更复杂的那么就要使用rt_i2c_transfer函数了,这个有比较大的灵活性,rt_i2c_master_recv只是对rt_i2c_transfer进行简单封装。
nongxiaoming
2013-07-18
rt-thread大师兄
楼主啊,这个是可以同时发送接收msg的,要读取器件的某某值,一般都会先写器件的某某寄存器,然后发送restart()再去发送器件地址+读标准,然后读取数据,那你就可以用两个msg,一个发送,一个读取,同时rt_i2c_transfer两个msg中间是不会去stop()的,而且会有个restart(),也就很容易的完成了读某某寄存器值,不用去处理什么start(),restart(),stop(),ack(),nack()之类的东西,整个流程就用rt_i2c_transfer完事。
撰写答案
登录
注册新账号
关注者
0
被浏览
7.6k
关于作者
taurus3g
这家伙很懒,什么也没写!
提问
8
回答
13
被采纳
0
关注TA
发私信
相关问题
1
[项目]搞个开源的硬件项目
2
硬件计划贴,及时更新,欢迎提意见
3
软件计划贴,及时更新,欢迎提意见::WMA,MOUNT,LWIP等问题急需解决.
4
MMS协议
5
定点的wma解压库-libwma
6
QQ群记录 [20090821]
7
STM32网络收音机PCB报名征集
8
第一版调试记录
9
第二版硬件讨论
10
RADIO项目相关模块规格--欢迎大家自己做板时规格与此兼容,减少重复劳动
推荐文章
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
env中添加lvgl软件包后,keil编译包--c99错误
2
【NXP-MCXA153】 定时器驱动移植
3
GD32F450 看门狗驱动适配
4
【NXP-MCXA153】看门狗驱动移植
5
RT-Thread Studio V2.2.9 Release Note
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
USB
DMA
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
FAL
rt-smart
ESP8266
I2C_IIC
UART
WIZnet_W5500
ota在线升级
PWM
freemodbus
flash
cubemx
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
编译报错
Debug
rt_mq_消息队列_msg_queue
SFUD
keil_MDK
msh
ulog
C++_cpp
MicroPython
本月问答贡献
踩姑娘的小蘑菇
7
个答案
2
次被采纳
a1012112796
18
个答案
1
次被采纳
红枫
5
个答案
1
次被采纳
Ryan_CW
5
个答案
1
次被采纳
张世争
4
个答案
1
次被采纳
本月文章贡献
YZRD
3
篇文章
6
次点赞
catcatbing
3
篇文章
6
次点赞
lizimu
2
篇文章
10
次点赞
qq1078249029
2
篇文章
2
次点赞
xnosky
2
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部