Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
I2C_IIC
at24cxx驱动包中读操作中有错误
发布于 2019-12-06 11:40:52 浏览:2442
订阅该版
最近做项目用到的RT THREAD 在做I2C存储的时候使用EVN工具 menuconfig RT-Thread online packages ---> peripheral libraries and drivers ---> at24cxx: eeprom at24cxx driver library. ---> 下载了at24cxx的驱动包,打开驱动包看了下程序源码发现一些问题 我们看下驱动包里读一个字节的源代码 ```uint8_t at24cxx_read_one_byte(struct rt_i2c_bus_device *bus, uint16_t readAddr) { rt_uint8_t buf[2]; rt_uint8_t temp; #if (EE_TYPE > AT24C16) buf[0] = (uint8_t)(readAddr>>8); buf[1] = (uint8_t)readAddr; if (rt_i2c_master_send(bus, AT24CXX_ADDR, 0, buf, 2) == 0) #else buf[0] = readAddr; if (rt_i2c_master_send(bus, AT24CXX_ADDR, 0, buf, 1) == 0) #endif { return -RT_ERROR; } read_regs(bus, 1, &temp); return temp; }```程序调用rt_i2c_master_send对I2C从机写寄存器地址,调用read_regs从I2C从机读一个字节(两个子函数源代码如下) rt_i2c_master_send源代码 ```rt_size_t rt_i2c_master_send(struct rt_i2c_bus_device *bus, rt_uint16_t addr, rt_uint16_t flags, const rt_uint8_t *buf, rt_uint32_t count) { rt_err_t ret; struct rt_i2c_msg msg; msg.addr = addr; msg.flags = flags & RT_I2C_ADDR_10BIT; msg.len = count; msg.buf = (rt_uint8_t *)buf; ret = rt_i2c_transfer(bus, &msg, 1); return (ret > 0) ? count : ret; }``` read_regs源代码 ```static rt_err_t read_regs(struct rt_i2c_bus_device *bus, rt_uint8_t len, rt_uint8_t *buf) { struct rt_i2c_msg msgs; msgs.addr = AT24CXX_ADDR; msgs.flags = RT_I2C_RD; msgs.buf = buf; msgs.len = len; if (rt_i2c_transfer(bus, &msgs, 1) == 1) { return RT_EOK; } else { return -RT_ERROR; } }```这里我们看到rt_i2c_master_send和read_regs最终都是调用rt_i2c_transfer这个函数进行的数据传输,我们在看下rt_i2c_transfer的源代码 ```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; }```在rt_i2c_transfer源代码的最后我们可以看到 该函数在最后对I2C总线发送了停止位(i2c_stop(ops);)那么问题来了 at24cxx的驱动包读一个字节调用了两次rt_i2c_transfer,相当于每次调用就发送一个停止位,这明显与I2C通讯机制不一致。 我们都知道I2C读一个字节数据的的流程是(大概流程 没写ACK NACK) 起始位 -- 器件地址+写 -- 寄存器地址 -- 起始位 -- 器件地址+读 -- 送机发送数据 -- 停止位 而 at24cxx的驱动包读一个字节的流程变成了 起始位 -- 器件地址+写 -- 寄存器地址 -- 停止位 -- 起始位 -- 器件地址+读 -- 送机发送数据 -- 停止位 很明显这是错误,不明白这么明显有错误的包官方为什么收录了。
查看更多
5
个回答
默认排序
按发布时间排序
tyustli
2019-12-07
这家伙很懒,什么也没写!
[i=s] 本帖最后由 tyustli 于 2019-12-7 15:34 编辑 [/i] 感觉这个软件包好久都没人维护了,,,,
sync
2020-03-11
这家伙很懒,什么也没写!
现在能正常使用不?楼主问题解决没?也打算用24CXX呢
Acuity
2020-04-16
这家伙很懒,什么也没写!
1、读函数应该调原始接口 ``` struct rt_i2c_msg msg[2]; msg[0].addr = SLAVE_ARRD; msg[0].flags = RT_I2C_WR; msg[0].len = 1; msg[0].buf = ® msg[1].addr = SLAVE_ARRD; msg[1].flags = RT_I2C_RD; msg[1].len = data_size; msg[1].buf = data; rt_i2c_transfer(i2c_device, msg, 2); ``` 2、写函数没有加入页写算法,效率有点低。 参考:[https://github.com/Prry/_24Cxx-EEPROM-FRAM-Dev](https://github.com/Prry/_24Cxx-EEPROM-FRAM-Dev)
ArvinLv
2020-04-16
这家伙很懒,什么也没写!
>1、读函数应该调原始接口 > >2、写函数没有加入页写算法,效率有点低。 --- static rt_size_t imxrt_i2c_mst_xfer(struct rt_i2c_bus_device *bus, struct rt_i2c_msg msgs[], rt_uint32_t num) { struct imxrt_i2c_bus *imxrt_i2c; rt_size_t i; RT_ASSERT(bus != RT_NULL); imxrt_i2c = (struct imxrt_i2c_bus *) bus; imxrt_i2c->msg = msgs; imxrt_i2c->msg_ptr = 0; imxrt_i2c->msg_cnt = num; imxrt_i2c->dptr = 0; for (i = 0; i < num; i++) { if (imxrt_i2c->msg[i].flags & RT_I2C_RD) { if (LPI2C_MasterStart(imxrt_i2c->I2C, imxrt_i2c->msg[i].addr, kLPI2C_Write) != kStatus_Success) { i = 0; break; } while (LPI2C_MasterGetStatusFlags(imxrt_i2c->I2C) & kLPI2C_MasterNackDetectFlag) { } if (LPI2C_MasterRepeatedStart(imxrt_i2c->I2C, imxrt_i2c->msg[i].addr, kLPI2C_Read) != kStatus_Success) { i = 0; break; } if (LPI2C_MasterReceive(imxrt_i2c->I2C, &imxrt_i2c->msg[i].buf, imxrt_i2c->msg[i].len) != kStatus_Success) { i = 0; break; } } else { if (LPI2C_MasterStart(imxrt_i2c->I2C, imxrt_i2c->msg[i].addr, kLPI2C_Write) != kStatus_Success) { i = 0; break; } while (LPI2C_MasterGetStatusFlags(imxrt_i2c->I2C) & kLPI2C_MasterNackDetectFlag) { } if (LPI2C_MasterSend(imxrt_i2c->I2C, imxrt_i2c->msg[i].buf, imxrt_i2c->msg[i].len) != kStatus_Success) { i = 0; break; } if (LPI2C_MasterWaitForTxFifoAllEmpty(imxrt_i2c->I2C) != kStatus_Success) { i = 0; break; } } } if (LPI2C_MasterStop(imxrt_i2c->I2C) != kStatus_Success) { i = 0; } imxrt_i2c->msg = RT_NULL; imxrt_i2c->msg_ptr = 0; imxrt_i2c->msg_cnt = 0; imxrt_i2c->dptr = 0; return i; } 这个imxrt_i2c_mst_xfer函数是RTT的抽象层函数,但是从这个函数来看读一个字节的流程变成了 起始位 -- 器件地址+写-- 起始位 -- 器件地址+读 -- 送机发送数据 -- 停止位; 理论上在写完器件地址后应该写寄存器地址啊,这个怎么没了?感觉这个驱动有问题啊?
simple_wen
2020-04-22
这家伙很懒,什么也没写!
所以这个软件包能用吗 做毕业设计准备用 结果发现软件包提供的文档里面的api说明和代码都不一样。。。。
撰写答案
登录
注册新账号
关注者
0
被浏览
2.4k
关于作者
mcuzx
这家伙很懒,什么也没写!
提问
4
回答
1
被采纳
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
开源共生 商业共赢 | RT-Thread 2024开发者大会议程正式发布!
2
【24嵌入式设计大赛】基于RT-Thread星火一号的智慧家居系统
3
RT-Thread EtherKit开源以太网硬件正式发布
4
如何在master上的BSP中添加配置yml文件
5
使用百度AI助手辅助编写一个rt-thread下的ONVIF设备发现功能的功能代码
热门标签
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
WIZnet_W5500
UART
ota在线升级
PWM
cubemx
freemodbus
flash
packages_软件包
BSP
潘多拉开发板_Pandora
定时器
ADC
GD32
flashDB
socket
中断
Debug
编译报错
msh
SFUD
rt_mq_消息队列_msg_queue
keil_MDK
ulog
MicroPython
C++_cpp
本月问答贡献
a1012112796
20
个答案
3
次被采纳
张世争
11
个答案
3
次被采纳
踩姑娘的小蘑菇
7
个答案
3
次被采纳
rv666
9
个答案
2
次被采纳
用户名由3_15位
13
个答案
1
次被采纳
本月文章贡献
程序员阿伟
9
篇文章
2
次点赞
hhart
3
篇文章
4
次点赞
RTT_逍遥
1
篇文章
6
次点赞
大龄码农
1
篇文章
5
次点赞
ThinkCode
1
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部