This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] TMS320F28335:轮询时的 I2C 读取/写入

Guru**** 2387080 points
Other Parts Discussed in Thread: TCAL9539-Q1
请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1496050/tms320f28335-i2c-read-write-on-polling

器件型号:TMS320F28335

工具与软件:

我在 F28335中使用 I2C。  

I2C 连接到三个 IO 扩展器 IC - TCAL9539-Q1。

我将共享我正在使用的 I2C 代码、如下所示。

我将在主循环中按顺序使用这种读写函数。  

在读取功能期间、我面临问题。
当我在调试模式下运行代码时、逐步操作- 我正在正确获取数据。 但是、当我持续运行代码时、数据并不正确、正如我在观察窗口中分析过的那样。

我还想验证轮询方法的读取和写入函数。

请验证代码并让我知道可能的解决方案。
提前感谢您。

/**
*@简介: I2C C GPIO 的初始化
*@param[in]
*@param[out]
*/
void vInitI2CMPIO (void)

EALLOW;

//
//启用所选引脚的内部上拉
//用户可以启用或禁用上拉。
//这将启用指定引脚的上拉。
//注释掉其他不需要的行。
//
GpioCtrlRegs.GPBPUD.bit.GPIO32 = 0;//启用 GPIO32的上拉(SDAA)
GpioCtrlRegs.GPBPUD.bit.GPIO33 = 0;//启用 GPIO33的上拉(SCLA)

//
//将所选引脚的鉴定设置为仅异步
//这将为所选引脚选择异步(无限定条件)。
//注释掉其他不需要的行。
//
GpioCtrlRegs.GPBQSEL1.bit.GPIO32 = 3;//异步输入 GPIO32 (SDAA)
GpioCtrlRegs.GPBQSEL1.bit.GPIO33 = 3;//异步输入 GPIO33 (SCLA)

//
//使用 GPIO 寄存器配置 SCI 引脚
//指定可能的 GPIO 引脚将是 I2C 功能引脚
//引脚。 注释掉其他不需要的行。
//
GpioCtrlRegs.GPBMUX1.bit.GPIO32 = 1;//将 GPIO32配置为 SDAA
GpioCtrlRegs.GPBMUX1.bit.GPIO33 = 1;//将 GPIO33配置为 SCLA

EDIS;
}

/**
*@简介:特殊功能寄存器的 I2C 初始化
*@param[in]
*@param[out]
*/
void vI2CaInitSFR (void)

//默认值-对于150MHz SYSCLKOUT
I2caRegs.I2CPS.all = 14;//预分频器-需要在模块时钟上支持7-12MHz (150/(14+1)= 10MHz)


I2caRegs.I2CCLKL = 15;//注意:必须为非零//10/(I2CCLKL+I2CCLKH)= i2c 速度
I2caRegs.I2CCLKH = 10;//注意:必须为非零
I2caRegs.I2CIER = 0;//启用 SCD 和 ARDY 中断

I2caRegs.I2CMDR.all = 0x0020;//使 I2C 退出复位
//挂起时停止 I2C
}

/**
*@简介:阅读 I2C 函数
*@param[in]: uint16_t ui16SlaveAddress 是从设备地址
* uint16_t ui16CmdAddress、命令地址
* uint16_t * pui16ReadBuffer、读取数据缓冲区
* uint16_t i16Nbyte -字节数
*@param[out]: true 或 false
*/
bool bReadI2C (uint16_t ui16SlaveAddress、uint16_t ui16CmdAddress、uint16_t * ui16ReadBuffer、uint8_t ui8Nbyte)

uint16_t i;

//等待从任何之前的事务中停止
while (I2caRegs.I2CMDR.bit.stp);

//设置从地址
I2caRegs.I2CSAR = ui16SlaveAddress;

//检查总线是否繁忙
while (I2caRegs.I2CSTR.bit.bb);

//写入寄存器地址(启动条件)**
I2caRegs.I2CCNT = 1;//一个字节(寄存器地址)
I2caRegs.I2CMDR.all = 0x6620;//主发送模式、启动条件

while (!I2caRegs.I2CSTR.bit.XRDY);//等待 TX 就绪

I2caRegs.I2CDXR = ui16CmdAddress;//发送寄存器地址

while (!I2caRegs.I2CSTR.bit.ARDY);//等待事务完成

//**确保在读取之前停止条件**
I2caRegs.I2CMDR.bit.stp = 1;
while (I2caRegs.I2CMDR.bit.stp);

//重新启动读取(重复启动)**
I2caRegs.I2CCNT = ui8Nbyte;//要读取的字节数
I2caRegs.I2CMDR.all = 0x6C20;//主接收模式、重复启动

对于(i = 0;i < ui8N 字节;i++)

while (!I2caRegs.I2CSTR.bit.RRDY);//等待 RX 就绪

pui16ReadBuffer[i]= I2caRegs.I2CDRR;//从从器件读取数据
}

I2caRegs.I2CMDR.bit.stp = 1;// Send stop condition (发送停止条件)

返回 true;
}

/**
*@简介:编写 I2C 函数
*@param[in]: uint16_t ui16SlaveAddress, Slave Device address
* uint16_t ui16CmdAddress、命令地址
* uint16_t * pui16WriteBuffer、写入缓冲区地址
* uint8_t ui8nbyte -字节数
*@param[out]: true 或 false
*/
bool bWriteI2C (uint16_t ui16SlaveAddress、uint16_t ui16CmdAddress、uint16_t * ui16WriteBuffer、uint8_t ui8nbyte)

uint16_t i = 0;

//在发送新数据之前清除先前的错误
I2caRegs.I2CSTR.bit.nack = 1;// Clear NACK bit (清除 NACK 位)
I2caRegs.I2CSTR.bit.bb = 1;//如果卡住、则清除总线忙
I2caRegs.I2CSTR.bit.ARDY = 1;// Clear ARDY (事务完成)标志

//如果 I2C 总线卡滞、请将其复位
如果(I2caRegs.I2CSTR.bit.BB = 1)

I2caRegs.I2CMDR.bit.stp = 1;// Send stop (发送停止)以释放总线
I2caRegs.I2CMDR.all = 0x0020;// Reset I2C module.
}

//设置从机地址
I2caRegs.I2CSAR = ui16SlaveAddress;

//配置传输
I2caRegs.I2CCNT = ui8nbyte + 1;//发送的总字节数(命令+数据)
I2caRegs.I2CDXR = ui16CmdAddress;//发送命令

//发送启动条件
I2caRegs.I2CMDR.all = 0x6E20;// STT=1 (启动)、TRX=1 (发送)、MST=1 (主器件)、IRS=1 (I2C 启用)

//等待 TX 就绪(XRDY)
while (I2caRegs.I2CSTR.bit.XRDY = 0);

//发送数据字节
对于(i = 0;i < ui8nbyte;i++)

I2caRegs.I2CDXR = pui16WriteBuffer[i];//加载数据到传输缓冲区

//等待 TX 就绪(XRDY)
while (I2caRegs.I2CSTR.bit.XRDY = 0);
}

//发送停止条件
I2caRegs.I2CMDR.bit.stp = 1;

//检查 I2C 是否已确认
如果(I2caRegs.I2CSTR.bit.nack == 1)

返回 false;
}

返回 true;

}
e2e.ti.com/.../0640.i2c.c

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Kaushik

    感谢您联系我们。

    [报价用户 id="560999" url="~/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1496050/tms320f28335-i2c-read-write-on-polling "]但当我持续运行代码时、数据不正确、因为我可以在观察窗口中分析。

    那么您将至少获得一些数据。 您是否可以使用逻辑分析仪/示波器来查看 C2000器件接收到的确切数据包?

    分步代码和正常运行代码之间的差异表明存在时序问题。 当您单步执行代码时、是否在每次运行 while 循环的实例时设置了断点? 您的主循环中还有什么其他东西? 您可能需要将轮询从 while 循环移至以一致频率运行的后台任务。

    您还可以考虑使用 I2C 模块的本机 RRDYINT、这样您就不必连续轮询 I2C 寄存器

    此致、

    Peter