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.

[参考译文] CCS/SW-EK-TM4C1294XL:单步执行和单步执行之间的差动结果(I2C)

Guru**** 2443910 points


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

https://e2e.ti.com/support/microcontrollers/arm-based-microcontrollers-group/arm-based-microcontrollers/f/arm-based-microcontrollers-forum/630189/ccs-sw-ek-tm4c1294xl-differents-results-between-step-over-and-step-into-i2c

器件型号:SW-EK-TM4C1294XL

工具/软件:Code Composer Studio

我正在为测试信号发生器编写一些测试代码。 我将使用 MCP4725芯片生成模拟电压(稍后将使用 MCP4728)。 我将我想要的12位值写入芯片寄存器、并在以后读取时预期读取相同的值、但情况是这样的。

当我步入 MCP4725SendReceive 函数时、它会起作用、但当我单步执行时、它不会起作用。

有什么想法吗? 我尝试了很多延迟。


#include #include #include "driverlib/fpu.h" #include "driverlib/gpio.h" #include "driverlib/i2c.h" #include "driverlib/pin_map.h" #include "driverlib/rom.h" #include "driverlib/sysctl.h" #include "driverlib/uart.h" #include "hw_intrinc/包含"#hw_hw_gpio.h"#include "#include "#include "#include "#"#include "inc/intrintrinc/包含"#"hw.hw_inc"#.hw_inc" // //系统配置。 //// ***************** uint32_t G_ui32SysClock; //保持主时钟速度 //********* //// 初始 UART 接口115200bps、8、N、1/// ********* void InitUART (void) { SysCtlPeripheralEnable (SYSCTL_Periph_GPIOA); while (!SysCtlPeripheralReady (SYSCTL_Periph_GPIOA)) { } GPIOPinConfigure (GPIO_PA0_U0RX); GPIOPinConfigure (GPIO_PA1_U0TX); SysCtlPeripheralEnable (SYSCTL_Periph_UART0); while (!SysCtlPeripheralReady (SYSCTL_Periph_UART0)) { } UARTClockSourceSet (UART0_BASE、UART_CLOCK_PIOSC); GPIOPinTypeUART (GPIO_Porta_base、GPIO_PIN_0 | GPIO_PIN_1); UARTStdioConfig (0、115200、16000000); } //********* // //初始化 DAC 芯片 // //********* void MCP4725Init (void) { UARTprintf ("正在启动。\n"); SysCtlPeripheralEnable (SYSCTL_Periph_GPIOD); while (!SysCtlPeripheralReady (SYSCTL_Periph_GPIOD)); GPIOPinConfigure (GPIO_PD0_I2C7SCL); GPIOPinConfigure (GPIO_PD1_I2C7SDA); GPIOPinTypeI2CSCL (GPIO_PORTD_BASE、GPIO_PIN_0); GPIOPinTypeI2C (GPIO_PORTD_base、GPIO_PIN_1); SysCtlPeripheralDisable (SYSCTL_Periph_I2C7); SysCtlPeripheralReset (SYSCTL_Periph_I2C7); SysCtlPeripheralEnable (SYSCTL_Periph_I2C7); while (!SysCtlPeripheralReady (SYSCTL_Periph_I2C7)) { } I2CMasterGlitchFilterConfigSet (I2C7 _BASE、I2C_MASTER_毛 刺脉冲_FILTER_8); I2CMasterInitExpClk (I2C2_base、g_ui32SysClock、false); } //********* // //更新 DAC 输出,然后读回输出寄存器 // ********* uint16_t MCP4725SendReceive (uint16_t loadvalue) { uint8_t pui8WriteData[2]; uint8_t pui8ReadData[5]; uint16_t readvalue; // //将所需的值写入 DAC 寄存器 //请参阅 mcp4725数据表第6.1.1节 // pui8WriteData[0]=(uint8_t)((loadvalue >> 8)& 0xF); pui8WriteData[1]=(uint8_t)(loadvalue); I2CMasterSlaveAddrSet (I2C7 _BASE、0x62、false); I2CMasterDataPut (I2C2_base、pui8WriteData[0]);//第一个字节 I2CMasterControl (I2C4_base、I2C_MASTER_CMD_BURST_SEND_START);//开始发送 while (I2CMasterBusy (I2C7 _BASE));//等待完成 if (I2CMasterErr (I2C4_base)!= I2C_MASTER_ERR_NONE)//检查是否有错误 { UARTprintf ("I2C 错误\n"); } I2CMasterDataPut (I2C2_base、pui8WriteData[1]);//第二个字节 I2CMasterControl (I2C4_base、I2C_MASTER_CMD_BURST_SEND_FINISH);//开始发送 while (I2CMasterBusy (I2C7 _BASE));//等待完成 if (I2CMasterErr (I2C4_base)!= I2C_MASTER_ERR_NONE)//检查是否有错误 { UARTprintf ("I2C 错误\n"); } //rom_SysCtlDelay (100000000);//尝试在这里放置一个大延迟、它不会更改结果 // //从芯片读取寄存器。 //请参阅 mcp4725数据表第6.2节 // I2CMasterSlaveAddrSet (I2C7 _BASE、0x62、TRUE); //图6.3的字节2 (实际上、第一个要读取的字节) I2CMasterControl (I2C4_base、I2C_MASTER_CMD_BURST_Receive_start); while (I2CMasterBusy (I2C7 _BASE)); pui8ReadData[0]= I2CMasterDataGet (I2C7 _BASE); if (I2CMasterErr (I2C4_base)!= I2C_MASTER_ERR_NONE) UARTprintf ("I2C 错误\n"); //图6.3的字节3 I2CMasterControl (I2C4_base、I2C_MASTER_CMD_BURST_Receive_contt); while (I2CMasterBusy (I2C7 _BASE)); pui8ReadData[1]= I2CMasterDataGet (I2C7 _BASE); if (I2CMasterErr (I2C4_base)!= I2C_MASTER_ERR_NONE) UARTprintf ("I2C 错误\n"); //图6.3的字节4 I2CMasterControl (I2C4_base、I2C_MASTER_CMD_BURST_Receive_contt); while (I2CMasterBusy (I2C7 _BASE)); pui8ReadData[2]= I2CMasterDataGet (I2C7 _BASE); if (I2CMasterErr (I2C4_base)!= I2C_MASTER_ERR_NONE) UARTprintf ("I2C 错误\n"); //图6.3的字节5 I2CMasterControl (I2C4_base、I2C_MASTER_CMD_BURST_Receive_contt); while (I2CMasterBusy (I2C7 _BASE)); pui8ReadData[3]= I2CMasterDataGet (I2C7 _BASE); if (I2CMasterErr (I2C4_base)!= I2C_MASTER_ERR_NONE) UARTprintf ("I2C 错误\n"); //图6.3的字节6 I2CMasterControl (I2C4_base、I2C_MASTER_CMD_BURST_Receive_finish); while (I2CMasterBusy (I2C7 _BASE)); pui8ReadData[4]= I2CMasterDataGet (I2C7 _BASE); if (I2CMasterErr (I2C4_base)!= I2C_MASTER_ERR_NONE) UARTprintf ("I2C 错误\n"); readvalue = pui8ReadData[1]<< 4 | pui8ReadData[2]>> 4;//寄存器 D11..d0 return (readvalue); } //********* //// 主要 // //********* int main (void) { uint16_t writeMilli伏特= 0; uint16_t readMilli伏特= 0; FPUEnable(); FPULazyStackingEnable(); G_ui32SysClock = SysCtlClockFreqSet ((SYSCTL_XTAL_25MHz | SYSCTL_OSC_MAIN | SYSCTL_USE_PLL | SYSCTL_CFG_VCO_480)、120000000); InitUART(); UARTprintf ("\033[2J\033[H"); UARTprintf ("CAN 传感器仿真器(CSS)正在启动。\n"); MCP4725Init(); while (1) { UARTprintf ("用%d mV\t 写入 DAC "、writeMilli伏特); readMilli伏特=MCP4725SendReceive( writeMilli伏特); UARTprintf ("从 dac 读取%d mV 值"、readMilli伏特 值); 如果(writeMilli伏特> 4095) { writeMilli伏特= 0; } 其他 { writeMilli伏特+= 128; } ROM_SysCtlDelay (8000000); } 返回1; }

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

    很难仅根据描述来表达。 我建议使用示波器(或逻辑状态分析器)来比较信号并查看可能发生的情况。 如果没有示波器捕获、则很难判断可能会发生什么情况。

    您可能需要查阅器件数据表、以查看是否有任何设置时间或是否节省了处理寄存器值并准备好读出的时间。 此外、您还提到您曾尝试过很多地方的延迟、但这并没有说太多... 您尝试的最长延迟值是多少? 您在哪些领域使用了延迟?为什么?

    同样、示波器在这里非常方便、可以查看需要在何处使用步进代码以执行某些操作。

    此外、还必须强制确认您是否在 SCL/SDA 上使用上拉电阻器及其值。 如果您有有效的响应、我想假设您具有这些响应、并且正在使用良好的值、但仍需要验证。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Ralph、

    按照海报中的直接引用:"当我步入 MCP4725SendReceive 函数时、它起作用、但当我单步执行时不起作用。"

    请注意、当代码为"单步进入"时、即表示"成功"-但当"单步执行!"时则表示"成功"   这是预期的-是不是吗?   (当"步越"时-关键代码块是否不可能执行-导致海报的问题?)

    海报可能具有"正常代码运行"、而不是"单步执行"。  "  (我认为这是你的结论。)

    不难接受"步越"代码(取决于被绕过的代码)-将减少和/或阻止程序的完全/正确运行...   在我(近) 10年的时间里@这个论坛-我不能忘记一个(类似的)投诉、它的原因是"超越!"   (同样、这似乎是一个语言问题-海报(很可能)意味着他 的"程序在运行时失败!")

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

    进一步思考"海报的(可能)代码在运行时出现故障"-遵循标准测试方法:

    • 识别然后在每个"主要"代码块之后插入"断点"
    • 以正常速度运行代码-然后记下 KEY (外设)寄存器的内容
    • 如果这些内容"符合预期"会记录这一事实
    • 删除该特定的断点
    • 再次运行代码(这个时间代码停止@中断点#2 (在代码中进一步)
    • 再次观察寄存器内容是否正确

    在许多情况下(我们已经观察到)、某些代码块将正确执行-其他代码块可能会失败。   

    这种"识别"允许对那些(可能)需要增加延迟的代码块(或者更好的是)等待特定"函数调用"正确完成的代码块进行"引脚指向"(或聚焦)。

    另请注意、由于用户的 MCU 和外部/连接的器件、"测试/验证"过程变得更加复杂-必须在完全符合规范的情况下进行管理。  (因此、将每个代码运行分析分解为小的逻辑部分的重要性!)

    以上是""(在此神秘(错误地)被禁止)的明确证明、证明了设计和开发期间巨大的持续价值(尤其是在此处)...

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

    感谢大家、

    我将首先尝试示波器、然后尝试断点。 我想我将在示波器上看到一些东西、因为输出电压遵循我读取的值、而不是我写入的值。 它应该是写入阶段中的某个东西。

    我的原型上有4k7上拉电阻、10厘米(4英寸)的电缆。 是的、当我"运行"软件时、它会失败。

    这是我的测试代码和电路、用于更复杂的东西、还有几个其他外设。 在将所有这些组合在一起之前、我将逐一进行测试、I2C、SSI、PWM、计时器、 CAN、GPIO。  

    我稍后将使用示波器、我想我会看到一些奇怪的东西。

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

    我认为原因可能是,当 Fabrizio 单步进入函数时,它会在 I2CMasterControl()被调用后为 I2C 提供足够的时间,然后到达下一条语句 while (I2CMasterBusy (I2C2_base)))。 当他单步执行函数时,代码将在 while (I2CMasterBusy (I2C7 _BASE))中失败,因为 I2C 尚未忙。

    根据您和 Amit 过去的建议、替换:

    while (I2CMasterBusy (I2C7 _BASE));

    其中:

    while (!(I2CMasterBusy (I2C7 _BASE)));

    while (I2CMasterBusy (I2C7 _BASE));

    我想 Fabrizio 可以尝试一下、看看它是否会起作用。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    查尔斯

    先生,很棒的酒店!   (我完全错过了- dumkopf!)

    Amit 获得了全部学分(CB1 ZERO)-这就是他的全部"方向错误"。   (严格/我避免129 (太慢了!)

    这就是说、运行代码的能力以及"选择性中断"(在战略点)纯粹的亲吻证明非常有用。   (虽然在这里被禁止-特别是在这里被禁止!)

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

    感谢您的建议、我也忘记了 I2C 的特定步骤。 希望它很快就会永久嵌入到我的脑海中、以便一直寻找它。

    您好 CB1、

    为清楚起见、我确实是根据单步执行与运行代码同义的想法提出我的建议。 因此、重点关注使用了哪些延迟以及获得一个 o 范围、从而查看时间安排以及延迟有助于而非帮助的位置。

    此外、我不确定、但听起来您是否建议步越函数完全跳过函数内部的代码执行? 我不认为是这样、而是不让您进入函数内的函数进行逐行调试、而是以正常速度运行函数、然后转到下一个函数。 比如伪断点。 我需要核实、但这是我多年来对"逾越"的理解、所以如果这是错误的话、我会很受骗。

    如果您无法访问快速 o 范围、断点方法当然也适用于调试、 但是、在我到目前为止使用 SPI (尤其是 SO)和 I2C 的经验中、我发现在问题识别时、数据/时钟线的查看速度要快得多、同样或更有用、因此我更喜欢在可能的情况下进行调试。 我花了比所需时间多得多的时间尝试盲目猜测可能会出现什么 SPI/I2C 问题、因为每次提供标记良好的示波器或 Saleae 逻辑状态分析仪捕获时、答案都变得非常明显、无需猜测。 )
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您好、Ralph、

    作为长期的"IAR"用户、我必须检查我是否通过"Step Over (单步执行)"来"否定"代码处理。 (我们始终且仅使用 IAR -正如客户(正确)要求我们使用多个供应商 MCU -单个供应商永远无法(始终)证明最佳/最明亮!)

    至于断点范围-海报确实报告了(部分) I2C 成功! 这-在我的书中(大部分时间)表示"信号基础知识"(可能)是正确的。 并将"责任"转移到更复杂的代码问题。

    大家一致认为,(两种)方法----结合使用----是最好的。 最坏的情况可能是"在实验室工作"(只是勉强工作)、然后在"现场"的情况下在短时间内失败。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    非常感谢 Charles、Ralf、CB1、Amit

    主要问题不是这种情况、但解决后、您的提示避免了其他问题(一个字节的消息、实例为2)。

    我在示波器上看到的错误是:

    1 -我 我再发送1个我应该发送的字节、并且处于错误的位置。 我不知道当我走过去时它如何工作、我想我稍后会看一下。

    2 -即使我每次发送一个常量数据、出现在示波器上的数据在地址之后的第一个字节中始终以计数方式发生变化。 发生这种情况(我认为)是因为 I2C 芯片在停止后接受更多数据以继续更新 DAC 输出、至少这是我在再次读取数据表时可以理解的内容。

    现在、我需要看一下示波器图、为了准确地了解与接收到的消息的关系、我在 Tiva 上看到的不是 PC 示波器软件读取的内容。

    下一步是尝试使用 sensorlib 中提供的 i2cm_drv.c 为该芯片编写一个"驱动程序"。

    不工作

    工作

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

    [引用 user="Ralph Jacobi"]我不确定、但听起来您是否建议步越函数完全跳过函数内的代码执行

    添加"完全"是 Ralph 的发明(不是我的发明)、正如该引语所揭示的:" 关键代码块是否不会执行" -导致海报的问题?   "完全"是对事实的错误陈述!

    虽然这篇文章(通过 IAR 的"帮助")并不像我想的那么明确-但它确实提供了(部分)封面。  (即"未输入!")   Devil 在 IAR 对"下一个语句、函数调用或指令"的解释和/或处理中"撒谎"!   如果我们的海报采用了(任何)"标准 C"(很可能通过 API)、那么某些代码可能不会被执行!   至少-有(部分)风险因素!

    "现实/Pro、供应商无关、实质性 IDE"(即 IAR)的功能如下所示:   ( 远小于 IDE 的依赖"功能处理" 是(不大可能)创建/证明"一般裁决..."的依据)

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

    非常有趣! 与编译器的细微差异。 不过、我知道我今天早些时候曾与之讨论过的 CCS 专家确实确认了我对 CCS 的"步越"代码执行的准确性。 很高兴知道 IAR 的工作方式并不完全相同、这可能对未来的帖子很有价值、因此感谢大家的分享!!
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    您好、Ralph、

    我经常坐在"纽约公立学校教室的后面",这是有充分理由的。  (惩罚)  因此-当被挑战时-"马口"(IAR 帮助)拯救。

    的确有差异-有些微妙-有些则不是这样!   (IAR (永远)支持 SWD -不要相信 CCS 已经(现在)达到了这个(GPIO 释放)目标!   当然、不能低估在多个 ARM 供应商之间快速、高效、自由地移动的能力!)

    我记得我们"超越"那些"太长时间"执行的功能(已知是好的)所带来的"节省时间"!   代码"完全执行"-我们(仍然)正在测试...

    然而-这里的问题从未"步越"-海报旨在"运行"-您/我都检测到了... (并摆脱了这种"检测"—Charles 提供了"解决方案"... 尽管(赦免)位在一些情况下发生了变化、但"重复/反转忙线检查"已被证明失败)

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

    哦、是的、肯定同意运行的意图。 刚才我们想、除了 OP 对其解决方案的总结之外、我们还应该为未来的读者关闭环路! )