您好!
我需要完整的代码审查/故障排除帮助、但无法将整个代码发布到此 公共空间。 如果有人愿意向我发送私人消息、以便进行深入的代码审查、我可以真正地使用帮助。
我不知道是什么导致我的代码间歇性地从程序空间中跳出、从而导致我的程序冻结并完全无法使用(除非我重新启动它)。
我有很多不同的功能(CapTIvate、I2C、SPI、计时器、中断、 按钮等)。
谢谢!
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.
您好!
我需要完整的代码审查/故障排除帮助、但无法将整个代码发布到此 公共空间。 如果有人愿意向我发送私人消息、以便进行深入的代码审查、我可以真正地使用帮助。
我不知道是什么导致我的代码间歇性地从程序空间中跳出、从而导致我的程序冻结并完全无法使用(除非我重新启动它)。
我有很多不同的功能(CapTIvate、I2C、SPI、计时器、中断、 按钮等)。
谢谢!
尊敬的 Dennis:
是的、正确。 我从方形一开始、先获取示例以单独工作、然后逐一将它们相加。 我认为此时它必须与 captate 有关、因为多次(当然不是每次)碰撞发生时、它提到函数"CAPT_saveCyclResultsAutoMultiFreq" 、但 我已经尝试了我可以尝试的一切。 但有时、它只是告诉我、程序在某个地址中断。
我还担心外设中断只是冲突、但很难判断。
我接着以私人邮件的形式发送了所有信息。
谢谢、
最大
尊敬的 Max:
CapTIvate 中断优先级是 MSP430上的最低优先级、因此不会与其他外设发生冲突、但是、如果 CapTIvate 使用大值 convation_count 进行校准、则可能会在一段时间内阻止代码执行。 我从您上传的文件中看到、转换计数使用了250、因此您在那里很好。 我确实注意到您启用了抗噪功能。 我会避免、除非您预计您的产品将会受到流经和交流线路的电气干扰。 现在、请尝试在未启用的情况下运行、并查看它是否有用。 这将提供线索。
该消息表示代码在其中一个库函数中处于停滞状态(黑框、因此没有可提供附加信息的源代码或符号)。
现在、我有了您的项目、我将对其进行介绍。
BTW、我喜欢您的软件架构文档中的软件状态图。 您使用什么工具来生成这些内容?
尊敬的 Dennis:
我已经尝试过、也没有尝试过。 但是、如果没有抗噪功能、它仍然会冻结错误、所有错误都只显示"break at address "xxxxx"、没有可用的调试信息、或者程序代码之外的错误"。
此外、谢谢! 该文档中的状态图都是使用 www.lucid.app 制作 的, 它非常简单、有效,具有许多功能,强烈推荐。
在没有启用抗噪功能的情况下进行调试:
Max、您好、感谢您提供了 lucid 提示。 我将对此进行检查。
我需要更详细地描述故障行为。 例如、当您打开系统电源并且不触摸任何内容时、系统正常、或者在某个时间(秒、分钟等)后、系统是否冻结? 或者、在您触摸其中一个电容式触摸按钮之前、它是否正常工作?
当它冻结时、如果查看调试器窗口、您应该会看到一个调用栈。 下面是一个示例。
您是否可以在您的快照挂起时拍摄它的快照?
Dennis、
当我使用电容式触控按钮时、它看起来实际上只是冻结了。
但是、即使我不使用任何电容按钮、 然后我暂停该程序、它仍然会在某个地址出现中断...但是 、当我 再次恢复该程序时、该程序不会冻结(LED 驱动器和电容式按钮都暂时工作、直到再次冻结-直到我将其复位)。
以下是使用电容式触控时冻结时的一些屏幕截图:
当我在不触摸任何电容按钮的情况下暂停程序时、会发生以下情况:
我将代码连接到 BSWP 面板、然后在 CAPT-FR2676上运行。 我对您的配置代码进行了一些更改、以便将输出发送到 GUI。 当然、我没有 SPI、I2C…… 正在运行、但我至少可以确认 CapTIvate 在触摸任何按钮时似乎正常工作并按预期作出响应。
[引用 userid="442330" URL"~/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1052252/msp430fr2676-code-project-review---code-going-off-into-the-weeds/3894648 #3894648"]当我使用电容式触控按钮时、它似乎仅会实际冻结。当检测到按钮时、您可以使用 SPI 和 IC2将数据发送到 LED 驱动器。 您是否已使用示波器/逻辑分析仪确认这些功能正常? 或者更好的问题是、如果您在按下按钮时监控 SPI 和 I2C 总线、它们是否正确且完全执行?
尊敬的 Max:
此时、我认为这是一个 I2C 总线问题。 您刚才说过、您可以让各个示例正常工作。
[引用 userid="442330" URL"~/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1052252/msp430fr2676-code-project-review---code-going-off-into-the-weeds/3892970 #3892970"]我从方形一级开始,先获取示例以单独工作,然后逐一将它们相加。 [/报价]让我们来解决这个问题、如果您返回后只执行 I2C (无 CapTIvate)、那么在将探针连接到 I2C 时是否仍然会看到该行为、这会使其正常工作、并且移除探针会导致 I2C 停止? 或者 I2C 本身是否正常工作? 例如、将各种值写入 LED 驱动器、查看其是否响应并更改 LED 等
Dennis、
好的、刚刚尝试过、现在仍然在项目中注释 captate 的情况下发生。
不过、这次我发现仲裁丢失标志(UCALIFG)被置位、导致总线保持繁忙状态。 从我所看到的情况来看,没有办法处理这种情况,但我不敢肯定
由于本项目中的视觉照明存在一些问题、我们将移除2个 LED 驱动器中的1个、并显著减少 LED 的数量。 我希望这将有助于解决这个问题、因为这两个驱动器中至少有一个似乎将 SDA 线路拉至低电平。 从我所读的内容来看、这似乎是什么会导致仲裁失败、除非您有其他想法?
尊敬的 Dennis:
很抱歉、这方面的延迟、 奇怪的是、我们的新电路板修订版今天刚刚推出(现在只有一个 LED 驱动器、LED 数量减少)。 我还没有太多的时间来彻底测试所有东西、但我确实让它冻结了我一次、但是我无法 复制。
我明天将进行一些全面的测试、并调试并连接我的逻辑分析仪。 我将在明天报告我的调查结果。
若要回答您之前的问题:
1) 1) MSP 是总线上的唯一主器件。
2) 2) LED 驱动器是当前 I2C 总线上的唯一器件。 (如果我移除了 LED 驱动器、则没有任何东西连接到总线)
Dennis、
在这里、似乎出现了相同的问题。
仲裁正在丢失并且停止标志正在被置位。 在这方面、我似乎找不到一个直接的答案。
----------------------------------------------------------------------
另一个发现:
当我使用逻辑分析仪进行调试时、我唯一可以将其连接到电路板的方法是通过柔性 电缆+ FPC 分接 组合。
事实证明、在我的逻辑分析仪断开连接且 FPC 分线板仍保持连接的情况下、I2C 正常工作。 只要 FPC 适配器连接到 I2C 线路、I2C 通信就可以正常工作。
如果我断开分线板的连接并仅连接柔性电缆、I2C 将再次停止工作。
----------------------------------------------------------------------
结论:
似乎向 SDA 和 SCL 布线添加更多表面积会对此处出现的任何问题产生积极影响...
Dennis、
这个图变得更浓...
我能够通过一些焊接将逻辑分析仪直接连接到电路板(绕过 FPC 分线)、这使我能够在仍然连接时看到误差。 显然(如果这实际上是问题的根源)、我只是得到一个否定、它导致它冻结。
如果我在得到一个 NACK 后发送一个重复起始、那么 MSP430确实会尝试重新启动通信、但是它只是接收到另一个 NACK 并无限期地停止。
如果我在收到 NACK 时发送停止条件、所有通信都将立即停止、并且不再尝试再次启动。
不确定另一种处理 NACK 的方法是什么。 如果您有任何想法、请告诉我。
尊敬的 Dennis:
这是我正在使用的 I2C 主设备的代码。 我在 NACK 标志中添加了一些额外的代码、似乎允许它在冻结之前运行更长时间、但现在还没有超出此范围。
此外、我 批准了您的 Altium 访问请求、现在应该可以查看 设计。
uint8_t i2c_tx_buffer[20]= {0}; // Pointer to TX data uint8_t i2c_rx_buffer[20]= {0}; // Pointer to RX data #pragma vector = USCI_B1_VECTOR __interrupt void USCIB1_ISR(void) { switch(__even_in_range(UCB1IV,USCI_I2C_UCBIT9IFG)) { case USCI_I2C_UCNACKIFG: UCB1CTL1 |= UCTXSTP; i2c_tx_byte_counter = 2; i2c_transmit_byte = 0; i2c_tx_buffer[0] = 0x25; i2c_tx_buffer[1] = 0x00; //UCB1I2CSA = 0x3C; UCB1IFG &= ~UCNACKIE; UCB1IE |= UCTXIE | UCNACKIE; UCB1CTL1 |= UCTXSTT; break; // Vector 4: NACKIFG break; case USCI_I2C_UCTXIFG0: // Vector 26: TXIFG0 break; if (i2c_tx_byte_counter > 0) // Check TX byte counter { UCB1TXBUF = i2c_tx_buffer[i2c_transmit_byte++]; // Load TX buffer i2c_tx_byte_counter--; // Decrement TX byte counter } else if(i2c_tx_byte_counter == 0) { i2c_transmit_byte=0; UCB1CTLW0 |= UCTXSTP; // I2C stop condition UCB1IFG &= ~UCTXIFG; // Clear USCI_B1 TX int flag } break; } } void i2c_init() { EUSCI_B_I2C_initMasterParam param = {0}; param.selectClockSource = EUSCI_B_I2C_CLOCKSOURCE_SMCLK; param.i2cClk = CS_getSMCLK(); param.dataRate = EUSCI_B_I2C_SET_DATA_RATE_100KBPS; param.byteCounterThreshold = 0; param.autoSTOPGeneration = EUSCI_B_I2C_NO_AUTO_STOP; EUSCI_B_I2C_initMaster(EUSCI_B1_BASE, ¶m); //Set Master in transmit mode EUSCI_B_I2C_setMode(EUSCI_B1_BASE, EUSCI_B_I2C_TRANSMIT_MODE); //Enable I2C Module to start operations EUSCI_B_I2C_enable(EUSCI_B1_BASE); EUSCI_B_I2C_clearInterrupt(EUSCI_B1_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT); //Enable master transmit interrupt EUSCI_B_I2C_enableInterrupt(EUSCI_B1_BASE, EUSCI_B_I2C_TRANSMIT_INTERRUPT0 + EUSCI_B_I2C_NAK_INTERRUPT); } void i2c_master_write(uint8_t slave_address, uint8_t register_address, uint8_t data) { i2c_tx_buffer[0] = register_address; //add register address to TX buffer i2c_tx_buffer[1] = data; i2c_transmit_byte=0; i2c_tx_byte_counter = 2; // Load TX byte counter UCB1I2CSA = slave_address; // configure slave address UCB1IFG &= ~(UCTXIFG + UCRXIFG); // Clear any pending interrupts UCB1IE &= ~UCRXIE; // Disable RX interrupt UCB1IE |= UCTXIE | UCNACKIE; // Enable TX interrupt //while (UCB1CTLW0 & UCTXSTP); // Ensure stop condition got sent UCB1CTLW0 |= UCTR + UCTXSTT; // I2C TX, start condition __bis_SR_register(GIE); // Enter LPM0 w/ interrupts, and remain in LPM0 until all data is TX'd }