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**** 2390755 points


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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1039978/msp430fr5994-code-is-working-with-breakpoints-but-not-working-without-breakpoints

器件型号:MSP430FR5994

您好、社区

我尝试设置传感器的某些寄存器的值(I2C 从设备) 但问题是、当我使用断点运行程序时、一切都很好、但当我在没有任何断点的情况下尝试相同的操作时、它只会将值发送到传感器、但传感器中没有响应。 我将在 guys.please 下方分享我的代码、并提出您的建议

代码:

#include <msp430.h> 
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <I2C.h>
//#include <algorithm.h>


/**
 * main.c
 */

#define BMP280_ADDRESS             0X57
#define PART_ID                 0XFF
#define MEAN_FILTER_SIZE        15
//Registers

#define Mode_Register 0x06
#define MAX30100_REG_SPO2_CONFIGURATION 0x07
#define MAX30100_REG_LED_CONFIGURATION  0x09
#define MAX30100_REG_FIFO_WRITE_POINTER 0x02
#define MAX30100_REG_FIFO_READ_POINTER 0x04
#define MAX30100_REG_FIFO_DATA 0x05
#define MAX30100_INTR 0X01

//Modes

#define HR_Mode 0x02                           //HR Mode
#define Spo2_Mode 0x03                        // Spo2 Mode
#define Spo2_config 0x05
#define redLedCurrent  0x02
#define irLedCurrent  0x02
#define deviceaddr 0x57
#define Intr_enable 0x30                    //Enable Spo2 and HR ready
#define ALPHA 0.95  //dc filter alpha value


uint8_t chip_ID=0;

uint8_t mBuffer[];
uint8_t rxData=0;
uint8_t i;
uint8_t nack_received;

uint8_t rxCount;
uint8_t *rxBuffer;

uint8_t txCount;
uint8_t *txBuffer;

//Variables

uint8_t P_LED_PULSE_WIDTH=0;        //Prev values
uint8_t P_SAMPLING_RATE=0;

uint8_t Read_Pointer=1;
uint8_t Write_Pointer=1;


uint8_t i=0;
uint8_t P_Spo_2_config=0;            //Prev values of SPo2_Reg


uint8_t receive_initiated=0;
uint8_t transmit_initiated=0;

uint8_t clock_timeout=0;

uint32_t ir_Array[100];
uint32_t red_Array[100];


uint8_t Rx_Buffer[64];                          // Transfer the values between Receive inteerupt and R_read



uint32_t un_temp;
uint32_t IR;
uint32_t RED;
uint8_t led[4]={0,0,0,0};
uint8_t RxByteCtr;



int32_t n_spo2;  //SPO2 value
int8_t h_spo2_valid;  //indicator to show if the SPO2 calculation is valid
int32_t n_heart_rate; //heart rate value
int8_t  ch_hr_valid;  //indicator to show if the heart rate calculation is valid
uint8_t uch_dummy;


//--------------------------------------------------------------------------------|
//                          Filters                                               |
//--------------------------------------------------------------------------------|
float meanDiffResIR=0;

struct dcFilter_t {
  float w;
  float result;
};

//struct butterworthFilter_t
//{
//  float v[2];
//  float result;
//};

struct meanDiffFilter_t
{
  float values[MEAN_FILTER_SIZE];
  uint8_t index;
  float sum;
  uint8_t count;
};

struct butterworthFilter_t
{
  float v[2];
  float result;
};

struct result1
{
    uint8_t IR;
    uint8_t RED;
};

struct dcFilter_t dcFilterIR = {0,0};

struct dcFilter_t dcFilterRed = {0,0};

struct meanDiffFilter_t meanDiffIR={0,0,0};

struct result1 result1={0,0};

void intialize()
{
    //Configure GPIO
       P1OUT &= ~BIT0;
       P1DIR |=BIT0;

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

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

       P7DIR  &= ~(BIT0 | BIT1);

       PM5CTL0 &= ~LOCKLPM5;        //Disable GPIO power-on high impedance mode
       __delay_cycles(50);
       __bis_SR_register(GIE);

}

void i2cConfig()
{
    UCB2CTLW0 = UCSWRST;        // Reset I2C interface for config

    UCB2CTLW0 =                 /* USCI - B2 configuration register */
                    UCMST         | // Master mode
                    UCSYNC        | // Synchronous mode
                    UCMODE_3      | // I2C mode
                    UCSSEL__SMCLK | // Select SMCLK
                    UCTR          | // Transmitter mode
                    UCSWRST       | // Don't release reset (yet)
                    0;

        UCB2CTLW1 =
                    UCCLTO_1      | // Clock low time-out select (28ms)
                    UCASTP_2      | // Automatic STOP condition generation (enabled)
                    UCGLIT_0      | // Deglitch time (50ns)
                    0;

        UCB2BRW = 10;               // Bit clock divider 1M/10 = 100kHz

        UCB2CTLW0 &= ~UCSWRST;      // Clear reset bit to start operation

        UCB2IE = UCNACKIE         | // Enable Nack interrupt
                 UCTXIE           | // Enable TX interrupt
                 UCRXIE           | // Enable RX interrupt
                 UCCLTOIE         | // Enable clock low time-out interrupt
                 0;
}

uint8_t read(uint8_t reg)
{
    i2c_start(BMP280_ADDRESS,WRITE);
    i2c_write(reg);
    i2c_repeated_start(BMP280_ADDRESS,READ);
    i2c_read(led,2);
    chip_ID=led[1];
    return chip_ID;
}

void write(uint8_t reg,uint8_t data)
{
    i2c_start(BMP280_ADDRESS,WRITE);
    i2c_write(reg);
    i2c_write(data);
    STOP_I2C;
}

void set_mode()
{
//        uint8_t temp=read(0x06);
//        temp = temp & 0x00;
//        temp = temp|mode;
//        write(0x06,0x02); // Mode_Reg, HR_MODE
//        i2c_stop();
//        write(0x06,0x00); // Mode_Reg, HR_MODE
//        write(0x06,0x02); // Mode_Reg, HR_MODE
//
    i2c_start(BMP280_ADDRESS,WRITE);
    i2c_write(0x06);
    i2c_write(0x03); // Mode_Reg, HR_MODE
    __delay_cycles(5);
    i2c_stop ();
    chip_ID=read(0x06);
}

void spo2_config()
{
    uint8_t P_Spo_2_config = read(MAX30100_REG_SPO2_CONFIGURATION);
    write(MAX30100_REG_SPO2_CONFIGURATION, (P_Spo_2_config & 0x00) | Spo2_config);
    i2c_stop();
    chip_ID=read(MAX30100_REG_SPO2_CONFIGURATION);
}

void LED_CURRENT()
{
  write(MAX30100_REG_LED_CONFIGURATION, redLedCurrent << 4 | irLedCurrent);
  i2c_stop();
}


uint8_t init_device()
{
    chip_ID=read(0xFF);
    if(chip_ID==17)
    {
        return 0;
    }
    else
    {
        return 1;
    }
}



//-----------------------------------------------------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------------------------------------------------------


//-----------------------------------------------------------------------------------------------------------------------------------------------------------|
//                                                      FILTERS                                                                                                                                                           |
//-----------------------------------------------------------------------------------------------------------------------------------------------------------|

int main(void)
{
    WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer
    intialize();
    i2cConfig();
    initI2C();
    while(init_device())
    {
        printf("Couldn't able to establish I2C connection with MAX30100");
    }

    set_mode();
    spo2_config();
    LED_CURRENT();

}

I2C 头文件

/*
 * i2c.h
 *
 *  Created on: 7 Dec 2020
 *      Author: forat
 */

#ifndef I2C_H_
#define I2C_H_
#include <stdint.h>

#define READ        0
#define WRITE       1

#define STOP_I2C        (UCB2CTLW0 |= UCTXSTP)

void initI2C (void);

void i2c_start (uint8_t,unsigned int);

void i2c_stop (void);

void i2c_repeated_start(uint8_t,unsigned int);

void i2c_write (uint8_t);//write data or reg_address

void i2c_read (uint8_t*,unsigned int);

#endif /* I2C_H_ */

I2c.c

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

#include "i2c.h"




void initI2C()
{
    //config P1.6 SDA P1.7 SCL
    UCB2CTLW0 &=0x00;
    UCB2CTLW1 &=0x00;
    UCB2TBCNT =0x00;

    P1SEL1 &= ~ (BIT6 | BIT7);
    P1SEL0 |= (BIT6 | BIT7);

    UCB2CTLW0 = UCSWRST;                      // Enable SW reset
    UCB2CTLW0 |= UCMODE_3 | UCMST | UCSSEL__SMCLK | UCSYNC; // I2C master mode, SMCLK
    UCB2BRW = 20;//3;//10;                            // fSCL = SMCLK/10 = ~100kHz
    //UCB2I2CSA = SLAVE_ADDR;                   // Slave Address
    UCB2CTLW0 &= ~UCSWRST;                    // Clear SW reset, resume operation
    UCB2IE |= UCNACKIE;//enable NACK ISR (TX and RX?)
    UCB2IE &=  ~UCTXIE;
    UCB2IE &=  ~UCRXIE;
    UCB2IE &=  ~UCCLTOIE;
}

void i2c_start (uint8_t dev_addr,unsigned int RW)
{
    while(UCB2STAT & UCBBUSY);//check if SDA and SCL are idle

    UCB2I2CSA = dev_addr;

    if(RW == READ){UCB2CTLW0 &= ~UCTR;}
    else{UCB2CTLW0 |= UCTR;}

    UCB2CTLW0 |= UCTXSTT;

    while (UCB2CTLW0 & UCTXSTT);//wait till the whole address has been sent and ACK'ed
}

void i2c_stop (void)
{
    UCB2CTLW0 |= UCTXSTP;//stop
    while(UCB2CTLW0 & UCTXSTP);//wait for a stop to happen
}

void i2c_repeated_start(uint8_t dev_addr, unsigned int RW)
{
    UCB2I2CSA = dev_addr;

    if(RW == READ){UCB2CTLW0 &= ~UCTR;}
    else{UCB2CTLW0 |= UCTR;}

    UCB2CTLW0 |= UCTXSTT;

    while (UCB2CTLW0 & UCTXSTT);//wait till the whole address has been sent and ACK'ed
}

void i2c_write (uint8_t data)
{
    UCB2TXBUF = data;
    while(UCB2CTLW0 & UCTXIFG0);//1 means data is sent completely
}

void i2c_read (uint8_t * led,unsigned int RxByteCtr)
{
    int i = 0;
    for(i = 0; i < RxByteCtr;i++)
    {
        while(!(UCB2IFG & UCRXIFG0));//make sure rx buffer got data

        if(i == RxByteCtr - 1)
            STOP_I2C;

        led[i] = UCB2RXBUF;
    }

    while(UCB2CTLW0 & UCTXSTP);//wait for a stop to happen
}



你们可以离开过滤器。我没有使用它们。

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

    您是否可以使用振荡器捕捉波形? 我认为通信速度可能太快、传感器无法快速响应。

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

    周您好、

    我曾尝试过延迟、但仍然无法正常工作。

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

    您能否测试波形?它可以判断发生了什么

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

    您能否解释一下测试波是什么意思?

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

    断点在哪里? 类似的症状表明、在 EUSCI 准备就绪之前、您正在进行某种操作。

    这一点、例如、突出:

    UCB2TXBUF = data;
    while(UCB2CTLW0 & UCTXIFG0);//1 means data is sent completely

    这可能应该被写入

    while(!(UCB2IFG & UCTXIFG0));//1 means data can be sent
    UCB2TXBUF = data;


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

    我也尝试过这种方法、但我无法看到这些值。

    在调试时(逐行执行)、我可以看到这些值。 请帮助我解决这些问题。

    谢谢

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

    我没有您的设备、所以我只能做检查。  

    一种可能是您过早发布重复启动。 在请求 UCTXIFG0之前、请尝试等待(第二个) UCTXIFG0。

    如果您有示波器、在这种情况下、示波器通常很方便。 此外、将您的序列与 TI 示例套件中的序列进行比较可能很有用。

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

    Bruce、您好!  

    我已经介绍了您的一些 MSP430示例、我已经用很好的方式更改了我的代码。 我在这里附上了代码。 但在这里、我也遇到了相同的问题。 我在这里附上了我的新代码、请仔细阅读并告诉我您的建议

    //******************************************************************************
    //   MSP430FR599x Demo - eUSCI_B2, I2C Master multiple byte TX/RX
    //
    //   Description: I2C master communicates to I2C slave sending and receiving
    //   3 different messages of different length. I2C master will enter LPM0 mode
    //   while waiting for the messages to be sent/receiving using I2C interrupt.
    //   ACLK = NA, MCLK = SMCLK = DCO 16MHz.
    //
    //                                     /|\ /|\
    //                   MSP430FR5994      4.7k |
    //                 -----------------    |  4.7k
    //            /|\ |             P7.1|---+---|-- I2C Clock (UCB2SCL)
    //             |  |                 |       |
    //             ---|RST          P7.0|-------+-- I2C Data (UCB2SDA)
    //                |                 |
    //                |                 |
    //                |                 |
    //                |                 |
    //                |                 |
    //                |                 |
    //
    //   Nima Eskandari and Ryan Meredith
    //   Texas Instruments Inc.
    //   January 2018
    //   Built with CCS V7.3
    //******************************************************************************
    
    #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
    
    //******************************************************************************
    // Example Commands ************************************************************
    //******************************************************************************
    
    #define SLAVE_ADDR  0x53
    
    /* CMD_TYPE_X_SLAVE are example commands the master sends to the slave.
     * The slave will send example SlaveTypeX buffers in response.
     *
     * CMD_TYPE_X_MASTER are example commands the master sends to the slave.
     * The slave will initialize itself to receive MasterTypeX example buffers.
     * */
    
    #define CMD_TYPE_0_SLAVE      0x00
    #define CMD_TYPE_1_SLAVE      1
    #define CMD_TYPE_2_SLAVE      2
    
    #define Power_CTL             0x2D
    #define Data_Rate             0x2C
    #define Data_Format           0x31
    
    #define X0_Reg                0x32
    #define X1_Reg                0x33
    #define Y0_Reg                0x34
    #define Y1_Reg                0x35
    #define Z0_Reg                0x36
    #define Z1_Reg                0x37
    
    
    #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};
    
    //******************************************************************************
    // General I2C State Machine ***************************************************
    //******************************************************************************
    
    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;
    
    
    /* 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;
    
    int16_t xf=0;
    int16_t yf=0;
    int16_t zf=0;
    
    uint8_t Data_rate=0;
    uint8_t Data_Res =0;
    uint8_t Dev_ID   =0;
    
    
    
    /* I2C Write and Read Functions */
    
    /* For slave device with dev_addr, writes the data specified in *reg_data
     *
     * dev_addr: The slave device address.
     *           Example: SLAVE_ADDR
     * reg_addr: The register or command to send to the slave.
     *           Example: CMD_TYPE_0_MASTER
     * *reg_data: The buffer to write
     *           Example: MasterType0
     * count: The length of *reg_data
     *           Example: TYPE_0_LENGTH
     *  */
    I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint8_t reg_addr, uint8_t *reg_data, uint8_t count);
    
    /* For slave device with dev_addr, read the data specified in slaves reg_addr.
     * The received data is available in ReceiveBuffer
     *
     * dev_addr: The slave device address.
     *           Example: SLAVE_ADDR
     * reg_addr: The register or command to send to the slave.
     *           Example: CMD_TYPE_0_SLAVE
     * count: The length of data to read
     *           Example: TYPE_0_LENGTH
     *  */
    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);
    
    
    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
        __bis_SR_register(LPM0_bits + GIE);           // 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 initGPIO()
    {
        // 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()
    {
        UCB2CTLW0 = UCSWRST;                      // Enable SW reset
        UCB2CTLW0 |= UCMODE_3 | UCMST | UCSSEL__SMCLK | UCSYNC; // I2C master mode, SMCLK
        UCB2BRW = 1600;                            // fSCL = SMCLK/160 = ~100kHz
        UCB2I2CSA = SLAVE_ADDR;                   // Slave Address
        UCB2CTLW0 &= ~UCSWRST;                    // Clear SW reset, resume operation
        UCB2IE |= UCNACKIE;
    }
    
    
    //******************************************************************************
    // Main ************************************************************************
    // Send and receive three messages containing the example commands *************
    //******************************************************************************
    
    int main(void) {
        WDTCTL = WDTPW | WDTHOLD;   // Stop watchdog timer
        initClockTo16MHz();
        initGPIO();
        initI2C();
    
    
       I2C_Master_ReadReg(SLAVE_ADDR, CMD_TYPE_0_SLAVE, TYPE_0_LENGTH);
       CopyArray(ReceiveBuffer, SlaveType0, TYPE_0_LENGTH);
       Dev_ID=ReceiveBuffer[0];
       __delay_cycles(10);
    
        I2C_Master_WriteReg(SLAVE_ADDR, Power_CTL, MasterType0, TYPE_0_LENGTH);
        __delay_cycles(10);
    //
        I2C_Master_WriteReg(SLAVE_ADDR, Data_Rate, MasterType3, TYPE_0_LENGTH);
        __delay_cycles(10);
    //
        I2C_Master_WriteReg(SLAVE_ADDR, Data_Format, MasterType4, TYPE_0_LENGTH);
        __delay_cycles(10);
    //
    //    I2C_Master_ReadReg(SLAVE_ADDR, Data_Rate, TYPE_0_LENGTH);
    //    CopyArray(ReceiveBuffer, SlaveType0, TYPE_0_LENGTH);
    //    Data_rate=ReceiveBuffer[0];
    //
    //    __delay_cycles(10);
    //
    //    I2C_Master_ReadReg(SLAVE_ADDR, Data_Format, TYPE_0_LENGTH);
    //    CopyArray(ReceiveBuffer, SlaveType0, TYPE_0_LENGTH);
    //    Data_Res=ReceiveBuffer[0];
    //
    //    __delay_cycles(10);
    //
    //    I2C_Master_ReadReg(SLAVE_ADDR, X0_Reg, TYPE_1_LENGTH);
    //    CopyArray(ReceiveBuffer, SlaveType0, TYPE_1_LENGTH);
    //    uint8_t x0 = ReceiveBuffer[0];
    //    __delay_cycles(10);
    //
    //    I2C_Master_ReadReg(SLAVE_ADDR, X1_Reg, TYPE_0_LENGTH);
    //    CopyArray(ReceiveBuffer, SlaveType0, TYPE_0_LENGTH);
    //    uint8_t x1 = ReceiveBuffer[0];
    //    __delay_cycles(10);
    //
    //    x1=x1&0x03;
    //    uint16_t x = (x1 << 8) + x0;
    //    xf = x;
    //    if(xf > 511)
    //    {
    //     xf = xf - 1024;
    //    }
    //
    //    I2C_Master_ReadReg(SLAVE_ADDR, Z0_Reg, TYPE_0_LENGTH);
    //    CopyArray(ReceiveBuffer, SlaveType0, TYPE_0_LENGTH);
    //    uint8_t z0 = ReceiveBuffer[0];
    //    __delay_cycles(10);
    //
    //    I2C_Master_ReadReg(SLAVE_ADDR, Z1_Reg, TYPE_0_LENGTH);
    //    CopyArray(ReceiveBuffer, SlaveType0, TYPE_0_LENGTH);
    //    uint8_t z1 = ReceiveBuffer[0];
    //    __delay_cycles(10);
    //
    //    z1=z1&0x03;
    //    uint16_t z = (z1 << 8) + z0;
    //    zf = z;
    //    if(zf > 511)
    //    {
    //     zf = zf - 1024;
    //    }
    //
    //    I2C_Master_ReadReg(SLAVE_ADDR, Y0_Reg, TYPE_0_LENGTH);
    //    CopyArray(ReceiveBuffer, SlaveType0, TYPE_0_LENGTH);
    //    uint8_t y0 = ReceiveBuffer[0];
    //    __delay_cycles(10);
    //
    //    I2C_Master_ReadReg(SLAVE_ADDR, Y1_Reg, TYPE_0_LENGTH);
    //    CopyArray(ReceiveBuffer, SlaveType0, TYPE_0_LENGTH);
    //    uint8_t y1 = ReceiveBuffer[0];
    //    __delay_cycles(10);
    //
    //    y1=y1&0x03;
    //    uint16_t y = (y1 << 8) + y0;
    //    yf = y;
    //    if(yf > 511)
    //    {
    //     yf = yf - 1024;
    //    }
    
    
    //    I2C_Master_ReadReg(SLAVE_ADDR, CMD_TYPE_0_SLAVE, TYPE_0_LENGTH);
    //    CopyArray(ReceiveBuffer, SlaveType0, TYPE_0_LENGTH);
    //
    //    I2C_Master_WriteReg(SLAVE_ADDR, CMD_TYPE_0_MASTER, MasterType0, TYPE_0_LENGTH);
    //    I2C_Master_WriteReg(SLAVE_ADDR, CMD_TYPE_1_MASTER, MasterType1, TYPE_1_LENGTH);
    //    I2C_Master_WriteReg(SLAVE_ADDR, CMD_TYPE_2_MASTER, MasterType2, TYPE_2_LENGTH);
    //
    //    I2C_Master_ReadReg(SLAVE_ADDR, CMD_TYPE_0_SLAVE, TYPE_0_LENGTH);
    //    CopyArray(ReceiveBuffer, SlaveType0, TYPE_0_LENGTH);
    //
    //    I2C_Master_ReadReg(SLAVE_ADDR, CMD_TYPE_1_SLAVE, TYPE_1_LENGTH);
    //    CopyArray(ReceiveBuffer, SlaveType1, TYPE_1_LENGTH);
    //
    //    I2C_Master_ReadReg(SLAVE_ADDR, CMD_TYPE_2_SLAVE, TYPE_2_LENGTH);
    //    CopyArray(ReceiveBuffer, SlaveType2, TYPE_2_LENGTH);
    
        __bis_SR_register(LPM0_bits + GIE);
        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;
      }
    }
    
    
     

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

    嗨、大家好、

    我想我已经了解了问题的位置。 在我的读取和写入函数上、我都设置了 LPM0位。 CPU 将关闭、直到出现任何中断。 一旦发生相应的中断(Tx 或 Rx)、我 将使用以下命令退出该模式:   

    BIC_SR_REGISTER_ON_EXIT (CPUOFF);

    但是、即使在执行上述命令后、我也无法退出低功耗模式的问题。 因此、我感觉退出低功耗模式的方式存在一些问题。 因此、请大家放弃您对此问题的建议。

    注:我使用的是上述相同的代码

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

    您如何判断它不会退出 LPM? 断点? 外部可见行为? 它在第一个交易或后续交易中失败了吗?

    我在这里没有 ADXL345、因此我在 P7.0/1上启用了内部脉冲、并得到了一个(预期) NACK。 当我向 NACK 情况添加唤醒时、它会正常唤醒(断点)。

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

    我一步一步运行代码,我看到第一个函数完成后,它 一直停留在同一行中,而不是前进到 main()函数中的第二个函数

    行:_bis_SR_register (CPUOFF + GIE)

    新问题:有时 Tx 中断也不会被触发

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

    您是否了解了 ISR? 请尝试在 CPUOFF 设置之后的"return"上设置断点、而不是单步执行。  

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

    现在我不会进入 ISR 本身、设置 UCTXSTT 位后、不会触发发送中断。

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

    不获得初始 TXIFG 通常意味着从器件将 SCL (或 SDA)保持在低电平("永久")。 这在调试时并不少见、因为在事务处理过程中很难自行复位主器件(MCU)。

    ADXL345没有复位引脚、因此要修复它、您需要对其进行下电上电(可能是对整个系统进行下电上电)。

    ------

    未经请求:ADXL345可在140uA 的电流下运行、因此可以使用 GPIO (<2mA)为其供电。 这样做将允许您在程序控制下重置它。