[经验] 【C2000 LaunchPad】I2C模块应用篇(查询法)

ltbytyn   2013-12-30 16:33 楼主
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楼。 本帖最后由 ltbytyn 于 2016-4-17 16:37 编辑

回复评论 (30)

【富士通FRAM心得提交——MB85RC64】一文使用的就是C2000 LaunchPad(F28027)I2C模块对FRAM进行测试。可供大家参考。
https://bbs.eeworld.com.cn/thread-427610-1-1.html
点赞  2013-12-30 16:43
谢谢斑竹的贡献。收了。
点赞  2014-1-3 11:40
引用: liuming759 发表于 2014-1-3 11:40
谢谢斑竹的贡献。收了。

TI官方的I2C程序就像玩具,不中用,大家只能探讨补全了。
点赞  2014-1-3 12:33
版主给个例子源码吧
点赞  2014-1-13 08:37
引用: linshl 发表于 2014-1-13 08:37
版主给个例子源码吧

给什么样的例子。楼主讲的还不够详细吗,具体的要自己去做。
点赞  2014-1-13 08:43
引用: linshl 发表于 2014-1-13 08:37
版主给个例子源码吧

给你个源码对你没有任何帮助。我已经讲的太详细了,你把我提到的整合一起就能成功,动动手对你的帮助才是最大的。
点赞  2014-1-13 09:15
Z这个很急需啊~!强烈帮顶~!
点赞  2014-1-27 14:34
引用: yue621 发表于 2014-1-27 14:34
Z这个很急需啊~!强烈帮顶~!

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

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

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

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

24c02的话,传送完器件地址以后不是只要传送一个字节的地址吗??为什么有high adress 和low adress
点赞  2014-7-8 10:53
24c02地址只有一个字节。24c64地址有个2个字节。自己想想或者查资料
点赞  2014-7-8 11:43
非常感谢。
点赞  2014-8-26 20:42
谢谢,楼主,看了上面的程序,还有几个问题请教,发送或接收数据之前还用查询一下总线的状态吗比如
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
点赞  2014-12-30 11:51
发送/接收的时候无需人为判断总线状态。因为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


点赞  2014-12-30 12:36
引用: 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寄存器,为什么这么操作呢,谢谢 本帖最后由 ergelove 于 2014-12-30 14:17 编辑
点赞  2014-12-30 14:16
楼主你好 我按照你的跑了一下 但是不成功啊,能帮帮我吗?或者给一个源程序,我想参考下;
点赞  2016-4-9 12:00
12下一页
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复