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.

[参考译文] MSP430FR5994:TXIFG 无效

Guru**** 2539570 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1031044/msp430fr5994-txifg-is-not-asserted

器件型号:MSP430FR5994

您好!

在过去两天里、我一直在尝试将2个字节的数据传输到 ADXL345。 但我仍然停留在同一个位置。我在这里共享了我的整个代码。 仔细研究、让我知道您的建议

#include <msp430.h> 
#include <stdio.h>
#define MAX30100_DEVICE                   0x57

/**
 * main.c
 */
int i=0;
char Data_In=0;
char packet[]={0x2D, 0x08,0x00};
int idx_cnt=0;

int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer

    //---Setup B0 for I2C
    UCB2CTLW0 |= UCSWRST;       // put in SW RST

    UCB2CTLW0 |= UCSSEL_3    ;   // Choose SMCLK
    UCB2BRW    = 10;            // set prescalar to 100

    UCB2CTLW0 |= UCMODE_3;      // Put into I2C
    UCB2CTLW0 |= UCMST;         // Set as master

    UCB2I2CSA = MAX30100_DEVICE;           //Set slave address 0x57
    UCB2TBCNT =sizeof(packet);               // Count = 1 byte

    UCB2CTLW1 |= UCASTP_2;      //auto STOP mode


    //--setup ports
    P7SEL1 &= ~BIT1;             //P7.1 = SCL
    P7SEL0 |=  BIT1;

    P7SEL1 &= ~BIT0;             //P7.0 = SDA
    P7SEL0 |= BIT0;

    PM5CTL0 &= ~LOCKLPM5;        // Turn on I/O

    UCB2CTLW0 &= ~UCSWRST;       //take out of in SW RST

    //-----Enable  IRQ
    UCB2IE |=UCRXIE0 ;  // local enable for RX0
    UCB2IE |=UCTXIE0 ;  //local  enable for TX0
    __enable_interrupt();



    while(1)
    {
       //Transmit reg addr with Write message
        UCB2CTLW0 |=UCTR;           //Put into TX mode
        UCB2CTLW0 |=UCTXSTT;        //Gen START

        while((UCB2IFG & UCTXIFG0) == 0)
        {
            printf("Stop on 1st while\n");
        }

        UCB2IFG &= ~UCSTPIFG;       //Clear the STOP Flag

        UCB2CTLW0 &=~UCTR;          //Put into RX Mode
        UCB2CTLW0 |=UCTXSTT;        //Gen START
        while((UCB2IFG & UCSTPIFG) == 0)
        {
            printf("Stop on second while\n");
        }
        UCB2IFG &= ~UCSTPIFG;       //Clear STOP FLAG


    }

}

//----------------------------------------------------------
//                ISR
//-----------------------------------------------------------
#pragma vector = EUSCI_B2_VECTOR
__interrupt void EUSCI_B2_I2C_ISR(void)
{
    switch(UCB2IV)
    {
    case 0x16: //ID 16:RXIFG0
        Data_In=UCB2RXBUF;
        printf("%d",Data_In);
        break;
    case 0x18: //ID 16:TXIFG0
        while(idx_cnt<=sizeof(packet-1))
        {
        UCB2TXBUF = packet[idx_cnt];
        printf("case 2");
        idx_cnt++;
        }
        break;
    default:
        break;
    }
}

 

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

    如何检测 TXIFG 是否被置位? ISR 中的断点? 或主函数中的轮询循环?

    如果 ISR 工作正常,则不可能出现一个 TXIFG,因为 ISR 将"吸收"它。  

    也就是说、你应该为每个 TXIFG 设定一次 TXBUF (只能)。 我认为这是由于 printf()而意外地起作用的。

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

            while((UCB2IFG & UCTXIFG0) == 0)
            {
                printf("Stop on 1st while\n");
            }
    

    我正在使用上面的轮询循环来检查 TXIFG。在主循环看到它之前、ISR 将会对其进行调用是非常正确的。但问题是 ISR 未按其应有的方式吸收它、TXIFG 未设置以使 ISR 获得触发。因此程序得到了结果 一直停留在 while 循环本身中。

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

    在这种情况下、示波器非常有用。  

    如果 STT 之后的 TXIFG 实际上从未出现、则表明总线被卡住。 这可能意味着(a)上拉电阻不正确或(b)从器件将 SCL 和/或 SDA 保持在低电平(可能是由于某些调试历史记录)。

    对于(a):尝试启用内部上拉电阻-这可能会有所帮助

    对于(b):是否已对 ADXL345进行下电上电? 当我使用其中一个 ADXL 时、我通常使用端口引脚为其供电、以便能够在程序控制下执行此操作。

    [编辑:我刚刚注意到:

    >#define MAX30100_device           0x57

    根据 ADXL345数据表(REve)第18页、地址为0x1D 或0x53、具体取决于 ALT_ADDRESS 引脚。 您仍应获得初始 TXIFG。]

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

    您好、Bruce、

    感谢您的回复、

    1. 我只想知道下电上电是什么意思?
    2. 您是指为传感器提供的电源吗?
    3. 我确认从器件正在将 SCL 线路保持在低电压状态。 现在、解决这个问题的方法是什么? 来解决这个问题。

    谢谢、

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

    1/2)是的、只需拔下3.3V (如果您使用的是 VIN)并将其插回。

    3) 3)如果从器件将 SCL 保持为低电平、您唯一可以做的就是将其复位。 [参考 I2C 规范(UM10204-R6)第3.2.13节]。 由于 ADXL345没有复位引脚、这意味着对其进行下电上电。 主器件需要控制 SCL (和 SDA)以生成启动。

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

    您既不启用内部上拉电阻器、也不提及外部电阻器。 使用哪个电阻器值上拉 SDA 和 SCL?

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

    您好、Bruce、

    现在、SDA 和 SCL 线路正常工作。 但我要发送的值是0x2D、但它传输0x25。 这里的问题是什么?

    谢谢、

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

    我尝试了10k 和4.7K。 我确保未启用内部上拉电阻器。

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

    您的代码现在是什么样的? 您是否仍在 ISR 中一次写入所有 TXBUF 字节?

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

            case USCI_I2C_UCTXIFG0:     // TXIFG0
                transmit_initiated = 1;
                UCB2TXBUF = *txBuffer++;
                break;

    嘿 Bruce、感谢您的回复。这就是我现在通过变速器实现的方式。 我正在尝试逐一写入传输字节。

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

    是否在事务之间重置 txBuffer?

    我不知道会改变你写入 TXBUF 的数据的机制、所以我的第一个猜测是你不会写入你认为的数据。

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

    Bruce、您好!

    我传输的任何内容 都很好。 我可以在寄存器中看到 TXBUF 值。 因此、这没有问题。 但问题是我无法从传感器接收数据。 我已经检查了示波器上的 SDA 和 SCL 线路、并且主器件/从器件 没有将线路保持在低电平。 但我仍然无法找到 无法获取 RX 数据的原因。 我已将同一代码与另一个从器件一起使用、它工作正常。  

    在 Adafruit ADXL345分线板中、已提供10K 上拉电阻器。 那么 、我是否应该为 I2C 通信添加一个外部上拉电阻器、或者板载电阻器足以完成此工作?  

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

    "无法接收"究竟意味着什么? (a)交易挂起? (b)意外的结果价值? (c)其他?

    您上面发布的代码(1)写入寄存器0x2D-0x2E、然后(2)读取寄存器0x2F (INT_MAP)、该值可能为0x00。  

    如果您的目标是读取 DATAX0-Z1、则应首先写入一个0x32的字节(DATAX0地址)、然后读取6个字节。 [参考数据表(REve)表19]

    作为快速检查、您可以将程序更改为从0x2F 开始(与现在一样)读取(3+6)、只需忽略前3个字节即可。