Toggle navigation
首页
问答
文章
积分商城
专家
专区
更多专区...
文档中心
返回主站
搜索
提问
会员
中心
登录
注册
I2C_IIC
关于模拟I2C 的建议
发布于 2019-01-28 08:43:02 浏览:4143
订阅该版
rtthread 提供的模拟I2C 协议确实非常好用,尤其是在STM32上, 但是我觉得仍然存在一个问题,就是在读取SDA 数据的时候, stm32 支持OD 输出,利用外部的上拉,可以实现在作为输出的时候,读取输入信息,但是并不是所有的芯片都支持这种模式 RT1052 就不支持, 我开始打算在读取SDA 的函数里面把 SDA 设置为输入,然后去读取,发现来不及, 但是用裸机的程序,在读取 SCL 产生脉冲之前就已经改变了SDA 的输入输出状态,表现正常 所以我建议是不是可以再需要读取SDA 的地方 rt_inline rt_bool_t i2c_waitack(struct rt_i2c_bit_ops *ops) { rt_bool_t ack; SDA_H(ops); // 在此处是否需要将SDA 改变成输入状态 i2c_delay(ops); if (SCL_H(ops) < 0) { bit_dbg("wait ack timeout
"); return -RT_ETIMEOUT; } ack = !GET_SDA(ops); /* ACK : SDA pin is pulled low */ bit_dbg("%s
", ack ? "ACK" : "NACK"); SCL_L(ops); return ack; } static rt_int32_t i2c_readb(struct rt_i2c_bus_device *bus) { rt_uint8_t i; rt_uint8_t data = 0; struct rt_i2c_bit_ops *ops = bus->priv; // 还有这个地方是不是也应该改变成输入状态 SDA_H(ops); i2c_delay(ops); for (i = 0; i < 8; i++) { data <<= 1; if (SCL_H(ops) < 0) { bit_dbg("i2c_readb: wait scl pin high " "timeout at bit %d
", 7 - i); return -RT_ETIMEOUT; } if (GET_SDA(ops)) data |= 1; SCL_L(ops); i2c_delay2(ops); } return data; } 如上,请开发组考虑,并统一更改
查看更多
14
个回答
默认排序
按发布时间排序
海阔天kongcyc
2019-01-28
这家伙很懒,什么也没写!
切换到输入,使用完,还需要切换到输入模式吧? 标
xingyanchen
2019-01-29
这家伙很懒,什么也没写!
>切换到输入,使用完,还需要切换到输入模式吧? >标 --- 是的,可以考虑SDA读取完就改回去,也可以在写数据之前改过去
海阔天kongcyc
2019-01-29
这家伙很懒,什么也没写!
>是的,可以考虑SDA读取完就改回去,也可以在写数据之前改过去 --- 嗯嗯,其实这个问题我也遇到过,有一些MCU不支持开漏输出,不过,不知道这个SDA输入输出方向修改,是不是也可以在驱动层做,不在驱动框架中间层做?
xingyanchen
2019-01-29
这家伙很懒,什么也没写!
[i=s] 本帖最后由 xingyanchen 于 2019-1-29 09:10 编辑 [/i] >嗯嗯,其实这个问题我也遇到过,有一些MCU不支持开漏输出,不过,不知道这个SDA输入输出方向修改,是不是 ... --- struct rt_i2c_bit_ops { void *data; /* private data for lowlevel routines */ void (*set_sda)(void *data, rt_int32_t state); void (*set_scl)(void *data, rt_int32_t state); rt_int32_t (*get_sda)(void *data); rt_int32_t (*get_scl)(void *data); void (*chang_sda_mode)(rt_int32_t mode); void (*udelay)(rt_uint32_t us); rt_uint32_t delay_us; /* scl and sda line delay */ rt_uint32_t timeout; /* in tick */ }; 我加了一个函数,改变状态的。然后再 i2c_bit_ops.c中 改变状态如下 rt_inline rt_bool_t i2c_waitack(struct rt_i2c_bit_ops *ops) { rt_bool_t ack; ops->chang_sda_mode(1); SDA_H(ops); i2c_delay(ops); 这样在驱动层只要实现 一下SDA关键的方向转变的函数就可以了 关键是只在驱动层做来不及,我试过了,指在驱动层,在读取SDA数据之前,更改SDA方向根本来不及读取就过去了
海阔天kongcyc
2019-01-29
这家伙很懒,什么也没写!
>struct rt_i2c_bit_ops >{ > void *data; /* private data for lowlevel routines */ --- 按照你的测试情况,在驱动层改变SDA方向,时间上不匹配问题,那么感觉就很有必要在底层驱动层添加修改模式的接口了,至少可以预留,中间层再去适配 另外再问一下,你这个ops->chang_sda_mode(1), 修改了sda模式,又再哪里恢复了?贴个代码看看?
xingyanchen
2019-01-29
这家伙很懒,什么也没写!
>按照你的测试情况,在驱动层改变SDA方向,时间上不匹配问题,那么感觉就很有必要在底层驱动层添加修改模 ... --- 我直接在后面跳出之前更改的 rt_inline rt_bool_t i2c_waitack(struct rt_i2c_bit_ops *ops) { rt_bool_t ack; ops->chang_sda_mode(1); // 此处改变 SDA_H(ops); i2c_delay(ops); if (SCL_H(ops) < 0) { bit_dbg("wait ack timeout\n"); ops->chang_sda_mode(0);//此处改回 return -RT_ETIMEOUT; } ack = !GET_SDA(ops); /* ACK : SDA pin is pulled low */ bit_dbg("%s\n", ack ? "ACK" : "NACK"); SCL_L(ops); ops->chang_sda_mode(0); //此处改回 return ack; } 还有读取的时候也需要,我只贴了wait ack部分的
海阔天kongcyc
2019-01-29
这家伙很懒,什么也没写!
>我直接在后面跳出之前更改的 > >rt_inline rt_bool_t i2c_waitack(struct rt_i2c_bit_ops *ops) --- 是的,这种修改和我设想的一致。这种方式还是挺建议官方考虑下的
xingyanchen
2019-01-29
这家伙很懒,什么也没写!
>是的,这种修改和我设想的一致。这种方式还是挺建议官方考虑下的 --- 咱们闲聊没用,需要提交,但是我老是提交不好,就不干随便提交了,只能提建议给官方看看,希望他们能改动吧
还没想好
2019-03-26
这家伙很懒,什么也没写!
楼主提到的这个问题,我们一般在驱动层去做。 目前有较多的芯片不支持开漏输出这种模式,针对这类芯片,一般的操作是: 输出高:输入上拉 输出低:输出低,无上下拉 下面贴一段代码方便大家理解 ``` static void set_sda(void *data, rt_int32_t state) { if (state) { /* 输出高时,相关引脚设置为输入上拉模式,此时总线电平被上拉拉高 */ gpio_cfg(sda, GPIO_DIR_INPUT, GPIO_ATTR_PULLHIGH); } else { /* 输出低时,相关引脚设置为输出模式,没有上下拉,输出0 */ gpio_cfg(sda, GPIO_DIR_OUTPUT, GPIO_ATTR_FLOATING); gpio_write(sda, 0); } } static void set_scl(void *data, rt_int32_t state) { if (state) { gpio_cfg(scl, GPIO_DIR_INPUT, GPIO_ATTR_PULLHIGH); } else { gpio_cfg(scl, GPIO_DIR_OUTPUT, GPIO_ATTR_FLOATING); gpio_write(scl, 0); } } static rt_int32_t get_sda(void *data) { return gpio_read(sda); } static rt_int32_t get_scl(void *data) { return gpio_read(scl); } ```
Ernest
2019-03-26
这家伙很懒,什么也没写!
>楼主提到的这个问题,我们一般在驱动层去做。 > >目前有较多的芯片不支持开漏输出这种模式,针对这类芯片,一 ... --- 骚操作
撰写答案
登录
注册新账号
关注者
0
被浏览
4.1k
关于作者
xingyanchen
这家伙很懒,什么也没写!
提问
19
回答
38
被采纳
1
关注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 studio的驱动5.1.0报错修改
2
基于RT-Thread的STM32开发第一讲——USART
3
pkgs --upgrade报错SSL未验证问题解决记录
4
CherryUSB STM32 glue 新增初始化
5
在LPC1114上移植 RT-Thread Nano 3.1.5
热门标签
RT-Thread Studio
串口
Env
LWIP
SPI
AT
Bootloader
Hardfault
CAN总线
FinSH
ART-Pi
DMA
USB
文件系统
RT-Thread
SCons
RT-Thread Nano
线程
MQTT
STM32
RTC
rt-smart
FAL
cubemx
I2C_IIC
UART
ESP8266
WIZnet_W5500
BSP
ota在线升级
PWM
flash
packages_软件包
freemodbus
潘多拉开发板_Pandora
ADC
GD32
定时器
编译报错
flashDB
keil_MDK
socket
中断
rt_mq_消息队列_msg_queue
Debug
ulog
SFUD
msh
C++_cpp
at_device
本月问答贡献
出出啊
1524
个答案
343
次被采纳
小小李sunny
1444
个答案
290
次被采纳
张世争
818
个答案
179
次被采纳
crystal266
555
个答案
162
次被采纳
whj467467222
1222
个答案
149
次被采纳
本月文章贡献
出出啊
1
篇文章
3
次点赞
小小李sunny
1
篇文章
1
次点赞
张世争
1
篇文章
1
次点赞
crystal266
2
篇文章
1
次点赞
whj467467222
2
篇文章
1
次点赞
回到
顶部
发布
问题
分享
好友
手机
浏览
扫码手机浏览
投诉
建议
回到
底部