打印

采用CSL调试C5509A的I2C小结(转)

[复制链接]
1908|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
采用CSL调试C5509A的I2C小结
作者:redbat_2…    **来源:redbat_228    点击数:805    更新时间:2011-7-21    [url=][/url]
两天在用CSL调试I2C总线接口的EEPROM,型号为24LC01。但是始终读写总是失败。以前在配置AIC23的时候,曾用过I2C。那时是根据瑞泰的程序修改的,但是程序运行不稳定,有时会出现无法配置的情况。这次比较有时间,对这个问题仔细研究了一下。

现在已经解决了,写了篇总结,以供参考。


由于我是从主板上引线到EEPROM板子的,所以开始怀疑是信号频率过高。测试波形,发现根本没有波形输出。降低5509A的主频,降低I2C总线的频率。经过N次尝试,终于能够正确读取数据了。测试波形,发现上升沿不是很陡峭,把I2C总线的上拉电阻由10k修改为了2.2k。这样上升沿足够陡峭了(至少确定该上升沿足够满足400k的频率了)。

恢复5509A的主频,提高I2C总线频率,读写还是失败。测试波形,仍然没有输出。在网上找到了一篇C5509A的I2C模块的应用文档(见参考文献),里面有读写EEPROM的例子。根据那个例子修改,读写仍然失败,现象依旧。

进一步搜索,发现有不少人碰到了类似的问题。最后,在TI的e2e社区找到了问题的所在(网址见参考文献)。原来是CSL中的I2C_setup函数有问题。摘取其中的解决方法如下:

I2C_FSET(I2CSTR,BB,0x1); /* Writing a 1 to BB Bus busy bit is supposed to clear it*/

/* Initializes I2C registers using initialization structure */

I2C_setup(&Init);

/* Need to calcualte I2CCLKL & I2CCLKH manually has functionnality not fully miplmented in CSL*/

I2C_RSET(I2CCLKL,220); /* Clock Divider Low register */

I2C_RSET(I2CCLKH,220); /* Clock Divider High register */

也就是在配置I2C模块之前,需要把I2CSTR寄存器中的BB位置1。同时,在待用完毕I2C_setup函数后,再重新配置一下I2CCLKL和I2CCLKH寄存器。

顺藤摸瓜,找到了CSL中的源文件,看到其中I2C_setup函数的代码如下:

void I2C_setup(I2C_Setup *Init) {

int old_intm;

Uint16 IPSC_calc;

old_intm = IRQ_globalDisable();

I2C_RSET(I2CMDR,I2C_I2CMDR_RMK(Init->free,0,0,0,1,1,Init->addrmode,0,Init->dlb,1,0,0,Init->bitbyte));

/* set own address */

I2C_RSET(I2COAR,Init->ownaddr); /* if slave, need to specify own address */

/* calculating the IPSC value */

IPSC_calc = (Init->sysinclock)/12; /* must correct rounding issue */

I2C_RSET(I2CPSC,IPSC_calc);

/* calculating the ICCLKL and ICCLKH register values */

I2C_RSET(I2CCLKL,15);

I2C_RSET(I2CCLKH,15);

IRQ_globalRestore(old_intm);

} /* end of init */

分析上面的程序,在计算I2C总线的频率时,出现了错误:因为I2C总线的频率主要由I2CPSC、I2CCLKL和I2CCLKH寄存器共同决定的。在程序中,根本就没有去查询I2C_Setup结构体中rate变量,只是查询了系统时钟,然后给I2CPSC寄存器赋值,而给I2CCLKL和I2CCLKH寄存器赋了固定值15。这无**确完成I2C时钟的配置。

打算重新编写这个函数。假设,input频率单位为MHz,I2C总线频率为kHz,则I2C总线频率的计算公式为:

module clock * 1000

master clock=-------------------------------------------------

[( ICCL+d )+( ICCH+d )]* (IPSC+1)

令ICCL = ICCH,则得到公式为:

input clock * 1000

master clock=------------------------------------------

2 * ( ICC+d ) *(IPSC+1)

根据上面的分析,重新编写了I2C_setup函数,如下:

void myI2C_setup(I2C_Setup * Init)

{

int old_intm;

Uint16 ICC_calc;

old_intm = IRQ_globalDisable();

I2C_RSET(I2CMDR,0); // reset I2C

// Set prescaler to generate module clock

// I2C input clock

// module clock=-------------------- , d=5

// ( IPSC+1 )

//

I2C_FSET(I2CSTR,BB,0x1); /* Writing a 1 to BB Bus busy bit is supposed to clear it*/

/* calculating the IPSC value */

I2C_RSET(I2CPSC,11);

// Set I2CCLKL & I2CCLKH to generate master clock

ICC_calc = (Init->sysinclock)/12;

ICC_calc = ICC_calc * 1000/2/(Init->rate);

ICC_calc = ICC_calc - 5;

I2C_RSET(I2CCLKL,ICC_calc); // 100kHz

I2C_RSET(I2CCLKH,ICC_calc);

/* set own address */

I2C_RSET(I2COAR,Init->ownaddr); /* if slave, need to specify own address */

//I2C模块复位,设置为主设备发送模式

I2C_RSET(I2CMDR,I2C_I2CMDR_RMK(Init->free,0,0,0,1,1,Init->addrmode,0,Init->dlb,1,0,0,Init->bitbyte));

}

通过测试,该函数能够成功用于EEPROM和AIC23的读写测试中。

此外,在采用byte write方式向EEPROM中连续写入数据时,注意在两次写入之间添加一个延时程序,否则会造成写入失败。

原文链接:http://www.61ic.com/Article/C5000/C55X/201107/36005.html

相关帖子

沙发
edishen| | 2015-1-27 23:47 | 只看该作者
看到太迟了    谢谢啦

使用特权

评论回复
板凳
zhangjin_comeon| | 2015-1-27 23:51 | 只看该作者
楼主对5509很熟悉   感谢分享

使用特权

评论回复
地板
biechedan| | 2015-1-29 00:16 | 只看该作者
这个平时真的不太注意到的。

使用特权

评论回复
5
zhangmangui| | 2015-1-29 21:45 | 只看该作者
支持一下   楼主分享的资料不错

使用特权

评论回复
6
edishen| | 2015-1-31 00:02 | 只看该作者
经典的分享

使用特权

评论回复
7
以马内利3005|  楼主 | 2015-1-31 10:47 | 只看该作者
edishen 发表于 2015-1-27 23:47
看到太迟了    谢谢啦

嘿嘿,不客气!

使用特权

评论回复
8
以马内利3005|  楼主 | 2015-1-31 10:48 | 只看该作者
zhangjin_comeon 发表于 2015-1-27 23:51
楼主对5509很熟悉   感谢分享

分享别人的,嘿嘿。

使用特权

评论回复
9
以马内利3005|  楼主 | 2015-1-31 10:49 | 只看该作者
biechedan 发表于 2015-1-29 00:16
这个平时真的不太注意到的。

是的

使用特权

评论回复
10
以马内利3005|  楼主 | 2015-1-31 10:49 | 只看该作者
zhangmangui 发表于 2015-1-29 21:45
支持一下   楼主分享的资料不错

谢谢版主!

使用特权

评论回复
11
以马内利3005|  楼主 | 2015-1-31 10:49 | 只看该作者
edishen 发表于 2015-1-31 00:02
经典的分享

使用特权

评论回复
12
zhangjin_comeon| | 2015-1-31 16:26 | 只看该作者
好几天没来了  

使用特权

评论回复
13
以马内利3005|  楼主 | 2015-2-1 00:13 | 只看该作者
zhangjin_comeon 发表于 2015-1-31 16:26
好几天没来了

是 啊

使用特权

评论回复
14
artom| | 2016-1-11 16:31 | 只看该作者
楼主,你好,,我最近在写i2c读写eeprom(at24c16)的程序,总是有问题。。我感觉我的读写函数可能有问题。。你可以分享下你的函数给我吗?  感激不尽

使用特权

评论回复
15
以马内利3005|  楼主 | 2016-1-29 14:29 | 只看该作者
我的eeprom用的是mcbsp读写的,不是i2c,不过有一点可能忽略,就是eeprom的读写函数有时间周期的限制,不能太频繁,在读写函数某位置要加延时函数,我现在不做这方面了,具体不太记得了,你自己想想看,再看看datasheet

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

个人签名:十字架十字架,永是我的荣耀。

18

主题

272

帖子

14

粉丝