我一直在尝试将 TMS320C5535配置为 I2C 从设备。 我正在 ezDSP5535平台上进行开发。 似乎我没有正确设置 I2C 中断、但在这一点上、我已经从阅读文献中用尽了任何想法。 基本上、如果我在从器件地址处使用 ICOAR 设置我的代码、我永远不会在 I2C 的 ISR 中遇到断点。 但是、如果我使用逻辑分析仪观察 SDA 和 SCL 线路、则在主处理器发送从器件地址时、DSP 会拉低 SDA 和 SCL 线路。 如果主处理器发送到其他地址、SDA 和 SCL 线不会被我的代码下拉、我可以成功地观察主处理器的其他 I2C 活动。 在任一种情况下、在 I2C 中断例程开始处设置的断点都不会被命中。 有人可以提供帮助吗? 感谢 you.e2e.ti.com/.../4431.main.ce2e.ti.com/.../usbstk5505.he2e.ti.com/.../IOpins.he2e.ti.com/.../aic3204.he2e.ti.com/.../csl_5F00_intc.he2e.ti.com/.../cslr_5F00_cpu.he2e.ti.com/.../PLL.he2e.ti.com/.../usbstk5505_5F00_i2c.c
我还附加了源文件、但 I2C 初始化和中断设置代码如下:
void lockin_I2C_init (void)
{
/*********
I2C 设置
设置是作为从发送器
指南来自 TMS320C5535技术参考手册(SPRUH87D)
P 317、sec 9.2.12.2描述了如何配置从接收器/发送器
这是本节的功能。
秘书长的报告 /
IRQ_disableAll();
/*设置中断矢量起始地址*/
IRQ_setVecs ((uint32)(&VECSTART));
IRQ_plug (I2C_EVENT、&I2C_ISR);
IRQ_CLEARALL (); //清除任何挂起的中断
//step 1显示"enable clock from PSC level"(从 PSC 级别启用时钟)。
SYS_PCGCR1 &=~SYSCLKDIS; //当该位为0时、系统时钟激活
SYS_PCGCR1 &=~I2CCG; //当该位为0时、I2C 外设时钟有效
//step 2复位 I2C
ICMDR &=~MDR_IRS;
//步骤3
//设置从地址,7位
ICMDR &=~MDR_XA;
ICOAR = 0x60;//0x61;//LockinSLA; //将来,较低的4位将与插槽 ID 进行 OR 运算
//步骤4.
//ICIMR 针对特定的 I2C 外设事件启用中断。
//仅'AAS'、用于识别其自身从地址的 DSP 中断最初为
//启用。 然后、这将设置一个被启用的中断序列、如下所示:
// -ICRRDY 可检测从器件地址之后的命令字节
// -ICXRDY 可检测 ICXRDY 何时准备好接收新数据
// -scd:检测到停止位、然后再次设置 AAS 以进行下一次发生
ICIMR = ICIMR_AAS;
//步骤5.
//设置 I2C 预分频器(ICPSC 寄存器、第335页和第309页时钟图)
//this set the prescaled module clock which is described
//AS 要求6.7-13.3 MHz 的范围。 在编写本文档时、时钟源完全不清楚。
//I 正在按照所用常量的 USBSTK5505_I2C_init ()代码执行操作、它们的状态为20
//对于12MHz 时钟。 我不知道这个数字来自哪里、对于100MHz 并不明智
//整体时钟,但使用时基于假设,因为存在其他时钟,所以它必须正确
eZdsp 上的//I2C 器件、它们工作正常、例如 AIC3204编解码器。
///Step 5显示预分频模块时钟频率= PLL1输出频率/(IPSC + 1)
//PLL1输出频率被理解为100MHz。 如果值为20、则会得到4.76MHz、这太慢
//指定所需范围。 根据我的计算、对于12MHz、PSC 应为7.33
ICPSC = 020;
//步骤6.
//配置 I2C 串行时钟频率 假设是对称的高半周期和低半周期、
//运行频率为(步骤5频率)/(ICC + 10)、其中 ICC 表示 ICCL 和 ICCH
//同样,USBSTK5505_I2C_init()代码与我的计算之间存在差异。
//对于20KHz 的 SCL,代码调用值20。 如果步骤5为12MHz、则提供 SCL
//、400 KHz。 如果步骤5为4.76MHz、则 SCL 为158.75KHz。 (P 326)
ICCLKL=20;
ICCLKH=20;
//步骤7.
//配置模式寄存器 ICMDR (第329页)
ICMDR = 0;
ICMDR |= RM; //数据字在 STP 位手动置位前连续重新生成/传输
ICMDR |= MDR_STT; //monitor 总线和 transmit /rec'v、用于响应主命令
//步骤8.
ICSTR = ICSTR; //通过写入1来清除任何挂起的中断标志
while (ICIVR) //通过读取 ICIVR 来将其置零
;
ICDXR = CURRENT_YN[0]; //Keep XSMT=0、防止 SDA/SCA 线路拉低
//从复位中释放 I2C
ICMDR |= MDR_IRS;
//步骤9.
//清除存在的任何中断
ICSTR = ICSTR; //通过写入1来清除任何挂起的中断标志
while (ICIVR) //通过读取 ICIVR 来将其置零
;
//步骤10
//检测起始条件和自身地址
ICMDR |= MDR_STT; //这也是在步骤7中完成的
//启用 CPU 中断
enable_interrupts ();
//IRQ_globalEnable();
ICntr = 0;
TxP =&lockin_Drain[0];
}
ISR 代码如下:
中断空 I2C_ISR (空)
{
SYS_GPIO_DATAOUT0 &= ClearPin15;
//确定中断源
if ( ICSTR & ICSTR_AAS )
{
//从器件地址建议
ICntr = 1;
TxP =&Current_yn[1];
}
否则( ICSTR & ICXRDY )
{
//发送请求的数据
ICDXR =*(TXP+icntr++);
如果(icntr == 6)
ICIMR = ICIMR_SCD;
}
否则、如果(ICSTR & ICSTR_SCD) //停止位
ICIMR = ICIMR_AAS;
//清除刚刚处理的挂起中断
ICSTR = ICSTR;
SYS_GPIO_DATAOUT0 |= SetPin15;
enable_interrupts ();
}