OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 6515|回复: 3

展示一下我的IIC模拟程序,兼请教问题。

[复制链接]

34

主题

805

帖子

4

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1863
金钱
1863
注册时间
2011-3-29
在线时间
139 小时
发表于 2012-12-16 21:46:06 | 显示全部楼层 |阅读模式
最近在调iic接口的陀螺仪等九轴模块,卖家给的stm32程序死活调试不通过,卖家还不承认程序有问题。用原子哥的程序也不行。没办法,自己写一个吧,增加各种的出错信息判断,方便调试。

出于要写就写一个好的的想法,给程序提出了如下要求:1、能够选择100k的速率或400k;2、能够处理多主机下的时钟信号同步与仲裁的情况;3、能够识别设备拉低SCL的情况,适当减低主机时钟频率适应;4、能够发现并打印各种出错信息,方便iic设备的调试。

其中第4点是最主要的,因为我写这个程序就是为了调试我的九轴模块。根据IIC协议中文版及参考原子等人的程序,我在alientek 的miniSTM32开发板上成功读写了板上的eeprom,也成功读取了
adxl345加速传感器的数据。目测数据能够随着重力方向变化,故初步判断应该是成功的。

/////////////////////////////////////////

介绍程序中2个重要的函数:
1、int  iic_dev_read (u8 dev, u8 addr, u8* data); 该函数读取iic总线上dev地址的iic设备,将设备addr地址上寄存器数据读到data,返回错误代码。
2、int  iic_dev_write(u8 dev, u8 addr, u8  data); 该函数将数据data写入iic总线上的dev地址的iic设备,数据写入地址为设备上的addr地址,返回错误代码。
上述2个函数能够识别的错误有:
1、err_bus_busy:总线被外部设备拉低,暂时不可用。包括SDA和SCL被拉低2种情况。
2、err_arb_fail:多主机竞争的情况,竞争失败,放弃控制权。(未测试)
3、err_dev_fail:设备没有响应。可能是总线上没有该设备,或是设备处于忙碌状态。
4、err_tar_fail:理论上可能发生的设备拒绝对相应的寄存器的读写操作。
5、总线被外部主机或设备拉低超时。按照iic规范,scl总线可以不限时间被拉低。考虑到我们是模拟iic,为了避免死循环而加入此项功能。

/////////////////////////////////////////
// 与移植有关的配置
// 使用原子的程序即可
extern void delay_us(u32 nus);
#define iic_delay(t_us) delay_us(t_us)
// 将相应端口设置为开漏输出。这个跟原子的程序不太一样,不用频繁的改变输入输出状态,而且端口电平可以被外部改变,适应总线同步与裁决等情况
extern void hw_iic_init(void);
// 这些端口的使用跟板上的情况一致
#define SDA Cin(11)
#define SCL PCin(12)
#define SCL_L() Cout(12)=0
#define SCL_H() Cout(12)=1
#define SDA_L() Cout(11)=0
#define SDA_H() Cout(11)=1

// 调试与优化相关配置,如果没有后面的printf(A);则程序不会打印出错信息,但依然会返回错误代码。
#define IIC_DEBUG(A)  printf(A)
// SCL时钟频率 fscl: 100kHz or 400kHz
#define F_SCL   (100)
// 释放SCL并查询的次数,如果SCL保持被外部拉低,则退出,并设置_IIC_ERROR_COUDE为:IIC_TIME_OUT
#define IIC_TIME_OUT_COUNT (255)
// 释放SCL并查询的次数,如果SCL保持被外部拉低,则DEBUG提示。
/*delay for voltage raising time*/
#define IIC_RAISING_COUNT (10)


IIC协议中文版.pdf

845 KB, 下载次数: 428

IIC实验.rar

18.36 KB, 下载次数: 453

业余程序玩家。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

34

主题

805

帖子

4

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
1863
金钱
1863
注册时间
2011-3-29
在线时间
139 小时
 楼主| 发表于 2012-12-16 22:12:22 | 显示全部楼层
然后是向版主请教的一点问题:
我用淘宝上买的加速度模块测试,发现程序将SCL总线释放后,SCL总线依然保存一定时间的低电平,然后才上升为高电平。看汇编代码的循环次数,估计保持时间约不到1us吧。
我程序中的 #define IIC_RAISING_COUNT (10),就是为了处理这种情况,在10个查询判断周期内忽略这种错误,如果超过这个周期,但不超过IIC_TIME_OUT_COUNT个周期,则仅打印该项信息。问题是根据iic协议,如果我没看错与理解错的话,设备在发送字节期间是不允许拉低scl总线的,只允许在一个字节发送完毕之后拉低scl。但实际测试下来,在字节传输期间也产生了scl被外部拉低的情况。而我们又确定外部是没有主机的,所以我怀疑是硬件的错误。
以上是我怀疑硬件有问题的一个判断依据,另一个依据是,即使不读写加速度模块,仅仅读板上的eeprom模块,只要加速度模块的scl连接到板上的scl线,同样也会出现scl线电平延迟释放的情况。
上传个原理图,请版主过过眼:




由于我对硬件实在是一窍不通,请教懂硬件的高手:从以上硬件情况看,其是否可能导致SCL端口电平变化缓慢的情况出现?

第二个问题:
卖家说模块是5V和3.3V兼容的,但原理图貌似没有给出降压芯片型号,那个U2不知道是什么。
板上有VCC、GND、3V3、SDA、SCL五条线,淘宝卖家说连到VCC就行,3V3不用连接。这样上面的稳压器压降没有问题吗?
我的测试情况是,GND、SDA、SCL连接好之后:1、VCC接3.3v或5v,3V3悬空;2、3V3接3.3v,VCC悬空;3、VCC或3V3先上电,然后再把线拔掉悬空,;这3钟情况下都能够读取数据。比较好奇的是第三种情况怎么能够成功读取数据?


3q!
业余程序玩家。
回复 支持 反对

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165309
金钱
165309
注册时间
2010-12-1
在线时间
2108 小时
发表于 2012-12-17 00:08:51 | 显示全部楼层
回复【2楼】ofourme:
---------------------------------
1,关于SCL延迟的问题,由于你设置的是开漏输出,没有输出高的能力,我怀疑可能是NMOS存在,输出电容比较大的缘故,仅靠4.7K上拉电阻,导致电压上升比较慢的缘故.引起SCL上升延迟.
2,这个U2,应该是个低压差的LDO芯片.低压差LDO还没用过,不知道具体型号,不好说.
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

1

主题

7

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2013-1-6
在线时间
0 小时
发表于 2013-1-6 19:32:57 | 显示全部楼层
STM32的IIC程序没这么复杂吧!
方向对了,就不怕路远。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2024-11-23 16:33

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表