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**** 2386930 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/1172339/msp430fr5994-interfacing-issue

器件型号:MSP430FR5994

你(们)好

我试图将 ADXL345加速计数据存储并检索到 AT24C256 EEPROM 中。但当我运行程序时、输出上会打印一些垃圾值。 加速计输出未存储到 EEPROM 中。我正在共享这段代码、请帮我。

///////////////////  main.c  /////////////////

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


    LPM1_Clock_config();
    // I2C pins
    P7SEL0 |= BIT0 | BIT1;
    P7SEL1 &= ~(BIT0 | BIT1);
    PM5CTL0 &= ~LOCKLPM5;
    // i2c Configuration
    initI2C();
    uart_config();
    power_ctrl();
    while (1)
    {

        int ADXL345_Dev_id, res_data,bw_data,data_format,count;
        I2C_Master_ReadReg(0x53,0x32,6);
        X1=((ReceiveBuffer[1]<<8)|ReceiveBuffer[0]);
        Y1=((ReceiveBuffer[3]<<8)|ReceiveBuffer[2]);
        Z1=((ReceiveBuffer[5]<<8)|ReceiveBuffer[4]);
        memset(addr,0,sizeof(addr));
        sprintf(addr,"X1=%d,Y1=%d,Z1=%d\r\n",X1,Y1,Z1);
        count=strlen(addr);
       // id_print(addr);
      //  if(count<=5)
        //{
        I2C_Master_WriteReg(0x50,0x00,addr,count);
        //count++;
        //}
        __delay_cycles(8000000);
        I2C_Master_ReadReg(0x50,0x00,count);
        for(i=0;i<=count;i++)
        {
        X[i]=ReceiveBuffer[i];
        }
       // i= atoi(X);
        // printf("%s\r\n",i);
        //sprintf(addr1,"x=%d,y=%d,z=%d\r\n",i);
        sprintf(addr1,"x=%d,y=%d,z=%d\r\n",X);
        id_print(addr1);

        UCA0IE &= ~UCTXIE;
        UCA0IE &= ~UCTXCPTIE;
        __delay_cycles(8000000);
    }
    return 0;
}


////////////////  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

//******************************************************************************
// Example Commands ************************************************************
//******************************************************************************

#define SLAVE_ADDR  0x50

/* 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      0
#define CMD_TYPE_1_SLAVE      1
#define CMD_TYPE_2_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

volatile int Rx_index=0;
volatile unsigned int Rx_key=0;
volatile int Tx_index=0;
volatile unsigned int Tx_key=0;
int size=0;
unsigned char Data[15]="";
unsigned char RXData[5]="";
//uint8_t address1;
//uint8_t address2;
/* 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] = { 11};


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_LSB_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;
uint8_t TransmitRegAddr_1 = 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 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, uint16_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)//0x53,0,1
{

    /* Initialize state machine */
    MasterMode = TX_REG_ADDRESS_MODE;
   // address1=dev_addr;
    if(dev_addr==0x53)
          {
           TransmitRegAddr = reg_addr;
          }
    else
          {
           TransmitRegAddr = (reg_addr >> 8);//MSB
           TransmitRegAddr_1 = (reg_addr & 0xFF); // LSB
          }
    RXByteCtr = count;//1
    TXByteCtr = 0;
    ReceiveIndex = 0;
    TransmitIndex = 0;
    /* Initialize slave address and interrupts */
    UCB2I2CSA = dev_addr;//0X53
    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();
    //for(i=0;i<1000;i++);
    __bis_SR_register(LPM0_bits);            // Enter LPM0 w/ interrupts

    return MasterMode;
}


I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint16_t reg_addr, uint8_t *reg_data, uint8_t count)
{
    /* Initialize state machine */
    MasterMode = TX_REG_ADDRESS_MODE;
    //TransmitRegAddr = reg_addr;//0X32
    //address2=dev_addr;
    if(dev_addr==0x53)
       {
        TransmitRegAddr = reg_addr;
       }
    else
       {
        TransmitRegAddr = (reg_addr >> 8);//MSB
        TransmitRegAddr_1 = (reg_addr & 0xFF); // LSB
        }
    //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];
    }
}


//******************************************************************************
// 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:
              if(TransmitRegAddr==0x50)
              {
                 UCB2TXBUF = TransmitRegAddr;   //0X32 MSB
                 MasterMode = TX_LSB_MODE;
              }
              else
              {
                 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 TX_LSB_MODE:
              UCB2TXBUF = TransmitRegAddr_1; //LSB
              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++];  // data=9
                 // UCB2CTLW0 |= UCTXSTP;
                  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;
  }
}

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

    > sprintf (addr1、"x=%d、y=%d、z=%d\r\n"、X);

    不能将 sprintf()与这样的数组一起使用。 一种可能的选择:

    > sprintf (addr1、"x=%d、y=%d、z=%d\r\n"、X[0]、X[1]、X[2]);

    ------

    您的 X[]数组是如何声明的? 您使用"count"写入它、这是 strlen()的结果、因此可能大于您的想象。

    ------

    我看不到任何写入 EEPROM 的代码。

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

    在使用 sprintf()之前,无需 memset()。 sprintf 将附加后缀'\0'。

    您确定 addr 和 addr1足够大以容纳您的字符串吗?

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

    你好 Bruce

    1) 1)我已按照您的建议更改了 sprintf 语句。 我将数组声明为 unsigned char X[20];但仍有一些值正在获取、这些值将连续重复。

    2) 2)我认为写入函数不 是先发生的。  

    3)我不确定的是,首先我将加速计值的字符串(addr)传递给 EEPROM。 例如、假设值为 X1=10、Y1=-40、Z=120。我将这些值作为字符串传递、因此每个数字将在 EEPROM 中以1字节的形式存储在每个地址位置。 因此、EEPROM 总共消耗9个位置、包括 NULL。 但是、在检索 相同的数据时、我们如何检索到与 X=10、Y=-40、Z=120相同的数据。 或者、如果我们使用存储整数、则可以轻松存储第一个值、但存储下一个 X、Y、Z 值也会变得很困难。 那么、您能不能建议我在天气好的情况下解决这个问题?

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

    由你决定。 我认为以整数进行存储会更好,但 atoi()可以将以 null 结尾的字符串转换为整数。

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

    您好 Keith

    即使我认为是相同的、并尝试了相应的方法、但输出没有变化。 首先、我认为数据不会存储在 EEPROM 中。

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

    我建议您后退一步。

    编写一个仅存储 EEPROM 数据并从中检索数据的程序。

    编写一个只获取加速计数据的程序

    根据需要将两者合并。

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

    > 案例 TX_REG_ADDRESS_MODE:
    >IF (TransmitRegAddr=0x50)

    我怀疑这种比较应该与 DEV_addr 而不是 TransmitRegAddr 进行。 数据表(doc0670)并未说明如果您仅发送一个地址字节会发生什么情况;可能会忽略该字节、这会导致您的读取在 EEPROM 中的字符串末尾开始。

     您在 UART 输出中看到了哪些值? %c 格式可能更合适。 如果在 main 的战略点断点(i2c 例程中的断点可能很棘手)、您可以看到实际使用的数据。

    [编辑:更正了拼写错误。]

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

    您好 Keith

    是的、我已经将加速计和 EEPROM 单独连接到 MSP430FR5994。 我可以在 EEPROM 上写入和读取1个整数值。确认后、我已开始合并这两 个整数值。但正如您所说、我尝试将3个整数值写入 EEPROM、但数据未写入 EEPROM。我正在共享这里的代码段、请帮我。

    /////////////////////  main.c  ///////////////////
    
    #include <msp430.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdint.h>
    #include <stdlib.h>
    #include <i2c.h>
    uint16_t X1;
    uint16_t Y1;
    uint16_t Z1;
    //uint16_t X=Y=Z=0;
    float f=0.004;
    int device_address= 0x50;
    char addr[30]="";
    char device_id[6]="";
    char string[10]="started";
    uint8_t num[5]={27};
    uint8_t x=10;
    uint8_t y=20;
    uint8_t z=30;
    
    int main(void)
    {
        WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer
    
    
        LPM1_Clock_config();
        // I2C pins
        P7SEL0 |= BIT0 | BIT1;
        P7SEL1 &= ~(BIT0 | BIT1);
        PM5CTL0 &= ~LOCKLPM5;
        // i2c Configuration
        initI2C();
        uart_config();
        while (1)
        {
            printf("started\r\n");
            I2C_Master_WriteReg(0x50,0x00,x,1);
            I2C_Master_WriteReg(0x50,0x01,y,1);
            I2C_Master_WriteReg(0x50,0x02,z,1);
            __delay_cycles(8000000);
            I2C_Master_ReadReg(0x50,0x00,1);
            X1=ReceiveBuffer[0];
            I2C_Master_ReadReg(0x50,0x01,1);
            Y1=ReceiveBuffer[0];
            I2C_Master_ReadReg(0x50,0x02,1);
            Z1=ReceiveBuffer[0];
            sprintf(addr,"X=%d,Y=%d,Z=%d\r\n",X1,Y1,Z1);
            id_print(addr);
            UCA0IE &= ~UCTXIE;
            UCA0IE &= ~UCTXCPTIE;
            __delay_cycles(1000000);
        }
    }
    
    
    
    /////////////////// 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
    
    //******************************************************************************
    // Example Commands ************************************************************
    //******************************************************************************
    
    #define SLAVE_ADDR  0x50
    
    /* 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      0
    #define CMD_TYPE_1_SLAVE      1
    #define CMD_TYPE_2_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
    
    volatile int Rx_index=0;
    volatile unsigned int Rx_key=0;
    volatile int Tx_index=0;
    volatile unsigned int Tx_key=0;
    int size=0;
    char Data[15]="";
    char RXData[5]="";
    
    /* 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] = { 11};
    
    
    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_LSB_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;
    uint8_t TransmitRegAddr_1 = 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 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, uint16_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)//0x53,0,1
    {
    
        /* Initialize state machine */
        MasterMode = TX_REG_ADDRESS_MODE;
        TransmitRegAddr = (reg_addr >> 8);//MSB
        TransmitRegAddr_1 = (reg_addr & 0xFF); // LSB
        RXByteCtr = count;//1
        TXByteCtr = 0;
        ReceiveIndex = 0;
        TransmitIndex = 0;
        /* Initialize slave address and interrupts */
        UCB2I2CSA = dev_addr;//0X53
        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();
        //for(i=0;i<1000;i++);
        __bis_SR_register(LPM0_bits);              // Enter LPM0 w/ interrupts
    
        return MasterMode;
    }
    
    
    I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint16_t reg_addr, uint8_t *reg_data, uint8_t count)
    {
        /* Initialize state machine */
        MasterMode = TX_REG_ADDRESS_MODE;
        //TransmitRegAddr = reg_addr;//0X32
        TransmitRegAddr = (reg_addr >> 8);//MSB
        TransmitRegAddr_1 = (reg_addr & 0xFF); // LSB
        //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];
        }
    }
    
    
    //******************************************************************************
    // 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;//0X32 MSB
                  MasterMode = TX_LSB_MODE;
                  break;
              case TX_LSB_MODE:
                  UCB2TXBUF = TransmitRegAddr_1; //LSB
                  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++];  // data=9
                     // UCB2CTLW0 |= UCTXSTP;
                      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;
      }
    }

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

    你好 Bruce

    我仅与 DEV_addr 进行了比较、与  TransmitRegAddr 进行了比较。  我已经给出了 if (dev_addr=0x53)的条件。

    我可以看到一些类似的值、但这些值是错误的、因为当我将加速计保持在基值时、所有这些值都是得到的。 如果我改变方向值、方向值应该改变、并且应该也应该有新值。如果我只连接加速计、它运行良好、但当我将代码与 EEPOM 合并时、它不工作 、也不存储在 EEPROM 中。  

    X=45、Y=97、Z=110
    X=100、Y=45、Z=97
    X=98、Y=99、Z=100
    X=101、Y=102、Z=103
    X=104、Y=105、Z=106
    X=107、Y=49、Z=61
    X=54、Y=44、Z=89
    X=49、Y=61、Z=49
    X=52、Y=44、Z=90
    X=49、Y=61、Z=49
    X=57、Y=50、Z=13
    X=10、Y=10、Z=13
    X=10、Y=10、Z=0
    X=0、Y=0、Z=0
     

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

    当我将这些值读取为 ASCII 时、我会看到如下所示的内容:"-and-abcdefghijk1=14、Z1=14、Z1=192\r\n\r\n。"

    其中一些看起来很熟悉、因此我怀疑您是在写入 EEPROM、但您 没有使用您认为是的(EEPROM)地址。 我刚才提到的情况说明现在是什么样子的?

    由于您正在写入字符串、您可以尝试使用"%s"设置 X[]格式。 只需确保 添加字符串终端器、其内容类似于 X[count]='\0';

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

    你好 Bruce

    我在 函数调用中将 EEPROM 地址用作函数参数0x50、并比较写入和读取函数主体中的地址以存储数据。 当我使用%s 时、它没有首先获得正确的数据、即使 我使用地址、数据也不会存储到 EEPROM 中。 我尝试在单独的程序中将整数值存储到 EEPROM 中。 但在这里、它也不会进行存储。 我在这里共享该代码。 请帮帮我。

    ////////////   main.c  /////////////////
    
    #include <msp430.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdint.h>
    #include <stdlib.h>
    #include <i2c.h>
    
    char* X[10];
    uint16_t X1;
    uint16_t Y1;
    uint16_t Z1;
    
    int device_address= 0x50;
    char addr[30]="";
    char device_id[6]="";
    
    int x=10;
    int y=20;
    int z=30;
    
    int main(void)
    {
        WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer
    
    
        LPM1_Clock_config();
        // I2C pins
        P7SEL0 |= BIT0 | BIT1;
        P7SEL1 &= ~(BIT0 | BIT1);
        PM5CTL0 &= ~LOCKLPM5;
        // i2c Configuration
        initI2C();
        uart_config();
        while (1)
        {
            int i;
            id_print("STARTED\r\n");
                                             ///  WRITING
            I2C_Master_WriteReg(0x50,0x00,x,1);
            id_print("x-written\r\n");
            __delay_cycles(8000000);
    
            I2C_Master_WriteReg(0x50,0x01,y,1);
            id_print("y-written\r\n");
            __delay_cycles(8000000);
    
            I2C_Master_WriteReg(0x50,0x02,z,1);
            id_print("z-written\r\n");
            __delay_cycles(8000000);
                                            ///  READING
            I2C_Master_ReadReg(0x50,0x00,1);
            X1=ReceiveBuffer[0];
            I2C_Master_ReadReg(0x50,0x01,1);
            Y1=ReceiveBuffer[0];
            I2C_Master_ReadReg(0x50,0x02,1);
            Z1=ReceiveBuffer[0];
            sprintf(addr,"X=%d,Y=%d,Z=%d\r\n",X1,Y1,Z1);
            id_print(addr);
            UCA0IE &= ~UCTXIE;
            UCA0IE &= ~UCTXCPTIE;
            __delay_cycles(1000000);
        }
    }
    
    
    
    ///////////////////   i2c.h  ///////////////////////
    
    //******************************************************************************
    //   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  0x50
    
    /* 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      0
    #define CMD_TYPE_1_SLAVE      1
    #define CMD_TYPE_2_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
    
    volatile int Rx_index=0;
    volatile unsigned int Rx_key=0;
    volatile int Tx_index=0;
    volatile unsigned int Tx_key=0;
    int size=0;
    char Data[15]="";
    char RXData[5]="";
    
    /* 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] = { 11};
    
    
    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_LSB_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;
    uint8_t TransmitRegAddr_1 = 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 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, uint16_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)//0x53,0,1
    {
    
        /* Initialize state machine */
        MasterMode = TX_REG_ADDRESS_MODE;
        TransmitRegAddr = (reg_addr >> 8);//MSB
        TransmitRegAddr_1 = (reg_addr & 0xFF); // LSB
        RXByteCtr = count;//1
        TXByteCtr = 0;
        ReceiveIndex = 0;
        TransmitIndex = 0;
        /* Initialize slave address and interrupts */
        UCB2I2CSA = dev_addr;//0X53
        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();
        //for(i=0;i<1000;i++);
        __bis_SR_register(LPM0_bits);              // Enter LPM0 w/ interrupts
    
        return MasterMode;
    }
    
    
    I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint16_t reg_addr, uint8_t *reg_data, uint8_t count)
    {
        /* Initialize state machine */
        MasterMode = TX_REG_ADDRESS_MODE;
        TransmitRegAddr = (reg_addr >> 8);//MSB
        TransmitRegAddr_1 = (reg_addr & 0xFF); // LSB
        //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];
        }
    }
    
    
    //******************************************************************************
    // 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;//0X32 MSB
                  MasterMode = TX_LSB_MODE;
                  break;
              case TX_LSB_MODE:
                  UCB2TXBUF = TransmitRegAddr_1; //LSB
                  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++];  // data=9
                     // UCB2CTLW0 |= UCTXSTP;
                      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;
      }
    }
    
    
    
    
    
    
    
    
    
     

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

    > I2C_Master_WriteReg (0x50、0x00、x、1);

    WriteReg 的第3个参数应为"uint8_t *" 指针、您将为其提供一个小整数。 这会将位置10处的(未知)值写入 EEPROM。  (编译器没有为此发出警告、我对此感到有些惊讶。)  

    您应该声明"uint8_t x"并使用:

    > I2C_Master_WriteReg (0x50、0x00、&x、1);

    与之类似、WriteReg 也会调用 y 和 z

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

    你好 Bruce

    我是按照您的建议执行的、但当我看到输出 x 和 y 值变得正确、但 z 值出错时。 当我尝试存储字符串时、字符串无法在 EEPROM 中存储。因此、请帮助我  

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

    我们讨论的是哪种代码? 您得到了什么错误的价值?

    在"string"版本中:您是否修复了我提到的那条 case 语句(实际上是它后面的 if ())?

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

    你好 Bruce

    我讨论的是将整数值存储在 EEPROM 中。 我也跟你说的一样。 当我传递 x=10、y=20、z=30时、EEPROM 会存储这些值。 但是、当我通过 x=100、y=200、z=300时、该 EEPROM 将存储为 x=100 y=200、z=44。 谈到字符串存储代码是,我也遵循了 if 语句,但没有任何内容存储在该语句中。 我想的是、如果这两个代码中的任何一个(interger 存储版本或字符串存储版本)工作正常、我将在主代码上使用该代码。 但它们都不能正常工作。  请帮帮我。

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

    10、20和30都可以放入一个字节(uint8_t)中、但300不能。 300 (mod 256)=44。

    如果您需要写入/读取大于255的值、则应返回 uint16_t 以表示 x、y、z 和

    1) 1)对于编写、请使用如下内容:

    > I2C_Master_WriteReg (0x50、0x00、(uint8_t *)&x、2);

    其中2=sizeof (uint16_t)

    2) 2)为了进行读取、您需要使用如下所示的内容重建 uint16_t:

    I2C_Master_ReadReg (0x50、0x00、2);
    X1=ReceiveBuffer[0]|(ReceiveBuffer[1]<<8);

    因为高字节位于索引[1]("小端字节序")。

    3) 3)将 EEPROM 地址步进2而不是1。

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

    你好 Bruce

    感谢您的重播是的、我在5小时前做了同样的事情、工作做得很好、但在存储字符串方面遇到了问题。 我将在此处共享代码、请为我提供帮助。

    /////////////////  main.c  ////////////////////
    #include <msp430.h>
    #include <stdio.h>
    #include <string.h>
    #include <stdint.h>
    #include <stdlib.h>
    #include <i2c.h>
    
    uint16_t X1,Y1,Z1;
    char* X;
    
    uint16_t address1=0x00;
    uint16_t address2=0x00;
    char addr[30]="";
    char addr1[30]="";
    char device_id[6]="";
    int i,count=0,j;
    
    int main(void)
    {
        WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer
    
    
        LPM1_Clock_config();
        // I2C pins
        P7SEL0 |= BIT0 | BIT1;
        P7SEL1 &= ~(BIT0 | BIT1);
        PM5CTL0 &= ~LOCKLPM5;
        // i2c Configuration
        initI2C();
        uart_config();
        power_ctrl();
        while (1)
        {
               int i;
               uint8_t len;
            
               I2C_Master_ReadReg(0x53,0x32,6);
               X1=((ReceiveBuffer[1]<<8)|ReceiveBuffer[0]);
               Y1=((ReceiveBuffer[3]<<8)|ReceiveBuffer[2]);
               Z1=((ReceiveBuffer[5]<<8)|ReceiveBuffer[4]);
    
               sprintf(addr,"%d,%d,%d",X1,Y1,Z1);
               len=strlen(addr);
    
                     I2C_Master_WriteReg(0x50,address1,addr,len);
                     address1=len+1;
                    
                
                   I2C_Master_ReadReg(0x50,address2,len);
                   for(i=0;i<=len;i++)
                   {
                   X[i]=ReceiveBuffer[i];
                   }
                   printf("%s",X);
                   address2=len+1;
               UCA0IE &= ~UCTXIE;
               UCA0IE &= ~UCTXCPTIE;
               __delay_cycles(8000000);
           }
    }
    
    
    /////////////////////  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
    
    //******************************************************************************
    // Example Commands ************************************************************
    //******************************************************************************
    
    #define SLAVE_ADDR  0x50
    
    /* 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      0
    #define CMD_TYPE_1_SLAVE      1
    #define CMD_TYPE_2_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
    
    volatile int Rx_index=0;
    volatile unsigned int Rx_key=0;
    volatile int Tx_index=0;
    volatile unsigned int Tx_key=0;
    int size=0;
    char Data[15]="";
    //unsigned char* Data;
    char RXData[5]="";
    //uint8_t address1;
    //uint8_t address2;
    /* 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] = { 11};
    
    
    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_LSB_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;
    uint8_t TransmitRegAddr_1 = 0;
    uint8_t TransmitRegAddr_2 = 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 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, uint16_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)//0x53,0,1
    {
    
        /* Initialize state machine */
        MasterMode = TX_REG_ADDRESS_MODE;
       // address1=dev_addr;
        if(dev_addr==0x53)
              {
               TransmitRegAddr = reg_addr;
              }
        else
              {
               TransmitRegAddr_1 = (reg_addr >> 8);//MSB
               TransmitRegAddr_2 = (reg_addr & 0xFF); // LSB
              }
        RXByteCtr = count;//1
        TXByteCtr = 0;
        ReceiveIndex = 0;
        TransmitIndex = 0;
        /* Initialize slave address and interrupts */
        UCB2I2CSA = dev_addr;//0X53
        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();
        //for(i=0;i<1000;i++);
        __bis_SR_register(LPM0_bits);            // Enter LPM0 w/ interrupts
    
        return MasterMode;
    }
    
    
    I2C_Mode I2C_Master_WriteReg(uint8_t dev_addr, uint16_t reg_addr, uint8_t *reg_data, uint8_t count)
    {
        /* Initialize state machine */
        MasterMode = TX_REG_ADDRESS_MODE;
        //TransmitRegAddr = reg_addr;//0X32
        //address2=dev_addr;
        if(dev_addr==0x53)
           {
            TransmitRegAddr = reg_addr;
           }
        else
           {
            TransmitRegAddr_1 = (reg_addr >> 8);//MSB
            TransmitRegAddr_2 = (reg_addr & 0xFF); // LSB
            }
           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 + 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];
        }
    }
    
    
    //******************************************************************************
    // 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:
                  if(UCB2I2CSA==0x50)
                  {
                     UCB2TXBUF = TransmitRegAddr_1;   //0X32 MSB
                     MasterMode = TX_LSB_MODE;
                  }
                  else
                  {
                     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 TX_LSB_MODE:
                  UCB2TXBUF = TransmitRegAddr_2; //LSB
                  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++];  // data=9
                     // UCB2CTLW0 |= UCTXSTP;
                      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;
      }
    }

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

    您看到了什么问题?

    > 字符* X;

    这会创建一个指向内存位置0 ("保留"内存)的指针(您的阵列)、这是最有害的。 请尝试以下类似方法:

    > char X[30]; //大小与 addr[]相同

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

    你好 Bruce  

    我可以在读取时看到字符串。 我一直在尝试存储相同的字符串、然后读回它。 我将字符串作为"hello"传递、但在读取字符串时、有时会被打乱。我将在这里共享这段代码、请帮我

     

    int main(void)
    {
        WDTCTL = WDTPW | WDTHOLD;   // stop watchdog timer
    
    
        LPM1_Clock_config();
        // I2C pins
        P7SEL0 |= BIT0 | BIT1;
        P7SEL1 &= ~(BIT0 | BIT1);
        PM5CTL0 &= ~LOCKLPM5;
        // i2c Configuration
        initI2C();
        uart_config();
        while (1)
        {
    
            
            uint8_t count1;int i;
            count1=strlen(string);
        
            I2C_Master_WriteReg(0x50,address1,string,count1);
            address1=address1+count1;
            sprintf(ad1,"\r\n%x\r\n",address1);
            id_print(ad1);
            __delay_cycles(8000000);
    
          
            I2C_Master_ReadReg(0x50,address2,count1);
            for(i=0;i<=count1;i++)
            {
            X[i]=ReceiveBuffer[i];
            }
            sprintf(addr,"X=%s\r\n",X);
            id_print(addr);
            address2=address2+count1;
            sprintf(ad2,"%x\r\n",address2);
            id_print(ad2);
           
    
            UCA0IE &= ~UCTXIE;
            UCA0IE &= ~UCTXCPTIE;
            __delay_cycles(1000000);
        }
    }
    
    

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

    您能举一个模块化的例子吗?

    我怀疑您遇到了地址换行(他们将其称为"回滚")、即达到特定的寻址边界时会发生什么情况。 对于写入和读取操作、这种方法不同、并且在数据表(doc0670)第10-11页中进行了说明。

    因此、通常最好使用固定长度的记录、这些记录的大小将页面大小平均划分(在本例中为64)。

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

    我正在使用 AT24C256 EEPROM。 它的最大大小为32KB、因此最大地址将为7FFF。 我不确定数据 是否在零位置写入或不在数据到达7FFF 位置时写入。 但在这里、当我手动递增地址时、该地址超出7FFF、并且在打印时、奇怪的是、数据也在打印、即使它穿过内存也是如此。 但我无法理解 EEPROM 是如何存储数据的、现在我对 EEPROM 是否存储数据有疑问。  

    我被传递为"sindhusa"字符串、这里是被 shuffed 的输出。

    7e
    X=sindhusha
    7e
    
    87
    X=sidhushaa
    87
    
    90
    X=sindhusha
    90
    
    99
    X=sindhusha
    99
    
    a2
    X=sindhusha
    a2
    
    ab
    X=sindhusha
    ab
    
    b4
    X=sindhusha
    b4
    
    bd
    X=sindhusha
    bd
    
    c6
    X=sinhusha
    c6
    
    cf
    X=sindhusha
    cf
    
    d8
    X=sindhusha
    d8
    
    e1
    X=sindhusha
    e1
    
    ea
    X=sindhusha
    ea
    
    f3
    X=sindhusha
    f3
    
    fc
    X=sindhusha
    fc
    
    105
    X=sindushas
    105
    
    10e
    X=shaasindh
    10e
    
    117
    X=ushasindh
    117
    
    120
    X=ushasindh
    120
    
    129
    X=ushasindh
    129
    
    132
    X=ushasindh
    132
    
    13b
    X=ushasindh
    13b
    
    144
    X=ushasndhu
    144
    
    14d
    X=shaisindh
    14d
    
    156
    X=ushasindh
    156
    
    15f
    X=ushasindh
    15f
    
    168
    X=ushasindh
    168
    
    171
    X=ushasindh
    171
    
    17a
    X=ushasindh
    17a
    
    183
    X=ushasidhu
    183
    
    18c

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

    >C6
    >X=sinhusha
    >C6

    该写入跨越页边界。 打包的写入地址、但读取地址没有。 在存储器结束(0x7FFF+1)时、写入和读取地址将换行为不同的值。 我建议您阅读数据表的第10-11页(查看"翻滚")。

    像"hello678"这样的东西可能会很好地工作。

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

    好的、我将读取、但我希望使用顺序写入和读取、而不是使用页面概念。 因为我想随机收集主项目上的数据。 顺序概念是否起作用?

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

    页面概念(用于编写)强加在您身上、因此您需要在其中工作。 没有"顺序写入"、只有"字节"和"页"。 除了写入(单个)字节不能跨越页边界之外、这些内容实际上是相同的。

    如果您需要写入大小为64的非除数记录、您可以选择预测写入何时将跨越页边界并将其拆分为两个事务。 这有点痛苦、但可以完成。

    如果要使用可变长度记录、您应该(另外)考虑稍后如何找到这些记录。

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

    你好 Bruce  

    抱歉、我错误地使用顺序读取来使用字节写入和读取、我之前键入过类似这样的内容。 在我的主项目中、我将仅存储可变长度、因此我需要通过各种方法来跟踪长度以存储下一个数据。您还可以向我说明、EEPROM 在完全填满后将从地址位置0开始过度写入?

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

    字节写入是指大小为1的页写入。 上面的代码使用 size>1,因此它们是“页面写入”。

    理论上、您可以一次写入每个字符串一个字节(事务大小=1)。 您不必考虑页面寻址、但它会相当慢(每个字节为5msec "罚分")。

    如果您执行的写入扩展到当前页面的末尾、则地址会返回到该页面的开头[datasheet p. 10]。 这也适用于存储器中的最后一页。 如果您在地址(0x7FFF+1)=0x8000处开始写入、该地址将写入地址0x0000、因为高阶地址位被忽略[数据表图 9]。

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

    你好 Bruce

    现在我的代码运行正常、但我对我将数据存储到 EEPROM 中并进行检索有一个新的怀疑、但我确信当电源在 EEPROM 中时、数据将存储在 EEPROM 中。 但是、当我关闭微控制器电源并再次重新连接时、EEPROM 将能够存储其停止位置的数据。

    例如、最初我将 x=10、y=20、z=30存储在0x0000、0x0001、0x0002、0x0003中、并且我将在下一个写入周期中递增地址和数据、即0x0004、0x0005、0x0006中的 x=11、y=21、z=31。现在我已断开微控制器并在 此时重新连接到0x0008、0009、0x0008、0009中。 这是可能的吗? 如果是、您可以帮助我执行这个操作。 当我尝试从第一个开始存储 EEPROM 时。 i.e、x=10、y=20、z=30、位于0x0000.0x0001、0x0002、0x0003中。 请帮帮我。   

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

    在一般情况下、这是一个相当复杂的问题。 我不能向您介绍一个完整的设计、但这里有一些概念。

    更简单的方法是在启动时使用存储器扫描、查找较新数据与(a)无效数据(可能是已擦除的字节)之间的边界、或(b)较旧数据(如果您循环写入数据)之间的边界。 这可能需要一段时间--在最好的情况下,读取整个内存大约需要一秒钟。

    我知道的所有方法都添加了额外的数据("冗余")、以使您能够区分这些情况。 考虑添加2个字节(总计(6+2)字节记录)。 一种应该是校验和/CRC、以检测胡说。 另一个可用于区分旧数据与新数据。 一个简单的用途可能是"生成计数器"、您每次填充存储器并回圈时都会递增。 如果您的扫描发现一条记录的计数器与上一条记录的计数器不同、则表示边界。

    您可以使用包含最终记录索引的保留 EEPROM 区域来加快或避免启动扫描。 但是、这会引入一组不同的复杂性、因为您将经常编写此区域、并且可能会磨损(超过 EEPROM 单元的写入寿命)这些 EEPROM 单元。 (关键字:"磨损矫正")

    人们已经这么做了很长时间、Web 搜索可以根据不同的假设和要求来建立一组方法。

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

    你好 Bruce

    我能否读取 FRAM 的示例代码。 我找到 FRAM 写入示例代码、但我没有找到 FRAM 读取。 那么、您可以向我发送一些示例代码吗?  

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

    如果您有一个新问题、您应该开始新的主题。

    读取 FRAM 无需执行任何特殊操作。 在示例(msp430fr599x_framwrite.c)中、您可以通过说(例如)"int x = 1 + FRAM_write[3];"来引用数组 FRAM_write。 如果您声明一个变量"const"、它通常被放置在 FRAM 中。

    如果不了解您的目标、就很难说得更多。

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

    您好!

    我在将存储加速计与 EEPROM 连接时遇到问题、但我能够写入和读取加速计的正数据、但我无法读取负值。 相反、负值会被存储为其等效正值。我在一些网站中搜索了如何存储负值、但我没有找到合适的问题。因此、请帮助我解决此问题。我正在共享 CODE.Write_address 的 EEPROM 部分为0x01。

     read_address=write_address;
            __delay_cycles(8000000);
            I2C_Master_WriteReg(0x50,write_address,X1,2);
            __delay_cycles(8000000);
            write_address=write_address+2;
            sprintf(addr,"X1=%d\r\n",X1);
            id_print(addr);
    
    
            I2C_Master_WriteReg(0x50,write_address,Y1,2);
            __delay_cycles(8000000);
            write_address=write_address+2;
            sprintf(addr,"Y1=%d\r\n",Y1);
            id_print(addr);
    
    
            I2C_Master_WriteReg(0x50,write_address,Z1,2);
            __delay_cycles(8000000);
            write_address=write_address+2;
            sprintf(addr,"Z1=%d\r\n",Z1);
            id_print(addr);
    
    
            I2C_Master_ReadReg(0x50,read_address,2);
            __delay_cycles(8000000);
            x=ReceiveBuffer[0];
            sprintf(addr,"x=%d\r\n",x);
            id_print(addr);
            read_address=read_address+2;
    
    
            I2C_Master_ReadReg(0x50,read_address,2);
            __delay_cycles(8000000);
            y=ReceiveBuffer[0];
            sprintf(addr,"y=%d\r\n",y);
            id_print(addr);
            read_address=read_address+2;
    
    
            I2C_Master_ReadReg(0x50,read_address,2);
            __delay_cycles(8000000);
            z=ReceiveBuffer[0];
            sprintf(addr,"z=%d\r\n",z);
            id_print(addr);
            read_address=read_address+2;
    
    
    
    
            sprintf(addr,"Received_data x=%d,y=%d,z=%d\r\n",x,y,z);
            id_print(addr);
            
            
            /////////////////// 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
    
    //******************************************************************************
    // Example Commands ************************************************************
    //******************************************************************************
    
    //#define SLAVE_ADDR  0x50
    
    /* 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      0
    #define CMD_TYPE_1_SLAVE      1
    #define CMD_TYPE_2_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
    
    volatile int Rx_index=0;
    volatile unsigned int Rx_key=0;
    volatile int Tx_index=0;
    volatile unsigned int Tx_key=0;
    int size=0;
    char Data[15]="";
    //unsigned char* Data;
    char RXData[5]="";
    //uint8_t address1;
    //uint8_t address2;
    /* 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] = { 11};
    
    
    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_LSB_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;
    uint8_t TransmitRegAddr_1 = 0;
    uint8_t TransmitRegAddr_2 = 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
     * */
    uint16_t ReceiveBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t RXByteCtr = 0;
    uint8_t ReceiveIndex = 0;
    uint16_t TransmitBuffer[MAX_BUFFER_SIZE] = {0};
    uint8_t TXByteCtr = 0;
    uint8_t TransmitIndex = 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(uint16_t dev_addr, uint16_t reg_addr, uint16_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(uint16_t dev_addr, uint16_t reg_addr, uint8_t count);
    void CopyArray(uint16_t *source, uint16_t *dest, uint8_t count);
    
    
    I2C_Mode  I2C_Master_ReadReg(uint16_t dev_addr, uint16_t reg_addr, uint8_t count)//0x53,0,1
    {
    
        /* Initialize state machine */
        MasterMode = TX_REG_ADDRESS_MODE;
       // address1=dev_addr;
        if(dev_addr==0x53)
              {
               TransmitRegAddr = reg_addr;
              }
        else
              {
               TransmitRegAddr_1 = (reg_addr >> 8);//MSB
               TransmitRegAddr_2 = (reg_addr & 0xFF); // LSB
              }
        RXByteCtr = count;//1
        TXByteCtr = 0;
        ReceiveIndex = 0;
        TransmitIndex = 0;
        /* Initialize slave address and interrupts */
        UCB2I2CSA = dev_addr;//0X53
        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();
        //for(i=0;i<1000;i++);
        __bis_SR_register(LPM0_bits);            // Enter LPM0 w/ interrupts
    
        return MasterMode;
    }
    
    
    I2C_Mode I2C_Master_WriteReg(uint16_t dev_addr, uint16_t reg_addr, uint16_t reg_data, uint8_t count)
    {
        /* Initialize state machine */
        MasterMode = TX_REG_ADDRESS_MODE;
        if(dev_addr==0x53)
           {
            TransmitRegAddr = reg_addr;
           }
        else
           {
            TransmitRegAddr_1 = (reg_addr >> 8);//MSB
            TransmitRegAddr_2 = (reg_addr & 0xFF); // LSB
            }
       // CopyArray(reg_data, TransmitBuffer, count);
        TransmitBuffer[0]=(reg_data & 0xFF);
        TransmitBuffer[1]=((reg_data>>8) & 0xFF);
        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(uint16_t *source, uint16_t *dest, uint8_t count)
    {
        uint8_t copyIndex = 0;
        for (copyIndex = 0; copyIndex < count; copyIndex++)
        {
            dest[copyIndex] = source[copyIndex];
        }
    }
    
    
    //******************************************************************************
    // 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:
                  if(UCB2I2CSA==0x50)
                  {
                     UCB2TXBUF = TransmitRegAddr_1;   //0X32 MSB
                     MasterMode = TX_LSB_MODE;
                  }
                  else
                  {
                     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 TX_LSB_MODE:
                  UCB2TXBUF = TransmitRegAddr_2; //LSB
                  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++];  // data=9
                     // UCB2CTLW0 |= UCTXSTP;
                      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;
      }
    }
    
            
            

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

    如果将 X1声明为"uint16_t"、您应该能够将其重新解释为具有如下符号的16位:

    > Int16_t signed_X1 =(Int16_t) X1;

    不过、如果是这种情况、我希望:

    > I2C_Master_WriteReg (0x50、WRITE_ADDRESS、X1、2);

    应该是

    > I2C_Master_WriteReg (0x50、WRITE_ADDRESS、&X1、2);