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.

[参考译文] TM4C123GH6PM:将系统切换至80MHz 时出现 I2C 问题

Guru**** 2473260 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/682829/tm4c123gh6pm-i2c-problem-when-switching-system-to-clock-to-80-mhz

器件型号:TM4C123GH6PM

您好!

在系统时钟设置为 SysCtlClockSet (SYSCTL_SYSDIV_1 | SYSCTL_USE_PLL | SYSCTL_INT | SYSCTL_XTAL_16MHz)的情况下使用 I2C 时获得的值正常工作、但当我将系统时钟增加到80MHz 时、通信仍然存在、但值会消失。 对我来说没有意义、因为 I2C 时钟线的时钟速度仍然设置为100kbps。


SysCtlClockSet (SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHz);//将时钟设置为80MHz
//初始化 I2C 模块0
void InitI2C0 (void)
{
//启用 I2C 模块0
SysCtlPeripheralEnable (SYSCTL_Periph_I2C0);

//复位模块
SysCtlPeripheralReset (SYSCTL_Periph_I2C0);

//启用包含 I2C 0的 GPIO 外设
SysCtlPeripheralEnable (SYSCTL_Periph_GPIOB);

//为端口 B2和 B3上的 I2C0功能配置引脚复用。
GPIOPinConfigure (GPIO_PB2_I2C0SCL);
GPIOPinConfigure (GPIO_PB3_I2C0SDA);

//为这些引脚选择 I2C 功能。
GPIOPinTypeI2CSCL (GPIO_PORTB_BASE、GPIO_PIN_2);
GPIOPinTypeI2C (GPIO_PORTB_BASE、GPIO_PIN_3);

//启用和初始化 I2C0主机模块。 使用的系统时钟
// I2C0模块。 最后一个参数设置 I2C 数据传输速率。
//如果为 false,则数据速率设置为100kbps,如果为 true,则数据速率将设置为
//设置为400kbps。
I2CMasterInitExpClk (I2C0_BASE、SysCtlClockGet (),false);

}


//在从器件
uint8_t I2CReceive(uint8_t slave_addr、uint8_t reg)
上读取指定寄存器{
while (I2CMasterBusy (I2C0_BASE));
//指定我们要向写入(寄存器地址)
//从器件
I2CMasterSlaveAddrSet (I2C0_BASE、SLAVE_addr、false);

//指定要读取的寄存器
I2CMasterDataPut (I2C0_BASE、reg);

//将控制字节和寄存器地址字节发送到从器件
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_START);

//等待 MCU 完成事务
while (I2CMasterBusy (I2C0_BASE));

//指定我们将从从从器件读取
I2CMasterSlaveAddrSet (I2C0_BASE、SLAVE_addr、TRUE);

//发送控制字节并从我们的寄存器中读取
//specified
I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_SINGLE_Receive);

//等待 MCU 完成事务
while (I2CMasterBusy (I2C0_BASE));

//返回从指定寄存器提取的数据
返回 I2CMasterDataGet (I2C0_BASE);
}



void I2C_send (uint8_t slave_addr、uint8_t reg、uint8_t data)
{
while (I2CMasterBusy (I2C0_BASE));
I2CMasterSlaveAddrSet (I2C0_BASE、SLAVE_addr、false);

//在从器件上发送寄存器地址
I2CMasterDataPut (I2C0_BASE、reg);

I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_START);
while (I2CMasterBusy (I2C0_BASE));
I2CMasterDataPut (I2C0_BASE、DATA);

I2CMasterControl (I2C0_BASE、I2C_MASTER_CMD_BURST_SEND_FINISH);
while (I2CMasterBusy (I2C0_BASE));

}

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

    [引用 user="Jacob Smith"]使用 I2C 时获得的值、系统时钟设置为  SysCtlClockSet (SYSCTL_SYSDIV_1 | SYSCTL_USE_PLL | SYSCTL_INT | SYSCTL_XTAL_16MHz);正常工作[/QUERE]

    我是否可以强烈反对?    "突出显示"中的参数不正确-会严重 地"超频 " MCU -因此证明"非法!"   当   "sysctl_use_pll" 参数为"正在播放"时、您可以降级到不低于"SYSDIV_2.5"的值。   因此-您对 "工作罚款"的诉求 会引起高度争议。

    [引用用户="Jacob Smith"] SysCtlClockSet (SYSCTL_SYSDIV_2_5 | SYSCTL_USE_PLL | SYSCTL_OSC_MAIN | SYSCTL_XTAL_16MHz);//将时钟设置为80MHz [/QUERPLET]

    您已经"决定了这个设置"-这是您所需80MHz 的完美选择。

    您只能说这些值 是"偏离"-这对于远程诊断而言不能证明"定量价值"。   而且- 您的非法系统时钟设置是否被报告正常工作-而您的合法/正确设置却失败了-这似乎并不奇怪吗?

    诊断任何串行总线实现(最常)都需要一个范围。   这可以确认 "比特率"、并启用多字节串行事务的研究视图。

    没有提到您在 两条 I2C 线路的每条线路上使用的"外部上拉电阻器"(~10K)。   (内部的值"过高"-导致"圆角边"并引发信号反射。)

    通常、"单步执行您的代码"-同时观察每个结果-将识别您的代码或连接"正在中断"的"位置"。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    这非常奇怪、因为它在无效时钟设置下完全正常工作。 我用"无效"时钟运行程序已经有一段时间了。 它在"无效"时钟设置下工作正常。 我从传感器中获取了大量正确的数据、所有数据都正常工作、直到我将时钟切换为以80MHz 运行。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    确实-我确实... "感受您的痛苦。"   了解-由于"过高"系统时钟设置导致的"过度耗散"、我无法让您(继续)非法操作 MCU -这可能会造成损害!

    您对以下内容"沉默":(wrt)

    • 存在外部上拉 Rs
    • 范围的存在
    • 建议 的"单步执行"结果  

    诊断是我公司的一个重点-我建议您"拨号"您的系统时钟-经验告诉我们、这通常证明是有用的。

    • 更改为 "Sys_Div_4"将产生50MHz SYSCLK  
    • 更改为 "Sys_Div_5"将产生40MHz SYSCLK。   

    我相信(其中一个或两个)这些(较低频率)都有更好的成功机会。  (80MHz 以上... 它将需要一个范围来"确定原因?")

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    有趣的是、您应该提到以50 MHz 和40 MHz 的频率尝试它、因为这正是我在阅读您的回复之前所做的。 是的、它在40MHz 和50MHz 下工作、但在66MHz 或80下工作。 我将不得不等到星期一才能确定范围。 传感器位于分线板上、该分线板上确实有上拉 R。 单步执行并查看我可以找到的内容。

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

    也许不是很有趣-有些人可能会说、"受启发"。   您是否可以通过赢得的 "修复"、"这解决了我的问题" 点选框来奖励该"修复"?

    当您获得 "示波器访问"时 、您可以 "简化位速率的测量"-将数据设置为 "0x55 或 0xAA"-其中任何一个都会发出交替的"位模式"-非常易于验证和测量...

    未声明为:

    • 您如何为 I2C 从设备供电 (您是否测量了该电压-而 I2C 事务是 "在线?")
    • 您的 MCU 与(假设)从板之间的"间隔距离和电缆或导线长度"。   I2C 是一种短长度接口-越短越好。

    当您"非法"选择"Sys_Div_1"作为参数-系统时钟"溢出"-并且我们"快速计算"您的(实际)频率为 "这两者之一"时。   (因此、您收到了两个频率-仅以一个频率的价格!)   这应该是"这个解决方案"点击的结果...

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

    谢谢-非常感谢。

    如果/当您可以访问示波器-并观察 I2C 位速率(通过选择0x55/0xAA 来激发"SDA"进行简化)-以及2-3字节 的"I2C 事务"-我们可以"深入探讨"。

    " 记住"- 当系统时钟超过(40或50MHz、 MCU 手册应该详细说明)时、"123是它强制执行"等待状态"、这很好、并且(这)可能会中断 I2C 时钟。   按指示拨号系统时钟,从“ 可疑列表”中删除了该“问题”。    (仍有(其他)不可口的人物-可能会被拉着-只是"看不见"。)