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:RX 中断和 STPIFG 问题

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1030906/msp430fr5994-rx-interrupt-and-stpifg-issue

器件型号:MSP430FR5994

您好!

我一直在尝试 通过 I2C 连接 ADXL345加速计。 我尝试过的所有方法 都导致我进入死区状态。无论我尝试传输的内容如何、都可以正常工作、但最后没有停止中断标志置位或 传感器无应答。 由于没有 ACK、我无法从传感器接收任何值。 我共享了我的整个代码。 仔细研究、让我知道您的建议。 提前感谢。

#include <msp430.h>
#include <stdio.h>
#include <stdint.h>
#define NUM_BYTES_TX 2
#define NUM_BYTES_RX 2
#define ADXL_345     0x53
int RXByteCtr, x1,y1,z1, RX_Data;       // enables repeated start when 1
volatile unsigned char RxBuffer[6];         // Allocate 6 byte of RAM
unsigned char *PRxData;                     // Pointer to RX data
unsigned char TXByteCtr, RX = 0;
unsigned char MSData[2];
uint8_t BW_RATE[2] ={0x2C,0x0D};
uint8_t POWER_CTL[2] ={0x2D,0x08};
uint8_t Data_Format[2] ={0x31,0x03};
unsigned int i,j;
void Setup_TX(unsigned char);
void Setup_RX(unsigned char);
void Transmit(unsigned char,unsigned char);
void TransmitOne(unsigned char);
void Receive(void);
void getX();
void getY();
void getZ();
void GPIO_Setup()
{
    // Ports
    P7SEL1 &= ~BIT0;
    P7SEL0 |= BIT0;
    P7SEL1 &= ~BIT1;
    P7SEL0 |= BIT1;
//    P7REN |= BIT0 | BIT1;                    // Enable Internal pullup resistor on P7.0 & P7.1
    PM5CTL0 &= ~LOCKLPM5;
}
int main(void)
{
  WDTCTL = WDTPW + WDTHOLD;                 // Stop WDT
  printf("Started Initialize\n");
  //Transmit process
  Setup_TX(ADXL_345);
  TransmitOne(BW_RATE[0]);
  while (UCB2CTL1 & UCTXSTP);
  printf("0x2C\n");
  Setup_TX(ADXL_345);
  TransmitOne(BW_RATE[1]);
  while (UCB2CTL1 & UCTXSTP);             // Ensure stop condition got sent
  printf("0x0D\n");
  Setup_TX(ADXL_345);
  TransmitOne(POWER_CTL[0]);
  while (UCB2CTL1 & UCTXSTP);             // Ensure stop condition got sent
  printf("0x2D\n");
  Setup_TX(ADXL_345);
  TransmitOne(POWER_CTL[1]);
  while (UCB2CTL1 & UCTXSTP);             // Ensure stop condition got sent
  printf("0x08\n");
  Setup_TX(ADXL_345);
  TransmitOne(Data_Format[0]);
  while (UCB2CTL1 & UCTXSTP);             // Ensure stop condition got sent
  printf("0x31\n");
  Setup_TX(ADXL_345);
  TransmitOne(Data_Format[1]);
  while (UCB2CTL1 & UCTXSTP);             // Ensure stop condition got sent
  printf("0x03\n");
  while(1)
  {
    getX();
//    getY();
//    getZ();
//    printf("x1 = %d, y1 = %d, z1 = %d\n",x1,y1,z1);
  }
}
void getX()
{
    //Transmit process
    Setup_TX(ADXL_345);
    TransmitOne(0x32);  // 0x32                    // Request Data from ADXL345 in 2g Range 10Bit resolution
    printf("Transmitted\n");
    while (UCB2CTL1 & UCTXSTP);             // Ensure stop condition got sent
    //Receive process
    UCB2IFG &= ~UCSTPIFG;
    Setup_RX(ADXL_345);
    Receive();
}
void getY()
{
    //Transmit process
    Setup_TX(ADXL_345);
    TransmitOne(0x34);                      // Request Data from ADXL345 in 2g Range 10Bit resolution
    printf("Transmitted\n");
    while (UCB2CTL1 & UCTXSTP);             // Ensure stop condition got sent
    //Receive process
    Setup_RX(ADXL_345);
    Receive();
}
void getZ()
{
    //Transmit process
    Setup_TX(ADXL_345);
    TransmitOne(0x36);                      // Request Data from ADXL345 in 2g Range 10Bit resolution
    printf("Transmitted\n");
    while (UCB2CTL1 & UCTXSTP);             // Ensure stop condition got sent
    //Receive process
    Setup_RX(ADXL_345);
    Receive();
}
void Setup_TX(unsigned char Dev_ID){
  RX = 0;
  printf("Inside TX\n");
  UCB2CTLW0 |= UCSWRST;               // Enable SW reset
  UCB1CTLW0 |= UCCKPL;
  UCB2CTLW0 |= UCSSEL__SMCLK;              // Use SMCLK, keep SW reset
  UCB2BRW = 10;                      // fSCL = SMCLK/12 = ~100kHz
  UCB2CTLW0 |= UCMODE_3;              // I2C Master, synchronous mode
  UCB2CTLW0 |= UCMST;
  UCB2CTLW0 |= UCTR;
  UCB2I2CSA = Dev_ID;                  // Slave Address is 053h
  UCB2CTLW1 = UCASTP_2;               // automatic STOP assertion
  GPIO_Setup();
  UCB2CTLW0 &= ~UCSWRST;             // Clear SW reset, resume operation
  UCB2IE |= UCTXIE0;
  __enable_interrupt();
//  __bis_SR_register(LPM0_bits + GIE);
}
void Setup_RX(unsigned char Dev_ID)
{
  printf("Inside RX\n");
  RX = 1;
  UCB2CTLW0 |= UCSWRST;               // Enable SW reset
  UCB1CTLW0 |= UCCKPL;
  UCB2CTLW0 |= UCSSEL__SMCLK;              // Use SMCLK, keep SW reset
  UCB2BRW = 10;                      // fSCL = SMCLK/12 = ~100kHz
  UCB2CTLW0 |= UCMODE_3;              // I2C Master, synchronous mode
  UCB2CTLW0 |= UCMST;
  UCB2CTLW0 &=~UCTR;
  UCB2I2CSA = Dev_ID;                  // Slave Address is 053h
  UCB2CTLW1 = UCASTP_2;               // automatic STOP assertion
  UCB2TBCNT = 1;
  GPIO_Setup();
  UCB2CTLW0 &= ~UCSWRST;             // Clear SW reset, resume operation
  UCB2IE |= UCRXIE0;
  __enable_interrupt();
  printf("RX Completed\n");
}
void Transmit(unsigned char Reg_ADD,unsigned char Reg_DAT)
{
    __disable_interrupt();
    printf("Inside Transmit Function\n");
    MSData[1]= Reg_ADD;
    MSData[0]= Reg_DAT;
    UCB2TBCNT = NUM_BYTES_TX;         // TX 2 bytes of data
    TXByteCtr = NUM_BYTES_TX;         // Load TX byte counter
    while (UCB2CTL1 & UCTXSTP);
    UCB2CTLW0 |= UCTXSTT;             // I2C TX, start condition
    __delay_cycles(2000);
    __enable_interrupt();
}
void TransmitOne(unsigned char Reg_ADD)
{
    printf("Inside TransmitOne Function\n");
    TXByteCtr = 1;
    UCB2TBCNT = 1;
    MSData[0]= Reg_ADD;
    UCB2CTLW0 |=UCTR;
    UCB2CTLW0 |= UCTXSTT;             // I2C TX, start condition
    __delay_cycles(2000);
    __enable_interrupt();
}
void Receive(void)
{
    printf("Receive\n");
    PRxData = (unsigned char *)RxBuffer;    // Start of RX buffer
    RXByteCtr = 1;
    while (UCB2CTL1 & UCTXSTP);
    UCB2CTLW0 |= UCTXSTT;                    // I2C start condition
    __delay_cycles(2000);
    __enable_interrupt();
}
//-------------------------------------------------------------------
// ISR Vector
//-------------------------------------------------------------------
#pragma vector = EUSCI_B2_VECTOR
__interrupt void I2C_B2_ISR(void)
{
    printf("Interrupt Routine\n");
    switch(UCB2IV)
      {
        case USCI_NONE:          break;         // Vector 0: No interrupts
        case USCI_I2C_UCALIFG:   break;         // Vector 2: ALIFG
        case USCI_I2C_UCNACKIFG:                // Vector 4: NACKIFG
            printf("inside NACK\n");
            UCB2CTL1 |= UCTXSTT;                //re-send start if NACK
          break;
        case USCI_I2C_UCSTTIFG:  break;         // Vector 6: STTIFG
        case USCI_I2C_UCSTPIFG:  break;         // Vector 8: STPIFG
        case USCI_I2C_UCRXIFG3:  break;         // Vector 10: RXIFG3
        case USCI_I2C_UCTXIFG3:  break;         // Vector 12: TXIFG3
        case USCI_I2C_UCRXIFG2:  break;         // Vector 14: RXIFG2
        case USCI_I2C_UCTXIFG2:  break;         // Vector 16: TXIFG2
        case USCI_I2C_UCRXIFG1:  break;         // Vector 18: RXIFG1
        case USCI_I2C_UCTXIFG1:  break;         // Vector 20: TXIFG1
        case USCI_I2C_UCRXIFG0:                 // Vector 22: RXIFG0
            if(RX == 1)
            {                                   // Master Receive?
              RXByteCtr--;                      // Decrement RX byte counter
              if (RXByteCtr)
                {
                  *PRxData++ = UCB2RXBUF;       // Move RX data to address PRxData
                  printf("Received = %d", *PRxData);
                }
              else
                {
                  UCB2CTL1 |= UCTXSTP;          // No Repeated Start: stop condition
                  *PRxData++ = UCB2RXBUF;       // Move final RX data to PRxData
                  printf("Else Received = %d", *PRxData);
                  __disable_interrupt();        // Exit LPM0
                }
            }
            else
            {
                printf("RX = 0\n");
            }
          break;
        case USCI_I2C_UCTXIFG0:                 // Vector 24: TXIFG0
            printf("ISR Transmitted\n");
            UCB2TXBUF = MSData[0];
            break;
        case USCI_I2C_UCBCNTIFG: break;         // Vector 26: BCNTIFG
        case USCI_I2C_UCCLTOIFG: break;         // Vector 28: clock low timeout
        case USCI_I2C_UCBIT9IFG: break;         // Vector 30: 9th bit
        default: break;
      }
}

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

    1) 1)设置寄存器值需要(至少)单次传输2个字节--第一个字节被解释为寄存器编号,第二个字节被解释为值。 [请参考 ADXL345数据表(REve)图41]此代码将其拆分为两个事务。 我建议您添加一个 TransmitTwo ()函数。  

    2) 2) TBCNT 只能在 I2C 单元处于复位状态时置1 (UCSWRST=1)[参考用户指南(SLAU367P)表32-8]。  一种方法是将长度值传递到 Setup_TX()中。

    3) 3)检查 UCTXSTP=0并不是等待事务完成的可靠机制、因为它只在事务的一小部分开启。 我建议您使用基于软件的"忙"变量。

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

    抱歉、PAL.This 未解决我的问题。问题在于传输后 TXIFG 未设置。请帮助我解决。

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

    好的、我读了"我尝试传输的任何内容都可以正常工作"、所以我在找其他地方。  

    您使用的是什么 ADXL345板? ADI 的 ADXL345EB 不提供总线上拉电阻、也不提供 Launchpad。 缺少上拉 电阻与非 TXIFG 症状一致。

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

    我们使用的是 Adafruit ADXL345开发板、我们还连接了4.7K 上拉电阻器、但仍然卡在 TXIFG 中

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

    未设置哪个 TXIFG? STT 之后的那个? 哪项交易?

    您可能需要尝试对加速计进行下电上电。 在进行某些事务后、此代码将生成它、可能已保留总线。

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

    Bruce、您好!

    感谢您的快速回复。

    事务之后的 TXIFG0 (while (!(UCB2IFG & UCTXIFG));)未被置位。 是、STT 之后。

    我们还尝试使用 TI 自己 SDK 中的示例代码与两个 MSP430fr5994作为从站和主站进行通信。 这也不能提供所需的结果。 该示例表明从器件向主器件发送5个字节。 我们还在从器件中启用了 UCTR。 在主器件中清除。 在主器件中、执行卡在此行中、同时(UCB2CTL1和 UCTXSTP);

    请帮助我们、

    谢谢你