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:相同的传感器模块在不同的微控制器上消耗不同的功率

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1087873/msp430fr5994-same-sensor-module-consuming-different-amount-of-power-on-different-microcontrollers

部件号:MSP430FR5994
主题中讨论的其他部件: ENERGYTRACE

嘿,社区,

我在加速计ADXL345上工作了一段时间。   我在这里遇到了一些奇怪的问题。

问题:

注:在整个问题过程中,寄存器值是相同的,只有传感器的功耗没有谈到微控制器+传感器的功耗  

1.我已通过Arduino通过I2C对ADXL345进行编程,并获得了传感器的功耗(0.02mA),但当我通过msp430FR5994对ADXL345进行编程时,我获得 了相同寄存器值的传感器功耗(0.2mA)。 但两个微控制器的传感器工作正常

我不会在哪里做错,也不会有任何合乎逻辑的解释。 我已经附上了Arduino代码和MSP430代码,请浏览并告诉我您对这一条的建议/想法。

MSP430 I2C驱动器

MSP430 i2c driver

#ifndef I2C_H_
#define I2C_H_

#include <msp430.h>
#include <stdint.h>
#include <stdbool.h>

//******************************************************************************
// Pin Config ******************************************************************
//******************************************************************************

#define LED_OUT     P1OUT
#define LED_DIR     P1DIR
#define LED0_PIN    BIT0
#define LED1_PIN    BIT1

#define CMD_TYPE_0_SLAVE      0x00
#define CMD_TYPE_1_SLAVE      1
#define CMD_TYPE_2_SLAVE      3
#define CMD_TYPE_3_SLAVE      2

#define CMD_TYPE_0_MASTER      3
#define CMD_TYPE_1_MASTER      4
#define CMD_TYPE_2_MASTER      5

#define TYPE_0_LENGTH   1
#define TYPE_1_LENGTH   2
#define TYPE_2_LENGTH   6

#define MAX_BUFFER_SIZE     20

/* MasterTypeX are example buffers initialized in the master, they will be
 * sent by the master to the slave.
 * SlaveTypeX are example buffers initialized in the slave, they will be
 * sent by the slave to the master.
 * */


//uint8_t MasterType2 [TYPE_2_LENGTH] = {'F', '4', '1', '9', '2', 'B'};
uint8_t MasterType1 [TYPE_1_LENGTH] = { 8, 9};
uint8_t MasterType0 [TYPE_0_LENGTH] = {0x08};
uint8_t MasterType3 [TYPE_0_LENGTH] = {0x0A};
uint8_t MasterType4 [TYPE_0_LENGTH] = {0x03};


uint8_t SlaveType2 [TYPE_2_LENGTH] = {0};
uint8_t SlaveType1 [TYPE_1_LENGTH] = {0};
uint8_t SlaveType0 [TYPE_0_LENGTH] = {0};



typedef enum I2C_ModeEnum{
    IDLE_MODE,
    NACK_MODE,
    TX_REG_ADDRESS_MODE,
    RX_REG_ADDRESS_MODE,
    TX_DATA_MODE,
    RX_DATA_MODE,
    SWITCH_TO_RX_MODE,
    SWITHC_TO_TX_MODE,
    TIMEOUT_MODE
} I2C_Mode;


I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count);

I2C_Mode I2C_Master_ReadReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t count);

void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count);

void initGPIO();

void initClockTo16MHz();

void initI2C(uint8_t SLAVE_ADDR,uint8_t clk_div);

#define MAX_BUFFER_SIZE     20

#define MAX_BUFFER_SIZE     20

/* Used to track the state of the software state machine*/
I2C_Mode MasterMode = IDLE_MODE;

/* The Register Address/Command to use*/
uint8_t TransmitRegAddr = 0;

/* ReceiveBuffer: Buffer used to receive data in the ISR
 * RXByteCtr: Number of bytes left to receive
 * ReceiveIndex: The index of the next byte to be received in ReceiveBuffer
 * TransmitBuffer: Buffer used to transmit data in the ISR
 * TXByteCtr: Number of bytes left to transfer
 * TransmitIndex: The index of the next byte to be transmitted in TransmitBuffer
 * */
uint8_t ReceiveBuffer[MAX_BUFFER_SIZE] = {0};
uint8_t RXByteCtr = 0;
uint8_t ReceiveIndex = 0;
uint8_t TransmitBuffer[MAX_BUFFER_SIZE] = {0};
uint8_t TXByteCtr = 0;
uint8_t TransmitIndex = 0;



I2C_Mode I2C_Master_ReadReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t count)
{
    /* Initialize state machine */
    MasterMode = TX_REG_ADDRESS_MODE;
    TransmitRegAddr = reg_addr;
    RXByteCtr = count;
    TXByteCtr = 0;
    ReceiveIndex = 0;
    TransmitIndex = 0;

    /* Initialize slave address and interrupts */
    UCB2I2CSA = dev_addr;
    UCB2IFG &= ~(UCTXIFG + UCRXIFG);       // Clear any pending interrupts
    UCB2IE &= ~UCRXIE;                       // Disable RX interrupt
    UCB2IE |= UCTXIE;                        // Enable TX interrupt

    UCB2CTLW0 |= UCTR + UCTXSTT;             // I2C TX, start condition
    __bis_SR_register(LPM0_bits+GIE);              // Enter LPM0 w/ interrupts

    return MasterMode;

}


I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count)
{
    /* Initialize state machine */
    MasterMode = TX_REG_ADDRESS_MODE;
    TransmitRegAddr = reg_addr;

    //Copy register data to TransmitBuffer
    CopyArray(reg_data, TransmitBuffer, count);

    TXByteCtr = count;
    RXByteCtr = 0;
    ReceiveIndex = 0;
    TransmitIndex = 0;

    /* Initialize slave address and interrupts */
    UCB2I2CSA = dev_addr;
    UCB2IFG &= ~(UCTXIFG + UCRXIFG);       // Clear any pending interrupts
    UCB2IE &= ~UCRXIE;                       // Disable RX interrupt
    UCB2IE |= UCTXIE;                        // Enable TX interrupt

    UCB2CTLW0 |= UCTR + UCTXSTT;             // I2C TX, start condition
    __enable_interrupt();
    __bis_SR_register(LPM0_bits);              // Enter LPM0 w/ interrupts

    return MasterMode;
}

void CopyArray(uint8_t *source, uint8_t *dest, uint8_t count)
{
    uint8_t copyIndex = 0;
    for (copyIndex = 0; copyIndex < count; copyIndex++)
    {
        dest[copyIndex] = source[copyIndex];
    }
}


//******************************************************************************
// Device Initialization *******************************************************
//******************************************************************************


void init_i2c_GPIO()
{
    // Configure GPIO
    LED_OUT &= ~(LED0_PIN | LED1_PIN); // P1 setup for LED & reset output
    LED_DIR |= (LED0_PIN | LED1_PIN);

    // I2C pins
    P7SEL0 |= BIT0 | BIT1;
    P7SEL1 &= ~(BIT0 | BIT1);

    // Disable the GPIO power-on default high-impedance mode to activate
    // previously configured port settings
    PM5CTL0 &= ~LOCKLPM5;
}

void initClockTo16MHz()
{
    // Configure one FRAM waitstate as required by the device datasheet for MCLK
    // operation beyond 8MHz _before_ configuring the clock system.
    FRCTL0 = FRCTLPW | NWAITS_1;

    // Clock System Setup
    CSCTL0_H = CSKEY_H;                     // Unlock CS registers
    CSCTL1 = DCOFSEL_0;                     // Set DCO to 1MHz

    // Set SMCLK = MCLK = DCO, ACLK = LFXTCLK (VLOCLK if unavailable)
    CSCTL2 = SELA__LFXTCLK | SELS__DCOCLK | SELM__DCOCLK;

    // Per Device Errata set divider to 4 before changing frequency to
    // prevent out of spec operation from overshoot transient
    CSCTL3 = DIVA__4 | DIVS__4 | DIVM__4;   // Set all corresponding clk sources to divide by 4 for errata
    CSCTL1 = DCOFSEL_4 | DCORSEL;           // Set DCO to 16MHz

    // Delay by ~10us to let DCO settle. 60 cycles = 20 cycles buffer + (10us / (1/4MHz))
    __delay_cycles(60);
    CSCTL3 = DIVA__1 | DIVS__1 | DIVM__1;   // Set all dividers to 1 for 16MHz operation
    CSCTL0_H = 0;                           // Lock CS registers
}

void initI2C(uint8_t SLAVE_ADDR,uint8_t clk_div)
{
    UCB2CTLW0 = UCSWRST;                      // Enable SW reset
    UCB2CTLW0 |= UCMODE_3 | UCMST | UCSSEL__SMCLK | UCSYNC; // I2C master mode, SMCLK
    UCB2BRW = clk_div;                            // fSCL = SMCLK/160 = ~1 MHz
    UCB2I2CSA = SLAVE_ADDR;                   // Slave Address
    UCB2CTLW0 &= ~UCSWRST;                    // Clear SW reset, resume operation
    UCB2IE |= UCNACKIE;
}

#if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
#pragma vector = USCI_B2_VECTOR
__interrupt void USCI_B2_ISR(void)
#elif defined(__GNUC__)
void __attribute__ ((interrupt(USCI_B2_VECTOR))) USCI_B2_ISR (void)
#else
#error Compiler not supported!
#endif
{
  //Must read from UCB2RXBUF
  uint8_t rx_val = 0;
  switch(__even_in_range(UCB2IV, USCI_I2C_UCBIT9IFG))
  {
    case USCI_NONE:          break;         // Vector 0: No interrupts
    case USCI_I2C_UCALIFG:   break;         // Vector 2: ALIFG
    case USCI_I2C_UCNACKIFG:                // Vector 4: NACKIFG
      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
        rx_val = UCB2RXBUF;
        if (RXByteCtr)
        {
          ReceiveBuffer[ReceiveIndex++] = rx_val;
          RXByteCtr--;
        }

        if (RXByteCtr == 1)
        {
          UCB2CTLW0 |= UCTXSTP;
        }
        else if (RXByteCtr == 0)
        {
          UCB2IE &= ~UCRXIE;
          MasterMode = IDLE_MODE;
          __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0
        }
        break;
    case USCI_I2C_UCTXIFG0:                 // Vector 24: TXIFG0
        switch (MasterMode)
        {
          case TX_REG_ADDRESS_MODE:
              UCB2TXBUF = TransmitRegAddr;
              if (RXByteCtr)
                  MasterMode = SWITCH_TO_RX_MODE;   // Need to start receiving now
              else
                  MasterMode = TX_DATA_MODE;        // Continue to transmision with the data in Transmit Buffer
              break;

          case SWITCH_TO_RX_MODE:
              UCB2IE |= UCRXIE;              // Enable RX interrupt
              UCB2IE &= ~UCTXIE;             // Disable TX interrupt
              UCB2CTLW0 &= ~UCTR;            // Switch to receiver
              MasterMode = RX_DATA_MODE;    // State state is to receive data
              UCB2CTLW0 |= UCTXSTT;          // Send repeated start
              if (RXByteCtr == 1)
              {
                  //Must send stop since this is the N-1 byte
                  while((UCB2CTLW0 & UCTXSTT));
                  UCB2CTLW0 |= UCTXSTP;      // Send stop condition
              }
              break;

          case TX_DATA_MODE:
              if (TXByteCtr)
              {
                  UCB2TXBUF = TransmitBuffer[TransmitIndex++];
                  TXByteCtr--;
              }
              else
              {
                  //Done with transmission
                  UCB2CTLW0 |= UCTXSTP;     // Send stop condition
                  MasterMode = IDLE_MODE;
                  UCB2IE &= ~UCTXIE;                       // disable TX interrupt
                  __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0
              }
              break;

          default:
              __no_operation();
              break;
        }
        break;
    default: break;
  }
}

#endif /* I2C_H_ */

MSP430主要c.

#include <msp430.h> 
#include <Communication_Drivers\i2c.h>

int recieve_count=0;
int data[10]={0};

#define ADXL_Address    0x53
#define Part_id      0x00
#define Clock_Div    160

#define Power_CTL             0x2D
#define Data_Rate             0x2C
#define Data_Format           0x31

#define X0_Reg                0x32


uint8_t adxl_Power_Ctl_cmd     [TYPE_0_LENGTH] = {0x08};  //
uint8_t adxl_Data_Rate_cmd     [TYPE_0_LENGTH] = {0x08};  // Lower power mode with 25 Hz bandwidth and 12.5Hz ODR   ||0x17 for 6.25hz bandwith and 12.5Hz ODR
uint8_t adxl_Data_Format_cmd   [TYPE_0_LENGTH] = {0x00};  //Range :+-2g INT inver bit is low

#define Power_CTL_value  0x08
#define Data_Rate_value  0x08
#define Data_Format_valu 0x00


/**
 * main.c
 */
int main(void)
{
	WDTCTL = WDTPW | WDTHOLD;	// stop watchdog timer
	
	init_i2c_GPIO();
	initI2C(ADXL_Address, Clock_Div);

	I2C_Master_WriteReg(ADXL_Address, Data_Rate, adxl_Data_Rate_cmd, TYPE_0_LENGTH);
    I2C_Master_WriteReg(ADXL_Address, Data_Format, adxl_Data_Format_cmd, TYPE_0_LENGTH);
    I2C_Master_WriteReg(ADXL_Address, Power_CTL, adxl_Power_Ctl_cmd, TYPE_0_LENGTH);
    I2C_Master_ReadReg(ADXL_Address, Part_id, TYPE_0_LENGTH);


    while(1)
    {
        I2C_Master_ReadReg(ADXL_Address, X0_Reg, TYPE_2_LENGTH);
        data[0] = (short)((((unsigned short)ReceiveBuffer[1]) << 8) | ReceiveBuffer[0]);
        data[1] = (short)((((unsigned short)ReceiveBuffer[3]) << 8) | ReceiveBuffer[2]);
        data[2] = (short)((((unsigned short)ReceiveBuffer[5]) << 8) | ReceiveBuffer[4]);
        __delay_cycles(8000000);
    }
	return 0;
}

Arduino代码

#include <Wire.h>

Int ReceiveBuffer[10]={0};
int recieve_count=0;
int data[10]={0};

#define ADXL_Address 0x53
#define Part_id 0x00


#Define Power_CTL 0x2D
#Define Data_Rate 0x2C
#Define Data_Format 0x31

#define X0_Reg 0x32

#define Power_CTL_Value 0x08
#define Data_RATE_VALUE 0x08
#Define Data_Format_valu 0x00


void setup(){
Serial.begin(11.52万);
Wire.begin();
serial.print ("开始");

Wire.beginTransmission(ADXL_Address);
wire.write (数据格式);
wire.write (Data_Format_valu);
wire.endTransmission ();


Wire.beginTransmission(ADXL_Address);
wire.write (数据速率);
wire.write (数据速率值);
wire.endTransmission ();

Wire.beginTransmission(ADXL_Address);
wire.write (Power_CTL);
wire.write (Power_CTL_Value);
wire.endTransmission ();
}

void loop(){
Wire.beginTransmission(ADXL_Address);
wire.write (0x32);
wire.endTransmission ();
wire.requestFrom (0x53,6,TRUE);

recieve_count=0;

while (Wire.Available ())

ReceiveBuffer[receve_count]=Wire.Read();
receve_count++;
}
DATA[0]=(短)((((无符号短) ReceiveBuffer[1])<8)| ReceiveBuffer[0]);
Data[1]=(短)((((unsigned short) ReceiveBuffer[3])<< 8)| ReceiveBuffer[2]);
Data[2]=(short)(((((unsigned short)ReceiveBuffer[5])<8)| ReceiveBuffer[4]);

serial.println (data[0]);
serial.println (data[1]);
serial.println (data[2]);
延迟(1000);

}

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

    您是如何衡量这一点的? 它是DMM (时间平均值)还是高分辨率 功率监视器(活动模式)? 此外,您如何将测量结果与ADXL345隔离?  

    我问一下,因为它看起来你运行的I2C大约是(1MHz/160)=6kHz,这意味着在I2C上拉时需要更多的时间。 我预计Arduino的运行频率为100kHz (可能为400kHz)。

    一个快速的实验是将Clock_div从160更改为10,这样总线以大约100kHz的频率运行。

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

    因为我的大部分组件都在试验电路板上。我只是在电源和传感器之间挂了一个电流表。 我还尝试了不同的时钟频率。 我已经检查了我的时钟配置,我的主板默认为8MHz。

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

    你好,Selvakumaran I:

    如果寄存器写入相同,则ADXL345的行为应该完全相同。 我怀疑系统中的其他地方可能存在差异。 我的最佳猜测是Arduino和MSP430FR5994之间的拉力调节器不同。

    您能否检查Arduino上的上拉电阻器? Arduino板上是否有内部上拉或上拉?

    MSP430FR5994能够使用内部上拉电阻器,但我没有看到您的代码配置这些电阻器。 您需要将PxOUT = 1设置为配置内部上拉。 您是否使用外部上拉电阻器?

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

    嗨,Evan,

    感谢您的建议。但我使用的是传感器开发板附带的外部上拉电阻

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

    我建议将MSP430 GPIO显式配置为上拉电阻器(参见表12-6。 PxOUT寄存器说明了解更多信息)。 如果未显式配置IO,则可将其配置为下拉,这将导致更高的电流消耗。 数据表显示PxOUT配置在重置后处于未知状态,因此最佳做法是对其进行编程。

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

    由于200uA即使在最高速度下也高于预期的功耗并且Vs=3.3V [Ref ADXL345 data sheet (Rev E) Figs 32/33],我怀疑芯片外有什么东西,总线是第一个怀疑的问题。 如何连接INT1/2? 另外,我想Vcc=Vdio=3.3V,您使用什么来处理Vs?  

    启动时,FR5994时钟(MCLK)以1MHz运行(DCO=8MHz,带有/8分频器)[请参阅FR5用户指南(SLAU367P)表和3-5 (DCOFSEL)和3-7 (DIVM)]。 我看不到上面的任何代码会改变这一点。 您可以在WFP 3.4 上测量(作为代理) SMCLK]

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

    嗨,Bruce,感谢您提供有关时钟的信息。 我不是很清楚这一点,对于Vs,我使用评估板上的3.3V电源针脚。 我将检查我的时钟并更新您的信息。

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

    嗨,Bruce,

    我已更改时钟设置并已检查。 但我仍然停留在0.18mA

    以下是新代码:

    #include <msp430.h> 
    #include <Communication_Drivers\i2c.h>
    
    int recieve_count=0;
    int data[10]={0};
    
    #define ADXL_Address    0x53
    #define Part_id      0x00
    #define Clock_Div    80
    
    #define Power_CTL             0x2D
    #define Data_Rate             0x2C
    #define Data_Format           0x31
    
    #define X0_Reg                0x32
    
    
    uint8_t adxl_Power_Ctl_cmd     [TYPE_0_LENGTH] = {0x08};  //
    uint8_t adxl_Data_Rate_cmd     [TYPE_0_LENGTH] = {0x08};  // Lower power mode with 25 Hz bandwidth and 12.5Hz ODR   ||0x17 for 6.25hz bandwith and 12.5Hz ODR
    uint8_t adxl_Data_Format_cmd   [TYPE_0_LENGTH] = {0x00};  //Range :+-2g INT inver bit is low
    
    #define Power_CTL_value  0x08
    #define Data_Rate_value  0x08
    #define Data_Format_valu 0x00
    
    
    void LPM1_Clock_config()
    {
        CSCTL0_H = CSKEY_H;
        CSCTL1 = DCOFSEL_6; //8MHz |DCOFSEL_0 -1MHz
        CSCTL2 = SELA__VLOCLK | SELS__DCOCLK | SELM__DCOCLK;  // Set SMCLK = MCLK = DCO
        CSCTL3 = DIVA_0|DIVS__1|DIVM__1;
        CSCTL0_H = 0;
    }
    
    /**
     * main.c
     */
    int main(void)
    {
    	WDTCTL = WDTPW | WDTHOLD;	// stop watchdog timer
    	
    	LPM1_Clock_config();
    	init_i2c_GPIO();
    	initI2C(ADXL_Address, Clock_Div);
    
    
    
    
        while(1)
        {
    
            I2C_Master_WriteReg(ADXL_Address, Data_Rate, adxl_Data_Rate_cmd, TYPE_0_LENGTH);
            I2C_Master_WriteReg(ADXL_Address, Data_Format, adxl_Data_Format_cmd, TYPE_0_LENGTH);
            I2C_Master_WriteReg(ADXL_Address, Power_CTL, adxl_Power_Ctl_cmd, TYPE_0_LENGTH);
            I2C_Master_ReadReg(ADXL_Address, Part_id, TYPE_0_LENGTH);
    
            I2C_Master_ReadReg(ADXL_Address, X0_Reg, TYPE_2_LENGTH);
            data[0] = (short)((((unsigned short)ReceiveBuffer[1]) << 8) | ReceiveBuffer[0]);
            data[1] = (short)((((unsigned short)ReceiveBuffer[3]) << 8) | ReceiveBuffer[2]);
            data[2] = (short)((((unsigned short)ReceiveBuffer[5]) << 8) | ReceiveBuffer[4]);
            __delay_cycles(8000000);
        }
    	return 0;
    }
    

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

    嗨,Bruce,

    我尝试了不同的评估板,现在它工作正常。 但这两个板都是相同的,但 传感器的功耗因板而异。 那么,这里的问题是什么呢?

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

    这些商业评估版是否包括ADI,Adafruit,SparkFun? 这些组织将出版图表,这可能是一个起点。

    我觉得有趣的是,加速MCU (以及总线)会降低功耗,即使只是一点点。

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

    Ya传感器是Adafruit adxl345。评估板I是指TI MSP430FR5994 Launchaad开发套件而不 是传感器开发套件。那么 ,同一程序在同一两个相同的MSP430FR5994 launad上的功耗不同的原因是什么。

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

    我不能随便说。  

    虽然此程序对于功能演示很有用,但对于演示FR5994中的低功耗并不特别有用。 首先,大多数PIN都是浮动的,启用了施密特触发器,因此它们会不断地进行拼图。 但这不会直接影响ADXL与。

    INT1/INT2是如何接线的? 它们是否连接到MCU? 它们是向上还是向下拉?

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

    嗨,Bruce,

    如果中断不是一个好的低功耗模式程序,中断将被拉下。 请帮我优化代码。

    我知道一些事情:

    1.如将销钉绑定到稳定状态。

    2.降低到适当的时钟速度

    3.尽量使MCU保持在“基本睡眠”模式

    4.数学函数不会耗时

    注意:此程序旨在每30秒读取加速度计数据,此处使用VLOCLK作为我 的ACLK的来源

    #include <msp430.h>
    #include <stdio.h>
    #include <i2c\I2C.h>
    #include <UART\UART.h>
    #include <ADXL345\ADXL345.h>
    #include <Clock_Config.H>
    #include <string.h>
    
    
    /**
     * main.c
     */
    
    int16_t x[5]={0};
    int16_t y[5]={0};
    int16_t z[5]={0};
    int16_t xf,yf,zf=0;
    int16_t data[5]={0};
    
    /*---------------------------------------------------------------------------------------------------------------------------------------------------\
     * ----------------------------------------------------------------------------------------------------------------------------------------------------
     *                                                          UART VARIABLES
     * ----------------------------------------------------------------------------------------------------------------------------------------------------
     ----------------------------------------------------------------------------------------------------------------------------------------------------------*/
    
    #define sizeOfNumber 5
    
    unsigned char num_string[sizeOfNumber]="";
    volatile unsigned char RXData[5]="";
    unsigned char TXData[300]="";
    volatile int Tx_position=0;
    volatile int Rx_position=0;
    
    volatile unsigned int Tx_key=0;
    volatile unsigned int Rx_key=0;
    
    int size=0;
    
    
    void Timer_initialize()
    {
        TB0CTL &=~TB0CTL;                         //Clears the timer
        TB0EX0 |=0x7;                             // again divided by 8 (4096/8=512)
        TB0CCTL0 = CCIE;                        // TBCCR0 interrupt enabled
    }
    
    void Timer_Start_30_Secs()
    {
        TB0CCR0 =1800;                          // approx 60 secs    (32768/512=60 but here are some errors it gives 45 secs so i experimened with values and settled with 35840)
        TB0CTL |=TBSSEL__ACLK|MC__UP|ID__8;
    //    __bis_SR_register(LPM4_bits|GIE);
    }
    
    
    #define ClockDiv 80
    int main(void)
    {
        WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer
    
    
        unsigned int ADXL345_Dev_id=0;
        unsigned int i=0;
    
        P1OUT = 0;
        P1DIR = 0xFF;
    
        P2OUT = 0;
        P2DIR = 0xFF;
    
        P3OUT = 0;
        P3DIR = 0xFF;
    
        P4OUT = 0;
        P4DIR = 0xFF;
    
        P5OUT = 0;
        P5DIR = 0xFF;
    
        P6OUT = 0;
        P6DIR = 0xFF;
    
        P7OUT = 0;
        P7DIR = 0xFF;
    
        P8OUT = 0;
        P8DIR = 0xFF;
    
        PJOUT = 0;
        PJDIR = 0xFFFF;
    
    
    
        LPM1_Clock_config();
        Timer_initialize();
        UART_GPIO_Config();
        initGPIO();
    
        initI2C(ADXL345_Address,ClockDiv);
    
        I2C_Master_ReadReg(ADXL345_Address, CMD_TYPE_1_SLAVE, 28);
    
        ADXL345_Dev_id=Adxl_Deviceid();
        Adxl_set_Datarate(ADXL345_Address, adxl_Data_Rate, adxl_Data_Rate_cmd, TYPE_0_LENGTH);
        Adxl_set_Dataformat(ADXL345_Address, adxl_Data_Format, adxl_Data_Format_cmd, TYPE_0_LENGTH);
    //    Adxl_set_Fifo_Ctl(ADXL345_Address, adxl_FIFO_CTL, adxl_FIFO_Cmd, TYPE_0_LENGTH);
    //    Adxl_set_Power_Ctl(ADXL345_Address, adxl_Power_CTL, adxl_Power_Ctl_cmd, TYPE_0_LENGTH);
    
    
        I2C_Master_ReadReg(ADXL345_Address, adxl_Data_Rate, TYPE_0_LENGTH);
        I2C_Master_ReadReg(ADXL345_Address, adxl_Data_Format, TYPE_0_LENGTH);
    
    
    
        while(1)
        {
        memset(TXData, 0, sizeof(TXData));
        Adxl_read_axis(ADXL345_Address,adxl_X0_Reg,TYPE_2_LENGTH,data,yf,zf);
        x[0]=data[0];
        y[0]=data[1];
        z[0]=data[2];
        i++;
    
        adxl_sleep_mode();    // Put accelerometer to sleep
        Timer_Start_30_Secs();
        __bis_SR_register(LPM4_bits|GIE);
        Wakeup();          // wakeup the acclerometer 
        }
        return 0;
    }
    
    
    
    //******************************************************************************
    // I2C Interrupt ***************************************************************
    //******************************************************************************
    
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector = USCI_B2_VECTOR
    __interrupt void USCI_B2_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(USCI_B2_VECTOR))) USCI_B2_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
      //Must read from UCB2RXBUF
      uint8_t rx_val = 0;
      switch(__even_in_range(UCB2IV, USCI_I2C_UCBIT9IFG))
      {
        case USCI_NONE:          break;         // Vector 0: No interrupts
        case USCI_I2C_UCALIFG:   break;         // Vector 2: ALIFG
        case USCI_I2C_UCNACKIFG:                // Vector 4: NACKIFG
          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
            rx_val = UCB2RXBUF;
            if (RXByteCtr)
            {
              ReceiveBuffer[ReceiveIndex++] = rx_val;
              RXByteCtr--;
            }
    
            if (RXByteCtr == 1)
            {
              UCB2CTLW0 |= UCTXSTP;
            }
            else if (RXByteCtr == 0)
            {
              UCB2IE &= ~UCRXIE;
              MasterMode = IDLE_MODE;
              __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0
            }
            break;
        case USCI_I2C_UCTXIFG0:                 // Vector 24: TXIFG0
            switch (MasterMode)
            {
              case TX_REG_ADDRESS_MODE:
                  UCB2TXBUF = TransmitRegAddr;
                  if (RXByteCtr)
                      MasterMode = SWITCH_TO_RX_MODE;   // Need to start receiving now
                  else
                      MasterMode = TX_DATA_MODE;        // Continue to transmision with the data in Transmit Buffer
                  break;
    
              case SWITCH_TO_RX_MODE:
                  UCB2IE |= UCRXIE;              // Enable RX interrupt
                  UCB2IE &= ~UCTXIE;             // Disable TX interrupt
                  UCB2CTLW0 &= ~UCTR;            // Switch to receiver
                  MasterMode = RX_DATA_MODE;    // State state is to receive data
                  UCB2CTLW0 |= UCTXSTT;          // Send repeated start
                  if (RXByteCtr == 1)
                  {
                      //Must send stop since this is the N-1 byte
                      while((UCB2CTLW0 & UCTXSTT));
                      UCB2CTLW0 |= UCTXSTP;      // Send stop condition
                  }
                  break;
    
              case TX_DATA_MODE:
                  if (TXByteCtr)
                  {
                      UCB2TXBUF = TransmitBuffer[TransmitIndex++];
                      TXByteCtr--;
                  }
                  else
                  {
                      //Done with transmission
                      UCB2CTLW0 |= UCTXSTP;     // Send stop condition
                      MasterMode = IDLE_MODE;
                      UCB2IE &= ~UCTXIE;                       // disable TX interrupt
                      __bic_SR_register_on_exit(CPUOFF);      // Exit LPM0
                  }
                  break;
    
              default:
                  __no_operation();
                  break;
            }
            break;
        default: break;
      }
    }
    
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector = EUSCI_A3_VECTOR             // eUSCI ISR
    __interrupt void USCI_A3_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(EUSCI_A3_VECTOR))) USCI_A3_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
        switch(__even_in_range(UCA3IV, USCI_UART_UCTXCPTIFG))
        {
            case USCI_NONE: break;
            case USCI_UART_UCRXIFG:
                Rx_key=0;
                RXData[Rx_position]=UCA3RXBUF;
                if((RXData[Rx_position] == '\x0d'/*'\r'*/) || (RXData[Rx_position] ==  '\n')||(RXData[Rx_position] == '\r'))
                {
                    __bic_SR_register_on_exit(CPUOFF|GIE);
                    UCA3IE &= ~UCRXIE;
                    Rx_position=0;
                    Rx_key=0;
                    break;
                }
                Rx_position++;
                break;
            case USCI_UART_UCTXIFG:
                if(Tx_key==1)
                {
                if(Tx_position>size)
                {
    //                UCA3TXBUF = TXData[0];
                    __bic_SR_register_on_exit(CPUOFF|GIE);
                    UCA3IE &= ~UCTXIE;
                    UCA3IE &= ~UCTXCPTIE;
                    Tx_key=0;
                    break;
                }
                UCA3TXBUF = TXData[Tx_position];
                Tx_position++;
                Tx_key=0;
                }
                 break;
            case USCI_UART_UCSTTIFG: break;
            case USCI_UART_UCTXCPTIFG:
                Tx_key=1;
                UCA3IFG|=UCTXIFG;
                break;
            default: break;
        }
    }
    
    
    #if defined(__TI_COMPILER_VERSION__) || defined(__IAR_SYSTEMS_ICC__)
    #pragma vector = TIMER0_B0_VECTOR
    __interrupt void Timer0_B0_ISR(void)
    #elif defined(__GNUC__)
    void __attribute__ ((interrupt(TIMER0_B0_VECTOR))) Timer0_B0_ISR (void)
    #else
    #error Compiler not supported!
    #endif
    {
        TB0CTL &=~TB0CTL;
        __bic_SR_register_on_exit(LPM4_bits);
    }
    
    

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

    TI的建议在用户指南(SLAU367P)的Sis 1.5 / 1.6 中,但您几乎已经了解了。

    您应该小心地任意将所有引脚都降低,特别是在启动板上,其中一些引脚实际上与事物相连。 例如,如果您不卸下TXD/RXD跳线,则会由EZ-FET (USB)驱动UCA0RXD (WFP 2.1)。 (顺便说一下,您是否取出了SD卡?)

    我对ADXL器件(我没有专门使用过345)的一个常用操作是通过GPIO引脚为其供电,这为我提供了全面的电源控制。 每次关机后再开机后重新初始化的成本,但我怀疑(?) 这大大超过了30秒。

    VLOCLK的规格为+/-VCLK 50 % [Ref data sheet (SLASE54C) Table 5-7],这对某些方面很好,但在较长的时间内会有很大的不同。 如果您可以安排,晶体振荡器(LFXT)非常节约,并且允许您使用RTC (包括3.5)。

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

    嗨,Bruce,

    感谢您的建议。 是的,我正在寻找VLOCLK。我正计划使用晶体振荡器来寻找我的ACLK (正如你所说的)。到目前为止 ,我没有使用SD卡。它只是坐在那里很理想。 但只是一个好奇的问题我将SD卡保留在插槽中会发生什么情况?

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

    如果已插入SD卡,则它将从3V3导轨中馈出,并侦听针脚。 例如,如果您驾驶的是WFP 4.0 (/CS)较低,则可能会尝试做一些事情。 这将显示在例如EnergyTrace上。  

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

    嗨,Bruce,

    感谢您提供信息。