14304|30

2856

帖子

260

TA的资源

五彩晶圆(高级)

楼主
 

【C2000 LaunchPad】I2C模块应用篇(查询法) [复制链接]

 
本帖最后由 ltbytyn 于 2016-4-17 16:37 编辑

F282xx/F283xx自身带有I2C模块,但受限于TI的官方例程中使用了fifo,其深度为4,在写EEPROM时,读写地址16位,占了2个字节,最多只留下2个字节存储数据,使用很不方便、实用性也极差。有不少网友在这一块碰壁,甚至逼的没办法使用IO口模拟I2C,放弃使用I2C模块。最近一直在测试28027的I2C模块有所获,可突破发送/接收长度限制(非fifo模式,当然这个长度也要和I2C器件匹)。本查介绍查询方式下的I2C模块使。
1、宏定义I2C模块操作参数
#define I2C_SLAVE_ADDR        0x50    //器件地址不含读写位。以24Cxx系列为例,器件地址应为:(0xA0>>1),即0x50
#define I2C_NUMBYTES          10        //发送/接收数据长度
#define I2C_EEPROM_HIGH_ADDR  0x00
#define I2C_EEPROM_LOW_ADDR   0x00

2、设置相应GPIO引脚用作I2C引脚。 修改F2802x_I2C.c文件中的void InitI2CGpio()函数。
3、初始化I2C模块。
void I2CA_Init(void)
{
   // Initialize I2C
   I2caRegs.I2CSAR = 0x0050;        // Slave address - EEPROM control code

   // I2CCLK = SYSCLK/(I2CPSC+1)
   #if (CPU_FRQ_40MHZ||CPU_FRQ_50MHZ)
     I2caRegs.I2CPSC.all = 4;       // Prescaler - need 7-12 Mhz on module clk
   #endif

   #if (CPU_FRQ_60MHZ)
     I2caRegs.I2CPSC.all = 6;       // Prescaler - need 7-12 Mhz on module clk
   #endif
   I2caRegs.I2CCLKL = 10;           // NOTE: must be non zero
   I2caRegs.I2CCLKH = 5;            // NOTE: must be non zero
   I2caRegs.I2CIER.all = 0x00;      // Enable SCD & ARDY interrupts

   I2caRegs.I2CMDR.all = 0x0020;    // Take I2C out of reset
                                    // Stop I2C when suspended

   I2caRegs.I2CFFTX.all = 0x0000;   // Enable FIFO mode and TXFIFO
   I2caRegs.I2CFFRX.all = 0x0000;   // Enable RXFIFO, clear RXFFINT,

   return;
}
4、执行I2C模块接收或者发送。
//I2C模块发送数据到I2C器件。
void  I2CA_SendData(void)
{
           Uint16 i;
           I2caRegs.I2CSAR = I2C_SLAVE_ADDR;                         //Set slave address
           I2caRegs.I2CCNT = I2C_NUMBYTES + 2;                         //Set count to 5 characters plus 2 address bytes
           I2caRegs.I2CDXR = I2C_EEPROM_HIGH_ADDR;                        //Send eeprom high address
           I2caRegs.I2CMDR.bit.TRX = 1;                                 //Set to Transmit mode
           I2caRegs.I2CMDR.bit.MST = 1;                                 //Set to Master mode
           I2caRegs.I2CMDR.bit.FREE = 1;                                //Run in FREE mode
           I2caRegs.I2CMDR.bit.STP = 1;                                 //Stop when internal counter becomes 0
           I2caRegs.I2CMDR.bit.STT = 1;                                 //Send the start bit, transmission will follow
           while(I2caRegs.I2CSTR.bit.XRDY == 0){};                 //Do nothing till data is shifted out
           I2caRegs.I2CDXR = I2C_EEPROM_LOW_ADDR;                          //Send eeprom low address

           for(i = 0; i < I2C_NUMBYTES; i++){
                   while(I2caRegs.I2CSTR.bit.XRDY == 0){};         //Do nothing till data is shifted out
                   I2caRegs.I2CDXR = TxdData;                                         //Send out the message
           }
}
//I2C模块从I2C器件接收数据
void  I2CA_ReceiveData(void)
{
           Uint16 i;
           I2caRegs.I2CSAR = I2C_SLAVE_ADDR;                         //Set slave address
           I2caRegs.I2CCNT = 2;                                                 //Set count to 2 address bytes
           I2caRegs.I2CDXR = I2C_EEPROM_HIGH_ADDR;                        //Send eeprom high address
           I2caRegs.I2CMDR.bit.TRX = 1;                                 //Set to Transmit mode
           I2caRegs.I2CMDR.bit.MST = 1;                                 //Set to Master mode
           I2caRegs.I2CMDR.bit.FREE = 1;                                //Run in FREE mode
           I2caRegs.I2CMDR.bit.STP = 0;                                 //Dont release the bus after Tx
           I2caRegs.I2CMDR.bit.STT = 1;                                 //Send the start bit, transmission will follow

           while(I2caRegs.I2CSTR.bit.XRDY == 0){};                 //Do nothing till data is shifted out
           I2caRegs.I2CDXR = I2C_EEPROM_LOW_ADDR;                         //Send eeprom low address
           I2caRegs.I2CCNT = I2C_NUMBYTES;                                //read 5 bytes from eeprom
           I2caRegs.I2CMDR.bit.TRX = 0;                                 //Set to Recieve mode
           I2caRegs.I2CMDR.bit.MST = 1;                                 //Set to Master mode
           I2caRegs.I2CMDR.bit.FREE = 1;                                //Run in FREE mode
           I2caRegs.I2CMDR.bit.STP = 1;                                 //Stop when internal counter becomes 0
           I2caRegs.I2CMDR.bit.STT = 1; //Repeated start, Reception will follow
           for(i = 0; i < I2C_NUMBYTES; i++){
                   while(I2caRegs.I2CSTR.bit.RRDY == 0){};         //I2CDRR not ready to read?
                   RxdData = I2caRegs.I2CDRR;
           }
}

测试程序见26楼。





最新回复

iic通信芯片之间的两根线,不错的分享。  详情 回复 发表于 2019-5-27 10:08

赞赏

1

查看全部赞赏

 
点赞 关注(3)

回复
举报

2856

帖子

260

TA的资源

五彩晶圆(高级)

沙发
 
【富士通FRAM心得提交——MB85RC64】一文使用的就是C2000 LaunchPad(F28027)I2C模块对FRAM进行测试。可供大家参考。
https://bbs.eeworld.com.cn/thread-427610-1-1.html
 
 

回复

290

帖子

0

TA的资源

纯净的硅(初级)

板凳
 
谢谢斑竹的贡献。收了。

点评

TI官方的I2C程序就像玩具,不中用,大家只能探讨补全了。  详情 回复 发表于 2014-1-3 12:33
 
 
 

回复

2856

帖子

260

TA的资源

五彩晶圆(高级)

4
 
liuming759 发表于 2014-1-3 11:40
谢谢斑竹的贡献。收了。

TI官方的I2C程序就像玩具,不中用,大家只能探讨补全了。
 
 
 

回复

7

帖子

0

TA的资源

一粒金砂(中级)

5
 
版主给个例子源码吧

点评

给你个源码对你没有任何帮助。我已经讲的太详细了,你把我提到的整合一起就能成功,动动手对你的帮助才是最大的。  详情 回复 发表于 2014-1-13 09:15
给什么样的例子。楼主讲的还不够详细吗,具体的要自己去做。  详情 回复 发表于 2014-1-13 08:43
 
 
 

回复

290

帖子

0

TA的资源

纯净的硅(初级)

6
 
linshl 发表于 2014-1-13 08:37
版主给个例子源码吧

给什么样的例子。楼主讲的还不够详细吗,具体的要自己去做。
 
 
 

回复

2856

帖子

260

TA的资源

五彩晶圆(高级)

7
 
linshl 发表于 2014-1-13 08:37
版主给个例子源码吧

给你个源码对你没有任何帮助。我已经讲的太详细了,你把我提到的整合一起就能成功,动动手对你的帮助才是最大的。
 
 
 

回复

68

帖子

0

TA的资源

一粒金砂(高级)

8
 
Z这个很急需啊~!强烈帮顶~!
 
 
 

回复

2856

帖子

260

TA的资源

五彩晶圆(高级)

9
 
yue621 发表于 2014-1-27 14:34
Z这个很急需啊~!强烈帮顶~!

                                       
 
 
 

回复

172

帖子

0

TA的资源

一粒金砂(中级)

10
 
I2C模块是不是只有I2CCNT 减到0才会发出停止信号??

点评

I2C模块是硬件的,当检测到发送完了就会发结束自动发信号,不需要人为干预  详情 回复 发表于 2014-7-8 08:34
 
 
 

回复

2856

帖子

260

TA的资源

五彩晶圆(高级)

11
 
jetlin1992 发表于 2014-7-7 23:44
I2C模块是不是只有I2CCNT 减到0才会发出停止信号??

I2C模块是硬件的,当检测到发送完了就会发结束自动发信号,不需要人为干预

点评

他是检测I2CCNT是否为0还是检测fifo是否空了  详情 回复 发表于 2014-7-8 09:26
 
 
 

回复

172

帖子

0

TA的资源

一粒金砂(中级)

12
 
ltbytyn 发表于 2014-7-8 08:34
I2C模块是硬件的,当检测到发送完了就会发结束自动发信号,不需要人为干预

他是检测I2CCNT是否为0还是检测fifo是否空了

点评

本文讲的是非FIFO方式。文章前面已经踢过了  详情 回复 发表于 2014-7-8 10:00
 
 
 

回复

2856

帖子

260

TA的资源

五彩晶圆(高级)

13
 
jetlin1992 发表于 2014-7-8 09:26
他是检测I2CCNT是否为0还是检测fifo是否空了

本文讲的是非FIFO方式。文章前面已经踢过了

点评

24c02的话,传送完器件地址以后不是只要传送一个字节的地址吗??为什么有high adress 和low adress  详情 回复 发表于 2014-7-8 10:53
 
 
 

回复

172

帖子

0

TA的资源

一粒金砂(中级)

14
 
ltbytyn 发表于 2014-7-8 10:00
本文讲的是非FIFO方式。文章前面已经踢过了

24c02的话,传送完器件地址以后不是只要传送一个字节的地址吗??为什么有high adress 和low adress
 
 
 

回复

2856

帖子

260

TA的资源

五彩晶圆(高级)

15
 
24c02地址只有一个字节。24c64地址有个2个字节。自己想想或者查资料
 
 
 

回复

5

帖子

0

TA的资源

一粒金砂(初级)

16
 
非常感谢。
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

17
 
谢谢,楼主,看了上面的程序,还有几个问题请教,发送或接收数据之前还用查询一下总线的状态吗比如
if (I2caRegs.I2CMDR.bit.STP == 1) 和  if (I2caRegs.I2CSTR.bit.BB == 1)

还有为什么要先把地址写进DXR寄存器再写MDR寄存器
           I2caRegs.I2CDXR = I2C_EEPROM_HIGH_ADDR;                        //Send eeprom high address
           I2caRegs.I2CMDR.bit.TRX = 1;                                 //Set to Transmit mode
           I2caRegs.I2CMDR.bit.MST = 1;                                 //Set to Master mode
           I2caRegs.I2CMDR.bit.FREE = 1;                                //Run in FREE mode
           I2caRegs.I2CMDR.bit.STP = 0;                                 //Dont release the bus after Tx
           I2caRegs.I2CMDR.bit.STT = 1;                                 //Send the start bit, transmission

点评

发送/接收的时候无需人为判断总线状态。因为28027中的I2C模块是纯硬件的,硬件自己会去检测,在总线空闲的时候发送/接收。“还有为什么要先把地址写进DXR寄存器再写MDR寄存器”没搞懂你的意思想说什么[/backcolor]  详情 回复 发表于 2014-12-30 12:36
 
 
 

回复

2856

帖子

260

TA的资源

五彩晶圆(高级)

18
 
发送/接收的时候无需人为判断总线状态。因为28027中的I2C模块是纯硬件的,硬件自己会去检测,在总线空闲的时候发送/接收。“还有为什么要先把地址写进DXR寄存器再写MDR寄存器”没搞懂你的意思想说什么
ergelove 发表于 2014-12-30 11:51
谢谢,楼主,看了上面的程序,还有几个问题请教,发送或接收数据之前还用查询一下总线的状态吗比如
if (I2caRegs.I2CMDR.bit.STP == 1) 和  if (I2caRegs.I2CSTR.bit.BB == 1)

还有为什么要先把地址写进DXR寄存器再写MDR寄存器
           I2caRegs.I2CDXR = I2C_EEPROM_HIGH_ADDR;                        //Send eeprom high address
           I2caRegs.I2CMDR.bit.TRX = 1;                                 //Set to Transmit mode
           I2caRegs.I2CMDR.bit.MST = 1;                                 //Set to Master mode
           I2caRegs.I2CMDR.bit.FREE = 1;                                //Run in FREE mode
           I2caRegs.I2CMDR.bit.STP = 0;                                 //Dont release the bus after Tx
           I2caRegs.I2CMDR.bit.STT = 1;                                 //Send the start bit, transmission


点评

就是如下语句 I2caRegs.I2CDXR = I2C_EEPROM_HIGH_ADDR; //Send eeprom high address I2caRegs.I2CMDR.bit.TRX = 1;  详情 回复 发表于 2014-12-30 14:16
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

19
 
本帖最后由 ergelove 于 2014-12-30 14:17 编辑
ltbytyn 发表于 2014-12-30 12:36
发送/接收的时候无需人为判断总线状态。因为28027中的I2C模块是纯硬件的,硬件自己会去检测,在总线空闲的时候发送/接收。“还有为什么要先把地址写进DXR寄存器再写寄存器”没搞懂你的意思想说什么

            就是如下语句                       I2caRegs.I2CDXR = I2C_EEPROM_HIGH_ADDR;                        //Send eeprom high address
           I2caRegs.I2CMDR.bit.TRX = 1;                                 //Set to Transmit mode
           I2caRegs.I2CMDR.bit.MST = 1;                                 //Set to Master mode
           I2caRegs.I2CMDR.bit.FREE = 1;                                //Run in FREE mode
           I2caRegs.I2CMDR.bit.STP = 0;                                 //Dont release the bus after Tx
           I2caRegs.I2CMDR.bit.STT = 1;                                 //Send the start bit, transmission will follow


           先把eeprom的地址写入DXR寄存器
            再写MDR寄存器,为什么这么操作呢,谢谢
 
 
 

回复

5

帖子

1

TA的资源

一粒金砂(初级)

20
 
楼主你好 我按照你的跑了一下 但是不成功啊,能帮帮我吗?或者给一个源程序,我想参考下;

点评

时间太长,代码未必能找到,我尽量找找看  详情 回复 发表于 2016-4-9 12:29
 
 
 

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

查找数据手册?

EEWorld Datasheet 技术支持

相关文章 更多>>
关闭
站长推荐上一条 1/8 下一条

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

About Us 关于我们 客户服务 联系方式 器件索引 网站地图 最新更新 手机版

站点相关: 国产芯 安防电子 汽车电子 手机便携 工业控制 家用电子 医疗电子 测试测量 网络通信 物联网

北京市海淀区中关村大街18号B座15层1530室 电话:(010)82350740 邮编:100190

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2025 EEWORLD.com.cn, Inc. All rights reserved
快速回复 返回顶部 返回列表