11095|10

31

帖子

0

TA的资源

一粒金砂(中级)

楼主
 

TMS320F28335 I2C控制RTC(DS1338)----查询 [复制链接]

 
TI 有关I2C的使用, 提供了EEPROM的例程, 该例程在controlSUITE中可以找到. 该例程写得非常完美, 值得借鉴, 但对于初学者来说还是有难度的. 看了ltbytyn君两篇关于TI 28027的两篇关于I2C的文章, 很受启发, 在此非常感谢他的无私分享.
I2C模块应用篇(查询法)
富士通FRAM应用心得
但在参考上述程序进行设计时 (使用TMS320F28335 I2C), 仍然会遇到种种问题, 特别是初学者, 会花费很多时间, 过程让人倍受煎熬. 下面我将近期项目测试时用到的例程与大家一起分享, 一起学习.
请看下面多字节写的代码
  1. /******************************************************************************
  2. 函数名称 : I2CA_Init
  3. 功能描述 : 初始化I2CA外设, CLK=400kHz
  4. 传         参 : 无
  5. 返   回  值 : 无
  6. ******************************************************************************/
  7. void I2CA_Init(void)
  8. {
  9.     // Initialize I2C
  10.     I2caRegs.I2CSAR = I2C_SLAVE_ADDR; // Slave address - RTC control code

  11.     #if (CPU_FRQ_150MHZ)              // Default - For 150MHz SYSCLKOUT
  12.         I2caRegs.I2CPSC.all = 14;     // Prescaler - need 7-12 Mhz on module clk (150/15 = 10MHz)
  13.     #endif
  14.     #if (CPU_FRQ_100MHZ)              // For 100 MHz SYSCLKOUT
  15.         I2caRegs.I2CPSC.all = 9;          // Prescaler - need 7-12 Mhz on module clk (100/10 = 10MHz)
  16.     #endif

  17.     I2caRegs.I2CCLKL = 10;                          // NOTE: must be non zero
  18.     I2caRegs.I2CCLKH = 5;                          // NOTE: must be non zero
  19.     //I2caRegs.I2CIER.all = 0x24;                  // Enable SCD & ARDY interrupts
  20.     I2caRegs.I2CIER.all = 0x00;                  // Disable I2CA interrupts

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

  23.     I2caRegs.I2CFFTX.all = 0x0000;          // Disable FIFO mode
  24.     I2caRegs.I2CFFRX.all = 0x0000;          // Disable RXFIFO

  25.     return;
  26. }

  27. /******************************************************************************
  28. 函数名称 : DS1338_WriteMultiByte
  29. 功能描述 : 设置多个时间寄存器初始值, 或向RAM区的某起始地址写入多个字节(不超过RAM区长度)的内容, 未考虑地址循环情况
  30. 传         参 : slaveAddr--从设备地址
  31.         regAddr--寄存器或纯存储器地址
  32.         regDat[]--写入的数据
  33.         datLen--数据长度(数据长度和地址长度总和可以超过FIFO深度, 但应在寻址区间内)
  34. 返   回  值 : 无
  35. ******************************************************************************/
  36. void DS1338_WriteMultiByte(Uint16 slaveAddr, Uint16 regAddr, Uint16 regDat[], Uint16 datLen)
  37. {
  38.     Uint16 i;

  39.     // Wait until the STP bit is cleared from any previous master communication.
  40.     // Clearing of this bit by the module is delayed until after the SCD bit is
  41.     // set. If this bit is not checked prior to initiating a new message, the
  42.     // I2C could get confused.
  43.     [color=Red]while(I2caRegs.I2CMDR.bit.STP == 1);[/color]

  44.     // Setup slave address
  45.     I2caRegs.I2CSAR = slaveAddr;

  46.     // Check if bus busy
  47.     [color=Red]while(I2caRegs.I2CSTR.bit.BB == 1);[/color]

  48.     [color=Blue]// Setup number of bytes to send(datLen + 1)
  49.     I2caRegs.I2CCNT = datLen + 1;[/color]

  50.     // Setup the address to send
  51.     I2caRegs.I2CDXR = regAddr;

  52.     // Send start as master transmitter
  53.     I2caRegs.I2CMDR.all = 0x6E20;

  54.     // Setup data to send
  55.     for (i=0; i<datLen; i++)
  56.     {
  57.             [color=Sienna]while(I2caRegs.I2CSTR.bit.XRDY == 0);[/color]
  58.             I2caRegs.I2CDXR = regDat[i];
  59.     }
  60. }
复制代码


这里没有开启FIFO, 没有使能中断, 仅通过查询寄存器的状态来进行写操作控制. 红色语句部分, 可以让你连续写操作(几个写函数在一起)时不会出错. 绿色语句中数据长度设置错误会导致停在---while(I2caRegs.I2CSTR.bit.XRDY == 0);
下面再来看看多字节多
  1. /******************************************************************************
  2. 函数名称 : DS1338_ReadMultiByte
  3. 功能描述 : 读取多个时间寄存器初始值, 或从RAM区的某起始地址读取多个字节的内容, 未考虑地址循环情况
  4. 传         参 : slaveAddr--从设备地址
  5.         regAddr--寄存器或纯存储器地址
  6.         regDat[]--读取数据的地址
  7.         datLen--数据长度
  8. 返   回  值 : 无
  9. ******************************************************************************/
  10. void DS1338_ReadMultiByte(Uint16 slaveAddr, Uint16 regAddr, Uint16 regDat[], Uint16 datLen)
  11. {
  12.     unsigned char i;
  13.         // Wait until the STP bit is cleared from any previous master communication.
  14.     // Clearing of this bit by the module is delayed until after the SCD bit is
  15.     // set. If this bit is not checked prior to initiating a new message, the
  16.     // I2C could get confused.
  17.     while(I2caRegs.I2CMDR.bit.STP == 1);

  18.     I2caRegs.I2CSAR = slaveAddr;

  19.     // Check if bus busy
  20.     while(I2caRegs.I2CSTR.bit.BB == 1);

  21.     // Send data to setup RTC address
  22.     I2caRegs.I2CCNT = 1;                  // Setup how many bytes to expect
  23.     I2caRegs.I2CDXR = regAddr;
  24.     I2caRegs.I2CMDR.all = 0x2620;

  25.     [color=Red]// Wait Register-access-ready
  26.     while(I2caRegs.I2CSTR.bit.ARDY == 0);[/color]

  27.     // Send restart as master receiver
  28.     I2caRegs.I2CCNT = datLen;    // Setup how many bytes to expect
  29.     I2caRegs.I2CMDR.all = 0x2C20;

  30.     for(i=0; i<datLen; i++)
  31.     {
  32.             [color=DarkRed]while(I2caRegs.I2CSTR.bit.RRDY == 0);[/color]
  33.             regDat[i] = I2caRegs.I2CDRR;
  34.     }
  35. }
复制代码


红色语句部分很重要, 不知ltbytyn君代码中美和没有这句, 是不是28027没有这个寄存器(应该不会吧), 感觉应该是 28027的主频低的缘故.
不加判断的话, 同样会导致停在---while(I2caRegs.I2CSTR.bit.XRDY == 0)处.

小结:
1 这种查询方法效率较低, 耗费CPU资源, 没有利用FIFO, 在实时应用中不可取. 附件中有FIFO例程.
2 I2C总线是比较基础的硬件外设, 很多场合都会用到. TI 的MSP430, C2000, Cortex-M3/M4 均有该外设, 但不同的MCU, I2C使用起来不尽相同, 不过原理都是相通的.

下面附上整个工程源码, 仅供参考.
查询法, 无FIFO Example_2833x_i2c_ds1338.rar (181.58 KB, 下载次数: 175)
FIFO 无中断例程
Example_2833x_i2c_ds1338_fifo.rar (236.81 KB, 下载次数: 172)

最新回复

太给力啊,呵呵,就喜欢这样有价值的分享。   详情 回复 发表于 2019-7-16 08:34

赞赏

2

查看全部赞赏

 
点赞 关注(1)

回复
举报

31

帖子

0

TA的资源

一粒金砂(中级)

沙发
 
本来想开两个帖子, 没时间, 事太多.
 
 

回复

31

帖子

0

TA的资源

一粒金砂(中级)

板凳
 
FIFO 发送代码
  1. /******************************************************************************
  2. 函数名称 : DS1338_WriteMultiByte
  3. 功能描述 : 设置多个时间寄存器初始值, 或向RAM区的某起始地址写入多个字节的内容, 未考虑地址循环情况
  4. 传         参 : slaveAddr--从设备地址
  5.         regAddr--寄存器或纯存储器地址
  6.         regDat[]--写入的数据
  7.         datLen--数据长度(数据长度和地址长度总和可以超过FIFO深度, 但应在寻址区间内)
  8. 返   回  值 : 无
  9. ******************************************************************************/
  10. void DS1338_WriteMultiByte(Uint16 slaveAddr, Uint16 regAddr, Uint16 regDat[], Uint16 datLen)
  11. {
  12.     Uint16 i;

  13.     // Wait until the STP bit is cleared from any previous master communication.
  14.     // Clearing of this bit by the module is delayed until after the SCD bit is
  15.     // set. If this bit is not checked prior to initiating a new message, the
  16.     // I2C could get confused.
  17.     while(I2caRegs.I2CMDR.bit.STP == 1);

  18.     // Setup slave address
  19.     I2caRegs.I2CSAR = slaveAddr;

  20.     // Check if bus busy
  21.     while(I2caRegs.I2CSTR.bit.BB == 1);

  22.     // Setup number of bytes to send(datLen + 1)
  23.     I2caRegs.I2CCNT = datLen + 1;

  24.     // Setup the address to send
  25.     I2caRegs.I2CDXR = regAddr;

  26.     // Send start as master transmitter
  27.     I2caRegs.I2CMDR.all = 0x6E20;

  28.     // Setup data to send
  29.     for (i=0; i<datLen; i++)
  30.     {
  31.             // Check the status of the transmit FIFO
  32.             while(I2caRegs.I2CFFTX.bit.TXFFST == 16);
  33.             I2caRegs.I2CDXR = regDat[i];
  34.     }
  35. }
复制代码

  1. /******************************************************************************
  2. 函数名称 : DS1338_ReadMultiByte
  3. 功能描述 : 读取多个时间寄存器初始值, 或从RAM区的某起始地址读取多个字节的内容, 未考虑地址循环情况
  4. 传         参 : slaveAddr--从设备地址
  5.         regAddr--寄存器或纯存储器地址
  6.         regDat[]--读取数据的地址
  7.         datLen--数据长度
  8. 返   回  值 : 无
  9. ******************************************************************************/
  10. void DS1338_ReadMultiByte(Uint16 slaveAddr, Uint16 regAddr, Uint16 regDat[], Uint16 datLen)
  11. {
  12.     unsigned char i;
  13.         // Wait until the STP bit is cleared from any previous master communication.
  14.     // Clearing of this bit by the module is delayed until after the SCD bit is
  15.     // set. If this bit is not checked prior to initiating a new message, the
  16.     // I2C could get confused.
  17.     while(I2caRegs.I2CMDR.bit.STP == 1);

  18.     I2caRegs.I2CSAR = slaveAddr;

  19.     // Check if bus busy
  20.     while(I2caRegs.I2CSTR.bit.BB == 1);

  21.     // Send data to setup RTC address
  22.     I2caRegs.I2CCNT = 1;                  // Setup how many bytes to expect
  23.     I2caRegs.I2CDXR = regAddr;
  24.     I2caRegs.I2CMDR.all = 0x2620;

  25.     // Wait Register-access-ready
  26.     while(I2caRegs.I2CSTR.bit.ARDY == 0);

  27.     // Send restart as master receiver
  28.     I2caRegs.I2CCNT = datLen;    // Setup how many bytes to expect
  29.     I2caRegs.I2CMDR.all = 0x2C20;

  30.     for(i=0; i<datLen; i++)
  31.     {
  32.             // Check the status of the receive FIFO
  33.             while(I2caRegs.I2CFFRX.bit.RXFFST == 0);
  34.             regDat[i] = I2caRegs.I2CDRR;
  35.     }
  36. }
复制代码
收多字节 FIFO代码

点评

谢谢楼主分享,但是不知道为啥我发现自己这边打断点看需要运行两次读操作才能看到正确的数  详情 回复 发表于 2019-4-19 16:06
 
 
 

回复

2万

帖子

74

TA的资源

管理员

4
 
太赞了,谢谢楼主分享。
加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身

点评

可以申精吗?  详情 回复 发表于 2017-6-10 09:24
 
个人签名

加油!在电子行业默默贡献自己的力量!:)

 
 

回复

31

帖子

0

TA的资源

一粒金砂(中级)

5
 
soso 发表于 2017-6-9 11:08
太赞了,谢谢楼主分享。

可以申精吗?

点评

综合了版主和核心坛友的建议,已经加精啦,希望楼主继续加油加油,多多分享技术干货,多多讨论。  详情 回复 发表于 2017-6-12 11:11
 
 
 

回复

2万

帖子

74

TA的资源

管理员

6
 

综合了版主和核心坛友的建议,已经加精啦,希望楼主继续加油加油,多多分享技术干货,多多讨论。
加EE小助手好友,
入技术交流群
EE服务号
精彩活动e手掌握
EE订阅号
热门资讯e网打尽
聚焦汽车电子软硬件开发
认真关注技术本身
 
个人签名

加油!在电子行业默默贡献自己的力量!:)

 
 

回复

24

帖子

1

TA的资源

宇宙尘埃

7
 
谢谢分享
 
 
 

回复

6

帖子

0

TA的资源

一粒金砂(初级)

8
 
谢谢分享
 
 
 

回复

38

帖子

0

TA的资源

一粒金砂(中级)

9
 
microli 发表于 2017-6-9 10:23
FIFO 发送代码

接收多字节 FIFO代码

谢谢楼主分享,但是不知道为啥我发现自己这边打断点看需要运行两次读操作才能看到正确的数
 
 
 

回复

2

帖子

0

TA的资源

一粒金砂(初级)

10
 

谢谢楼主分享,但是不知道为啥我发现自己这边打断点看需要运行两次读操作才能看到正确的数
 
 
 

回复

2618

帖子

0

TA的资源

纯净的硅(高级)

11
 

太给力啊,呵呵,就喜欢这样有价值的分享。

 
 
 

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

随便看看
查找数据手册?

EEWorld Datasheet 技术支持

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

 
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
快速回复 返回顶部 返回列表