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.

[参考译文] MSP430F5529和 AD5933之间的 I2C 通信出现问题

Guru**** 2553450 points
Other Parts Discussed in Thread: MSP430G2553, MSP-FET

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/593848/problem-with-i2c-communication-between-msp430f5529-and-ad5933

器件型号:MSP430F5529
主题中讨论的其他器件:MSP430G2553MSP-FET
#define SLAVE_ADDRESS 0x0D /**< AD5933的地址。 */
#define BAUD_RATE 12 /**<波特率值。 */
#define SDA_PIN 0x00 // msp430F5529 UCB0SDA 引脚
#define SCL_PIN 0x01 // msp430F5529 UCB.S.引脚

P1DIR |= BIT1;
P1OUT |= BIT1;
P1OUT ^=(BIT1);//打开 LED (在发送所有初始化数据时关闭)

P3REN |= SDA_PIN + SCL_PIN;
P3SDA_PIN |= SDA_PIN + SCL_PIN;
P3SEL_PIN;+ SCL_PIN //将 I2C 引脚分配给 USCI_B0

UCB0CTL1 |= UCSWRST; //启用 SW 复位
UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C 主设备,同步模式
UCB0CTL1 = UCSSEL_2 + UCSWRST; //使用 SMCLK、保持软件复位
UCB0BR0 =波特率; //设置预分频
器 UCB0BR1 = 0;
UCB0I2CSA = SLAVE_ADDRESS; //设置从地址
UCB0CTL1 &=~UCSWRST; //清除 SW 复位,恢复操作
// UCB0IE = UCNACKIE;//使用和不使用此行进行尝试,
UCB0IE |= UCTXIE 没有区别; //启用 TX 就绪中断

P1OUT ^=(BIT1);//

在(UCB0STAT 和 UCBBUSY)时关闭 LED
;

这是我的代码。 我知道我的板可以工作、因为 LED 闪烁正常、但我始终会在最后一个 while 循环中卡住。

此代码也是根据 MSP430G2553与 AD5933的通信进行调整的、在该通信中它运行良好。 我根据数据表更改了所有必要的端口和引脚。

这与另一个系统的另一个区别是、现在我使用 MSP-FET 闪存仿真工具和一个微 UBS 供电 、而不是使用迷你 USB 端口。 但我不知道这可能会或不会影响我的代码。

看来 MSP 的 STAT 从未改变、通信也未建立。 有人能帮我解决这个问题吗? 我不知道初始化有什么问题。 问题可能在于中断? 我应该怎么做?

提前感谢大家为我提供帮助。

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

    Gabriela、您好!

    有关调试 I2C 问题、请参阅以下应用手册。 MSP430 MCU 上常见 eUSCI 和 USCI 串行通信问题的解决方案

    我还建议从我们的 I2C 代码示例之一开始。 根据您的代码、有几件事是很好的。 首先、您启用 TX 中断、但没有 ISR。 这意味着您将跳转到陷阱 ISR、而不执行任何操作。 这也意味着您不会填充 TXBUFF、因此 I2C 线路上不会发送任何内容。 此外、如果您曾突破 while 语句、您的程序将结束、而不执行任何其他操作。 这意味着您将发送一个字节、然后不执行任何操作。 您需要一个应用程序循环[while (1)]以确保器件保持运行。

    有关其他 I2C 调试工作、请参阅上述链接的应用报告。

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

    非常感谢! 我检查了 AP、我已经尝试过这些解决方案、但它们不起作用。 代码有时会跳转到陷阱 ISR、但只是当我删除它并继续运行代码时。 我不明白为什么 MSP430G2553不会发生这种情况? 我不知道 ISR、尽管我付出了很多努力、但我无法更正。

    我找到了 I2C 代码示例、但也无法运行、它会卡在以下位置:

    _bis_SR_register (LPM0_bits + GIE); //输入 LPM0,启用中断 

    我尝试根据我的代码修改这些示例、但我没有成功、因此我尝试自行运行这些示例、但它们不起作用。

    http://software-dl.ti.com/msp430/msp430_public_sw/mcu/msp430/MSP-EXP430F5529LP/latest/index_FDS.html

    我从这里挑选示例、Windows 版本和 I2C、然后选择说"这是主代码"的示例。用于读取或写入一个或多个字节。


    我的代码实际上会继续、我发送起始位并读取数据等 我只是在代码停止的循环之前通过代码。 如果我在这里求解、其余部分应该可以正常工作、因为它适用于 MSP43G2553系统。

    我希望你们能帮我解决这个问题、这是我的硕士项目、我在所有这些后退都落后于最后期限。

    非常感谢您的参与!

    此致、

    加布里埃拉

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

    您好! 有人可以帮我解决这个问题吗?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您未正确初始化端口。 内置的上拉电阻在100kHz 下太弱、SDA_PIN/SCL_PIN 值错误(它们必须使用 BITx)。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    为什么端口不正确?  什么缺失或错误? 您能更具体吗?
    关于 SDA_PIN/SCL_PIN、它们是针对 P3.0和3.1的家乐福(BIT0/BIT1 = 0x00 / 0x01)。

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

    MSP430‍f5529.h 使用替代事实:

    #define BIT0 (0x0001)
    #define BIT1 (0x0002)
    #define BIT2 (0x0004)
    ... 
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    此外、您如何知道上拉电阻器在 kHz 频率下太弱?
    我的上拉电阻器各为4.7kOhm。
    也许我的波特率是错误的、您能告诉我应该如何计算它吗?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    kΩ 上拉电阻器远大于4.7k Ω。 如果您有外部引脚、则无需在 PxREN 中启用内部引脚。

    通过将时钟源的频率除以分频值、可以计算出 μ I²C 时钟频率。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    哦、对了! 谢谢你:)我更改了它,但它没有解决我的问题。
    我将直接进入 ISR 陷阱、或者(UCB0STAT 和 UCBBUSY)始终为0。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    正如 Jace 已经告诉您的、您会因为您启用了中断而获得中断。

    从一个超级简单的程序开始、该程序只执行一个字节的 μ I²C 事务。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    啊、好的、我移除了这条线。 尽管问题仍然存在:/
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    有什么问题? ISR 陷阱中的所有其他操作?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    是的、我理解。 他说:"首先、您启用 TX 中断、但没有 ISR。"

    您能向我解释一下我应该如何执行 ISR 吗? 我不熟悉它、我已经搜索过、但我不明白应该怎么做。

    问题是、无论什么、UCB0STAT 和 UCBBUSY 始终为0。 这意味着未建立通信。 有时我会遇到 ISR 陷阱、但最常见的情况是这种陷阱。

    非常感谢您努力帮助我!

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    您实际上需要 ISR 吗? 您如何使用 G2553实现这一点? (所有 I²C 示例程序都有 ISR。)

    在 START 和 STOP 条件之间设置 UCBBUSY。 您显示的代码从未发送起始条件、因此 μ I²C 模块当然不会忙。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    在 G2553系统中、我以同样的方式实现了它、并且它工作得很好。 我没有使用任何 ISR。
    之后发送 START 条件、以发送数据并接收数据。 就像在 G2553系统中一样。 我在 G2553和 F5529之间进行了调整。
    我发现它们之间唯一最不同的是中断:
    根据 I2C 模式下的每个用户指南:对于处于 I2C 模式的 USCI 模块、G2553有两个中断向量、一个与发送和接收中断标志相关联、另一个与四个状态更改中断标志相关联。 F5529只有一个中断向量共享、用于传输、接收和状态变化。
    我的问题是、因为我没有对它进行任何更改。 您能告诉我问题是否可能是因为这个原因? 如果是、我如何尝试解决这个问题?
    非常感谢您对我的问题的耐心和理解。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    "同样的方式"是否包括启用中断?
    不管怎样、如果您不使用中断、它们的向量可能是什么都无关紧要。

    嗯、如果你显示的代码正常工作、并且如果你在后面执行的一些其他代码出现问题、那么显示该其他代码可能会有帮助。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    问题在于该代码、因为我无法继续。

    我的 G2553初始化代码、它起作用:

    P1SEL |= SDA_PIN + SCL_PIN; //将 I2C 引脚分配给 USCI_B0
    P1SEL2 |= SDA_PIN + SCL_PIN; //将 I2C 引脚分配给 USCI_B0
    
    UCB0CTL1 = UCSWRST; //启用 SW 复位
    UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C 主设备,同步模式
    UCB0CTL1 = UCSSEL_2 + UCSWRST; //使用 SMCLK、保持软件复位
    UCB0BR0 =预分频; //设置预分频
    器 UCB0BR1 = 0;
    UCB0I2CSA = SLAVE_ADDRESS; //设置从地址
    UCB0CTL1 &=~UCSWRST; //清除 SW 复位、恢复运行
    UCB0I2CIE = UCNACKIE;
    IE2 = UCB0TXIE; //在
    
    (UCB0STAT 和 UCBBUSY)期间启用 TX 就绪中断
    ; 

    预分频为0x12、 SDA_PIN 0x80、SCL_PIN 0x40。 但它还包括启用中断。

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

    我确实有中断、很抱歉我的错误。 下面是它们的代码。

    #pragma vector = USCIAB0RX_Vector
    _中断 void USCIAB0RX_ISR (void){
    if (UCB0STAT 和 UCNACKIFG){ //如果从器件发送 NACK
    UCB0CTL1 |= UCTXSTP;
    UCB0STAT &=~UCNACKIFG、则发送停止;
    }
    
    
    
    #pragma vector = USCIAB0TX_Vector
    __interrupt void USCIAB0TX_ISR (void){
    if (UCB0IFG & UCRXIFG)}{
    if (UCB0IFG =
    UCTXSTP= UCB0)| UCB0CTL1 = UCB0; // I2C 停止条件
    * TI_Receive_field = UCB0RXBUF;
    TI_Receive_field++;
    }否则{
    * TI_Receive_field = UCB0RXBUF;
    TI_Receive_field++;
    byteCtr——}
    
    }否则{
    (byteCtr = 0){
    UCB0CTL1 || UCTXSTP; // I2C 停止条件
    UCB0IFG &=~UCRXIFG; //清除 USCI_B0 TX int 标志
    }否则{
    UCB0TXBUF =* TI_Transmit 字段;
    TI_Transmit 字段++;
    byteCtr -;
    }
    
    }} 

    但它们都有警告:"#2580-D pragma vector=接受数字参数或"unused_interrupts"、但不接受 USCIAB0RX_vector "


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

    为什么您以前没有告诉我们编译器抱怨该代码?

    在 F5529上、USCI B0模块有一个中断向量。 检查中断源的最简单方法是中断矢量寄存器:

    #pragma vector = USCI_B0_vector
    __interrupt void USCI_B0_interrupt (void)
    {
    开关(UCB0IV){
    USCI_I2C_UCNACKIFG 案例:
    (笑声)
    中断;
    USCI_I2C_UCRXIFG 案例:
    (笑声)
    中断;
    USCI_I2C_UCTXIFG 案例:
    (笑声)
    中断;
    默认值:
    中断;
    }
    } 

    (请注意、读取 UCB0IV 会自动清除相应的中断标志。)

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

    非常感谢! 我认为这将解决这个问题。 我将 ISR 更改为:

    #pragma vector = USCI_B0_vector
    __interrupt void USCI_B0_ISR (void)
    {
    开关(_偶数_在范围内(UCB0IV、12))
    {
    情况0:
    中断; //向量0:无中断
    案例2:
    中断; //向量2:ALIFG
    案例4:
    UCB0CTL1 |= UCTXSTP;
    UCB0IFG &=~UCNACKIFG;
    中断; //向量4:NACKIFG
    案例6:
    中断; //向量6:STTIFG
    案例8:
    中断; //向量8:STPIFG
    案例10: //向量10:RXIFG
    IF (byteCtr = 0)
    {
    UCB0CTL1 |= UCTXSTP; // I2C 停止条件
    * TI_Receive_field = UCB0RXBUF;
    TI_Receive_field++;
    }
    其他
    {
    * TI_Receive_field = UCB0RXBUF;
    TI_Receive_field++;
    字节 Ctr --;
    }
    中断;
    情况12: //向量12:TXIFG
    IF (byteCtr = 0)
    {
    UCB0CTL1 |= UCTXSTP; // I2C 停止条件
    UCB0IFG &=~UCRXIFG; //清除 USCI_B0 TX int 标志
    }
    其他
    {
    UCB0TXBUF =* TI_transmit 字段;
    TI_Transmit 字段++;
    字节 Ctr --;
    }
    中断;
    默认值:
    中断;
    
    }
    }
    

    由于我使用上面的代码调整中断、所以不会确认从器件是否存在。 下面的函数永远不会变为真、这意味着中断正暂挂。 如何纠正这种情况?

    unsigned char TI_USCI_I2C_SLAVE_Present (unsigned char SLAVE_ADDRESS){
    unsigned char IE2_bak、slaveadr_Bak、ucb0i2cie、returnValue;
    ucb0i2cie = UCB0IE; //恢复旧的 UCB0IE
    IE2_BAK = UCB0IE; //存储 IE2寄存器
    slaveadr_Bak = UCB0I2CSA; //存储旧从地址
    UCB0IE &=~ UCNACKIE; //无 NACK 中断
    UCB0I2CSA = SLAVE_ADDRESS; //设置从器件地址
    UCB0IE &=~(UCTXIE + UCRXIE); //无 RX 或 TX 中断
    _disable_interrupt ();
    UCB0CTL1 |= UCTR + UCTXSTT + UCTXSTP; // I2C TX、启动条件
    while (UCB0CTL1和 UCTXSTP)
    ; //等待停止条件
    
    返回值=!(UCB0IFG 和 UCNACKIFG);
    _enable_interrupt ();
    UCB0IE = IE2_BAK; //恢复 IE2
    UCB0I2CSA = slaveadr_Bak; //恢复旧从地址
    UCB0IE = ucb0i2cie; //恢复旧的 UCB0CTL1
    返回返回值; //返回是否
    //发生 NACK
    } 

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    当您使用示波器或逻辑分析仪观察时、总线上会发生什么情况?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我将使用示波器进行检查。

    它现在在行中显示了一条警告"#238-D controlling expression is constant":这意味着没有中断完成、它们始终处于挂起状态。

    while (TI_USCI_I2C_SLAVE_Present); 

    函数代码的相关信息。 这意味着不会创建/完成中断、它们始终处于挂起状态。

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

    若要调用函数、请添加超文本:

    while (TI_USCI_I2C_SLAVE_Present ()
    ); 

    在 C 语言中、不带 paranthesis 的函数名只是函数的地址。

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

    哦、对了! 我还需要发送 SLAVE_ADDRESS。 我这么做了、现在它卡在里面、而停止条件不是发送的。

    unsigned char TI_USCI_I2C_SLAVE_Present (unsigned char SLAVE_ADDRESS){
    unsigned char IE2_bak、slaveadr_Bak、ucb0i2cie、returnValue;
    
    ucb0i2cie = UCB0IE; //恢复旧的 UCB0IE
    IE2_BAK = UCB0IE; //存储 IE2寄存器
    slaveadr_Bak = UCB0I2CSA; //存储旧从地址
    UCB0IE &=~ UCNACKIE; //无 NACK 中断
    UCB0I2CSA = SLAVE_ADDRESS; //设置从器件地址
    UCB0IE &=~(UCTXIE + UCRXIE); //无 RX 或 TX 中断
    _disable_interrupt ();
    UCB0CTL1 |= UCTR + UCTXSTT + UCTXSTP; // I2C TX、启动条件
    while (UCB0CTL1和 UCTXSTP)
    ; //等待停止条件
    
    返回值=!(UCB0IFG 和 UCNACKIFG);
    _enable_interrupt ();
    UCB0IE = IE2_BAK; //恢复 IE2
    UCB0I2CSA = slaveadr_Bak; //恢复旧从地址
    UCB0IE = ucb0i2cie; //恢复旧的 UCB0CTL1
    返回返回值; //返回是否
    //发生 NACK
    } 

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

    此外、如果我删除该验证。 初始问题仍然存在:

    while (UCB0STAT 和 UCBBUSY)
    ; 

    永远停留在这里。 STAT 不变。

    我将检查示波器中发生的情况、然后返回给您。

    非常感谢您为帮助我所做的一切努力!

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

    还有一件事、我尝试运行其中一个代码示例、附加的代码示例起作用! 我刚才更改了从器件地址。 尽管我无法理解原因。 请听我说。

    很抱歉让你如此困扰。 但是,我非常感谢大家对我的问题给予的关注和耐心。 我真的需要我的代码能够以一个 ap 的方式工作。

    非常感谢。

    e2e.ti.com/.../0257.MSP430F55xx_5F00_uscib0_5F00_i2c_5F00_04.c

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    ICBBUSY 是检查您的第一个帖子中显示的那个还是其他某个帖子?
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    是的、它与初始帖子相同。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    下面显示了我的整个代码。 突出显示的行是它停止的位置。 您能看到它有什么问题吗?

    #include 
    
    /*
    * main.c
    */
    
    #define SLAVE_ADDRESS 0x0D /**< AD5933的地址。 //
    #define BAUD_RATE 0x12 /**<波特率值。 */
    #define SDA_PIN BIT0 // msp430F5529 UCB0SDA 引脚
    #define SCL_PIN BIT1 // msp430F5529 UCB.S.引脚
    有符号 char byteCtr;
    无符号 char * TI_transmit _field;
    
    int main (void)
    {
    WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器
    
    P3OUT |= SDA_PIN + SCL_PIN;
    P3SEL |= SDA_PIN + SCL_PIN; //将 I2C 引脚分配给 USCI_B0
    
    //P1SEL |= BIT1;
    //P1OUT &=~BIT1;//piscar led
    
    UCB0CTL1 |= UCSWRST; //启用 SW 复位
    UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C 主设备,同步模式
    UCB0CTL1 = UCSSEL_2 + UCSWRST; //使用 SMCLK、保持软件复位
    UCB0BR0 =波特率; //设置预分频器
    UCB0BR1 = 0;
    UCB0I2CSA = SLAVE_ADDRESS; //设置从器件地址
    UCB0CTL1 &=~UCSWRST; //清除 SW 复位,恢复操作
    UCB0IE = UCNACKIE;
    UCB0IE |= UCTXIE; //启用中断
    UCB0IE |= UCRXIE;
    
    while (UCB0STAT 和 UCBBUSY)
    ;
    
    
    unsigned char field[2]={0x80、0xB1};
    TI_Transmit 字段=字段;
    byteCtr = 2;
    UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX、启动条件
    while (UCB0STAT 和 UCBBUSY)
    ;
    
    while (1)
    ;
    }
    
    #pragma vector = USCI_B0_vector
    __interrupt void USCI_B0_ISR (void)
    {
    开关(_偶数_在范围内(UCB0IV、12))
    {
    情况0:
    中断; //向量0:无中断
    案例2:
    中断; //向量2:ALIFG
    案例4:
    UCB0CTL1 |= UCTXSTP;
    UCB0IFG &=~UCNACKIFG;
    中断; //向量4:NACKIFG
    案例6:
    中断; //向量6:STTIFG
    案例8:
    中断; //向量8:STPIFG
    案例10: //向量10:RXIFG
    
    情况12: //向量12:TXIFG
    IF (byteCtr = 0)
    {
    UCB0CTL1 |= UCTXSTP; // I2C 停止条件
    UCB0IFG &=~UCRXIFG; //清除 USCI_B0 TX int 标志
    }
    其他
    {
    UCB0TXBUF =* TI_transmit 字段;
    TI_Transmit 字段++;
    字节 Ctr --;
    }
    中断;
    默认值:
    中断;
    
    }
    }
    

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    在初始化之后、TX 缓冲区就为空、因此 TXIFG 被置位。 您正在启用 TXIE、因此中断处理程序会立即运行、并设置 TXSTP。 如果没有启动、则不允许这样做。

    只有当您实际准备好发送时、才应设置 TXIE。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    我使用与 G2553相同的示波器检查了总线、通道的菜单选项。
    不幸的是,没有发生任何变化。 SDA 始终为低电平、SCL 始终为高电平。
    您建议我现在做什么?
    这简直太令人沮丧了!
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    这很有意义、谢谢。
    虽然我尝试了注释"UCB0IE |= UCRXIE"行、然后注释"UCB0IE = UCNACKIE"、结果是一样的。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。
    区别在于、初始化后立即没有接收到的数据、也没有发生 NACK、因此不会出于这些原因调用中断。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    我应该将"UCB0IE |= UCTXIE;"行放在哪里? 请查看我的代码下方。

    请注意、如果我注释第一个"while (UCB0STAT 和 UCBBUSY)"、它会在另一个 while 上停止。

    #include 
    
    /*
    * main.c
    */
    
    #define SLAVE_ADDRESS 0x0D /**< AD5933的地址。 //
    #define BAUD_RATE 0x12 /**<波特率值。 */
    #define SDA_PIN BIT0 // msp430F5529 UCB0SDA 引脚
    #define SCL_PIN BIT1 // msp430F5529 UCB.S.引脚
    
    有符号 char byteCtr;
    无符号 char * TI_transmit 字段;
    无符号 char * TI_receive_field;
    
    int main (void)
    {
    WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器
    
    //LED 配置
    P1DIR |= BIT1;
    P1OUT |= BIT1;
    P1OUT ^=(BIT1);//打开 LED
    
    要发送的//MSP 配置
    P3SEL |= SDA_PIN + SCL_PIN; //将 I2C 引脚分配给 USCI_B0
    
    UCB0CTL1 |= UCSWRST; //启用 SW 复位
    UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C 主设备,同步模式
    UCB0CTL1 = UCSSEL_2 + UCSWRST; //使用 SMCLK、保持软件复位
    UCB0BR0 =波特率; //设置预分频器
    UCB0BR1 = 0;
    UCB0I2CSA = SLAVE_ADDRESS; //设置从器件地址
    UCB0CTL1 &=~UCSWRST; //清除 SW 复位,恢复操作
    UCB0IE = UCNACKIE;
    UCB0IE |= UCTXIE; //启用中断
    
    P1OUT ^=(BIT1); //关闭 LED
    while (UCB0STAT 和 UCBBUSY) //等待先前的通信清除
    ;
    
    //开始配置从机寄存器
    unsigned char field[2]={0x80、0xB1};
    TI_Transmit 字段=字段;
    byteCtr = 2;
    UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX、启动条件
    while (UCB0STAT 和 UCBBUSY)
    ;
    
    while (1)
    ;
    }//
    
    中断
    #pragma vector = USCI_B0_vector
    __interrupt void USCI_B0_ISR (void)
    {
    开关(_偶数_在范围内(UCB0IV、12))
    {
    情况0:
    中断; //向量0:无中断
    案例2:
    中断; //向量2:ALIFG
    案例4:
    IF (UCB0IFG 和 UCNACKIFG) //如果从器件发送 NACK,则发送 STOP
    {
    UCB0CTL1 |= UCTXSTP;
    UCB0IFG &=~UCNACKIFG;
    }
    中断; //向量4:NACKIFG
    案例6:
    中断; //向量6:STTIFG
    案例8:
    中断; //向量8:STPIFG
    案例10: //向量10:RXIFG --我还没有使用它(但我需要它)
    IF (byteCtr = 0)
    {
    UCB0CTL1 |= UCTXSTP; // I2C 停止条件
    * TI_Receive_field = UCB0RXBUF;
    TI_Receive_field++;
    }
    其他
    {
    * TI_Receive_field = UCB0RXBUF;
    TI_Receive_field++;
    字节 Ctr --;
    }
    中断;
    情况12: //向量12:TXIFG
    IF (byteCtr = 0)
    {
    UCB0CTL1 |= UCTXSTP; // I2C 停止条件
    UCB0IFG &=~UCTXIFG; //清除 USCI TX int 标志
    }
    其他
    {
    UCB0TXBUF =* TI_transmit 字段;
    TI_Transmit 字段++;
    字节 Ctr --;
    }
    中断;
    默认值:
    中断;
    
    }
    }
    
    
    

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

    将其放置在您希望发生第一个 TX 中断的位置、即直接在设置 TXSTT 之后。
  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    如您所见(在上面的完整代码中)、我在 STT 之后有相同的行、但是、即使我在第一次注释时(我应该删除的行、我理解)、它也会卡在 STT 之后的那个行中。

    请再次检查上面的代码、并忽略其中首次突出显示的代码。

    UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX、启动条件
    while (UCB0STAT 和 UCBBUSY)
    ; 

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

    哦、我明白了。 我也尝试过它、但也发生了同样的情况、在循环中停下来。

    WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器
    
    //LED 配置
    P1DIR |= BIT1;
    P1OUT |= BIT1;
    P1OUT ^=(BIT1);//打开 LED
    
    要发送的//MSP 配置
    P3SEL |= SDA_PIN + SCL_PIN; //将 I2C 引脚分配给 USCI_B0
    
    UCB0CTL1 |= UCSWRST; //启用 SW 复位
    UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C 主设备,同步模式
    UCB0CTL1 = UCSSEL_2 + UCSWRST; //使用 SMCLK、保持软件复位
    UCB0BR0 =波特率; //设置预分频器
    UCB0BR1 = 0;
    UCB0I2CSA = SLAVE_ADDRESS; //设置从器件地址
    UCB0CTL1 &=~UCSWRST; //清除 SW 复位,恢复操作
    UCB0IE = UCNACKIE;
    //UCB0IE |= UCTXIE; //启用中断
    
    P1OUT ^=(BIT1); //关闭 LED
    // while (UCB0STAT 和 UCBBUSY) //等待先前的通信清除
    //;
    
    //开始配置从机寄存器
    unsigned char field[2]={0x80、0xB1};
    TI_Transmit 字段=字段;
    byteCtr = 2;
    UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX、启动条件
    UCB0IE |= UCTXIE;
    while (UCB0STAT 和 UCBBUSY)
    ;
    
    while (1)
    ; 

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

    该解决方案在初始化过程中启用全局中断。

    我使用了该行:

    _enable_interrupt (); 

    感谢所有努力帮助我的人。

    此致、

    加布里埃拉