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.

[参考译文] MSP430FR6889:睡眠模式期间 MSP430的低功耗。

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1381023/msp430fr6889-low-power-consumption-of-msp430-during-sleep-modes

器件型号:MSP430FR6889
Thread 中讨论的其他器件: ENERGYTRACE

工具与软件:

你好!  

Im:在 我的项目中使用 MSP430FR6889评估板(MSP-EXP430FR6889)。 我正在尝试在低功耗模式(LPM3或 LMP4)下操作 MSP430、但在验证电流消耗时遇到问题、因为我不确定应该从何处连接电流表。  
我可以在数据表中看到、电流消耗也可以达到5微安、但到目前为止我无法核实。  


Im 尝试将加速计与 MSP430结合使用、移动时 MSP320应唤醒并读取加速计。 代码可在下面找到。  

#include "driverlib.h"
#include <gpio.h>
#include <msp430fr5xx_6xxgeneric.h>
#include <stdint.h>
#include <stdio.h>
#include <math.h>
#include <dsplib.h>

// Address of the BMI160
#define SLAVE_ADDR 0x69
#define MAX_BUFFER_SIZE 20
#define SAMPLES 128
#define SAMPLE_RATE 100.0 // Sample rate in Hz based on BMI160 configuration

volatile uint8_t tap_detected = 0; // Flag to track if a tap has been detected
int16_t input[SAMPLES] = {0}; // Store samples
void initI2C() {
    UCB1CTLW0 = UCSWRST;                      // Enable SW reset
    UCB1CTLW0 |= UCMODE_3 | UCMST | UCSSEL__SMCLK | UCSYNC; // I2C master mode, SMCLK
    UCB1BRW = 160;                            // fSCL = SMCLK/160 = ~100kHz
    UCB1I2CSA = SLAVE_ADDR;                   // Slave Address
    UCB1CTLW0 &= ~UCSWRST;                    // Clear SW reset, resume operation
}

void I2C_Master_WriteReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t *data, uint8_t count) {
    // Send start condition
    UCB1CTLW0 |= UCTR | UCTXSTT;
    while (!(UCB1IFG & UCTXIFG)); // Wait for TX buffer to be ready

    // Send device address with write flag
    UCB1TXBUF = dev_addr << 1; // Address with write bit
    while (!(UCB1IFG & UCTXIFG)); // Wait for TX buffer to be ready

    // Send register address
    UCB1TXBUF = reg_addr;
    while (!(UCB1IFG & UCTXIFG)); // Wait for TX buffer to be ready

    // Send data
    for (int i = 0; i < count; i++) {
        UCB1TXBUF = data[i];
        while (!(UCB1IFG & UCTXIFG)); // Wait for TX buffer to be ready
    }

    // Send stop condition
    UCB1CTLW0 |= UCTXSTP;
    while (UCB1CTLW0 & UCTXSTP); // Wait for stop condition
}

void I2C_Master_ReadReg(uint8_t dev_addr, uint8_t *data, uint8_t count) {
    // Send repeated start and switch to receive mode
    UCB1CTLW0 &= ~UCTR;
    UCB1CTLW0 |= UCTXSTT;
    while (UCB1CTLW0 & UCTXSTT);

    // Receive data
    for (int i = 0; i < count; i++) {
        while (!(UCB1IFG & UCRXIFG0));
        data[i] = UCB1RXBUF;
    }

    // Send stop condition
    UCB1CTLW0 |= UCTXSTP;
    while (UCB1CTLW0 & UCTXSTP);
}

void initGPIO() {
    // I2C pins (P4.0 is SDA, P4.1 is SCL)
    P4SEL1 |= BIT0 | BIT1;
    P4SEL0 &= ~(BIT0 | BIT1);
    // Configure INT1 pin (P3.2) as input
    P3DIR &= ~BIT2;
    P3IES &= ~BIT2; // Interrupt on rising edge
    P3IFG &= ~BIT2; // Clear interrupt flag
    P3IE |= BIT2;   // Enable interrupt

    PM5CTL0 &= ~LOCKLPM5; // Disable the GPIO power-on default high-impedance mode
}

void init_BMI160_ACC() {
    uint8_t writeData[2];

    // Soft reset BMI160
    writeData[0] = 0xB6;
    I2C_Master_WriteReg(SLAVE_ADDR, 0x7E, writeData, 1);
    __delay_cycles(55000); // Delay 55ms for BMI160 to stabilize

    // Set accelerometer to LPM mode
    writeData[0] = 0x12;
    I2C_Master_WriteReg(SLAVE_ADDR, 0x7E, writeData, 1);
    __delay_cycles(5000); // Delay 5ms for accelerometer to stabilize

    // Set ODR to 100Hz with no average
    writeData[0] = 0x86;
    I2C_Master_WriteReg(SLAVE_ADDR, 0x40, writeData, 1);

    // Set both INT1 and INT2 pins as output, active-high, push-pull
    writeData[0] = 0x0A;
    I2C_Master_WriteReg(SLAVE_ADDR, 0x53, writeData, 1);

    // Temporarily latch the interrupt for 80ms
    writeData[0] = 0x09;
    I2C_Master_WriteReg(SLAVE_ADDR, 0x54, writeData, 1);

    // Route single-tap interrupt to INT1 pin
    writeData[0] = 0x04;
    I2C_Master_WriteReg(SLAVE_ADDR, 0x55, writeData, 1);

    // Configure tap sensing
    writeData[0] = 0x14; // Default values
    I2C_Master_WriteReg(SLAVE_ADDR, 0x60, writeData, 1);

    writeData[0] = 0x00; // Default threshold value
    I2C_Master_WriteReg(SLAVE_ADDR, 0x5F, writeData, 1);

    // Enable single-tap and double-tap interrupt
    writeData[0] = 0x07;
    I2C_Master_WriteReg(SLAVE_ADDR, 0x50, writeData, 1);
}

#pragma vector=PORT3_VECTOR
__interrupt void Port_3(void) {
    if (P3IFG & BIT2) {
        P3IFG &= ~BIT2; // Clear the interrupt flag for INT1
        if (!tap_detected) {
            tap_detected = 1;
            printf("Single-tap detected!\n");
            __bic_SR_register_on_exit(LPM4_bits); // Exit LPM4 on ISR exit
        }
    }
}


const float G_SENSITIVITY = 0.061; // Sensitivity in mg per LSB for the accelerometer

void process() {
    for (int i = 0; i < SAMPLES; i++) {
        uint8_t reg_data[2] = {0};
        uint8_t reg_addr = 0x17; // Register address for the Z-axis data (low byte)
        // Write register address
        I2C_Master_WriteReg(SLAVE_ADDR, reg_addr, NULL, 0);
        // Read data
        I2C_Master_ReadReg(SLAVE_ADDR, reg_data, 2);

        // Interpret the received data (Z-axis)
        int16_t raw_data = (int16_t)((reg_data[1] << 8) | reg_data[0]);
        input[i] = raw_data;
        printf("%d,", raw_data);


        // Convert raw data to G
        float acceleration_mg = raw_data * G_SENSITIVITY; // Acceleration in mg
        float acceleration_g = acceleration_mg / 1000.0; // Convert mg to g
        //input[i] = acceleration_g;
        //printf("%.4f,", acceleration_g);
    }
}


int main(void) {
    WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer
    initGPIO();
    initI2C();
    init_BMI160_ACC();

    __enable_interrupt(); // Enable global interrupts
    while (1) {
        __bis_SR_register(LPM4_bits + GIE); // Enter LPM4 with interrupts enabled
        process(); // Process data after waking up
        tap_detected = 0; // Reset the tap detected flag
    }

    return 0;
}

到目前为止、我的代码运行良好、但 我不知道如何验证电流消耗。  

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

    我希望您可以将电流表连接到 J101 ("桥接")接头上的3V 跳线两端。

    电流表可能无法为您提供所需的详细信息。 为此、我建议在 CCS 中使用 EnergyTrace 功能。