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.

[参考译文] MSP430FR6047:MSP430FR6047 EEPROM 读取/写入

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1327877/msp430fr6047-msp430fr6047-eeprom-read-write

器件型号:MSP430FR6047

在 msp430fr6047中使用24LC512 EEPROM 的 Im
我能够使用该代码写入一些数据/值、并通过 Arduino 读取、但不能使用我的 MSP430读取。

(要查看我通过人类可读逻辑进行的 UART 通信的输出)

我提供的读取代码似乎不起作用  
在代码的末尾、我还提供了写入代码、当我使用 ardunio IDE 读取时、可以在 arduno 中发挥作用

//---- 使用 MSP430读取
#包含
#包含

#define ENABLE_PINS 0xFFFE
#define EEPROM_ADDR 0x50 // EEPROM 的 I2C 地址
#define EEPROM_DATA_ADDR 0 //从 EEPROM 读取数据的起始地址
#define data_size 10 //数据数组大小

uint8_t dataRead [data_size];//存储读取数据的数组

void init_i2C(){

P8SEL0 |= BIT5 | BIT6;
P8SEL1 &=~(BIT5 | BIT6);
//初始化 I2C 模块(USCI_B1)
UCB1CTLW0 |= UCSWRST;//启用软件复位
UCB1CTLW0 |= UCSSEL_SMCLK;//选择 SMCLK 作为时钟源
UCB1BRW = 80;//针对所需的 SCL 频率设置时钟分频器
UCB1CTLW0 |= UCMODE_3 | UCMST;// I2C 模式、主模式
UCB1CTLW1 |= UCASTP_2;//在达到 UCB1TBCNT 后生成自动停止
UCB1CTLW0 &=~μ V UCSWRST;//清除软件复位以启动 USCI

void uart_init(){
//配置 UART 引脚
P8SEL0 |= BIT2 | BIT3;// P8.2 = TX、P8.3 = RX
P8SEL1 &=~(BIT2 | BIT3);

//配置 UART 设置
UCA3CTLW0 |= UCSWRST;//将 UART 模块置于复位状态
UCA3CTLW0 |= UCSSEL_SMCLK;//选择 SMCLK 作为时钟源
UCA3BR0 = 104;//将波特率设置为9600 (假设 SMCLK 为1MHz)
UCA3MCTLW = 0x2000;//设置调制(UCBRSx = 4、UCBRFx = 1、UCOS16 = 0)
UCA3BR1=0;
UCA3CTLW0 &=μ~UCSWRST;//初始化 UART 模块

void uart_sendInt (int 值)
{
//将整数转换为字符串
char buffer[6];// Buffer 用于将整数存储为字符串(假设最大长度为5位)
INT I = 0;
如果(值< 0)
{
UCA3TXBUF ='-';//对于负数发送'-'
value =-value;//将值转换为正数/
I++;

正确
{
Buffer[i++]=值% 10 +'0';//将每个数字转换为字符
value /= 10;

while (值!= 0);
//以相反的顺序发送字符
while (--i >= 0)
{
while (! (UCA3IFG & UCTXIFG));//等待 UART 缓冲区就绪
UCA3TXBUF = buffer [i];//发送字符


void readFromEEPROM (uint16_t address、uint8_t * data、uint16_t dataSize){
//设置从机地址
UCB1I2CSA =(0xA0 >> 1);
//发送启动条件
UCB1CTLW0 |= UCTR | UCTXSTT;

//等待开始条件的发送
// while (UCB1CTLW0 & UCTXSTT);
__delay_cycles (600);
//发送要读取的内存地址
UCB1TXBUF =(地址>> 8)& 0xFF;//高字节
//while (! (UCB1IFG & UCTXIFG));//等待 TX 缓冲区准备就绪
__delay_cycles (600);
UCB1TXBUF =地址& 0xFF;//低字节
// while (! (UCB1IFG & UCTXIFG));//等待 TX 缓冲区准备就绪
__delay_cycles (600);
UCB1I2CSA =(0xA0 >> 1);
//发送重复启动条件并设置为读取模式
UCB1CTLW0 |= UCTXNACK;
__delay_cycles (600);
// UCB1CTLW0 |= UCTXSTT;//st 位
//_delay_cycles (600);
UCB1CTLW0 &=~μ s UCTR;
uint16_t i;
//从 EEPROM 读取数据
for (i = 0;i < dataSize;i++){
__delay_cycles (900);// while (! (UCB1IFG & UCRXIFG));//等待 RX 缓冲区填满
data[i]= UCB1RXBUF;//读取数据字节
如果(i == dataSize - 1)
{
//为最后一个字节发送 NACK 和 STOP 条件
UCB1CTLW0 |= UCTXNACK | UCTXSTP;


int main (void){
WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器
PM5CTL0 = ENABLE_PINS;//解锁引脚

INIT_I2C();
uart_init();

//从 EEPROM 读取数据
readFromEEPROM (EEPROM_DATA_ADDR、dataRead、DATA_SIZE);
INT I;
//通过 UART 发送读数据作为整数
对于(I = 0;I < data_size;I++){

uart_sendInt (dataRead [i]);
// uart_sendInt (dataRead [i]);
// UCA3TXBUF = dataRead [i];
// while (! (UCA3IFG & UCTXIFG));
// UCA3TXBUF ='\n';
// while (! (UCA3IFG & UCTXIFG));

while (1);//无限循环

返回0;

//---- 使用 MSP430编写代码

#包含
#包含

#define ENABLE_PINS 0xFFFE
#define EEPROM_ADDR 0x50 // EEPROM 的 I2C 地址
#define EEPROM_DATA_ADDR 0 //将数据写入 EEPROM 的起始地址
#define data_size 10 //数据数组大小

uint8_t dataToWrite[data_size]={0x30、0x31、0x32、0x33、0x34、0x35、0x36、0x37、0x38、0x39};//待写入的数据

void init_i2C(){

P8SEL0 |= BIT5 | BIT6;
P8SEL1 &=~(BIT5 | BIT6);
//初始化 I2C 模块(USCI_B1)
UCB1CTLW0 |= UCSWRST;//启用软件复位
UCB1CTLW0 |= UCSSEL_SMCLK;//选择 SMCLK 作为时钟源
UCB1BRW = 80;//针对所需的 SCL 频率设置时钟分频器
UCB1CTLW0 |= UCMODE_3 | UCMST;// I2C 模式、主模式
UCB1CTLW1 |= UCASTP_2;//在达到 UCB1TBCNT 后生成自动停止
UCB1CTLW0 &=~μ V UCSWRST;//清除软件复位以启动 USCI

void writeToEEPROM (uint16_t address、uint8_t * data、uint16_t dataSize){
//设置从机地址
UCB1I2CSA =(0xA0 >> 1);
//发送启动条件
UCB1CTLW0 |= UCTR | UCTXSTT;

//等待开始条件的发送
// while (UCB1CTLW0 & UCTXSTT);
__delay_cycles (600);
//发送要写入的存储器地址
UCB1TXBUF =(地址>> 8)& 0xFF;//高字节
__delay_cycles (600);
// while (! (UCB1IFG & UCTXIFG));//等待 TX 缓冲区准备就绪
UCB1TXBUF =地址& 0xFF;//低字节
__delay_cycles (600);
// while (! (UCB1IFG & UCTXIFG));//等待 TX 缓冲区准备就绪
uint16_t i=0;
//将数据写入 EEPROM
对于(i = 0;i < dataSize;i++){
UCB1TXBUF =数据[i];
__delay_cycles (600);//写入数据字节
// while (! (UCB1IFG & UCTXIFG));//等待 TX 缓冲区准备就绪

//发送停止条件
UCB1CTLW0 |= UCTXSTP;

int main (void){
WDTCTL = WDTPW | WDTHOLD;//停止看门狗计时器
PM5CTL0 = ENABLE_PINS;//解锁引脚

INIT_I2C();

writeToEEPROM (EEPROM_DATA_ADDR、dataToWrite、DATA_SIZE);

while (1);//无限循环

返回0;

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

    尊敬的 Aravind:

    那么、您已经使用 Arduino 创建了此接口、可使用。现在、您正在尝试为 MSP430写入相同的接口、但无法使用。 您是否尝试过探测 I2C 线路以确保 MSP 生成的信号符合预期?

    您可能需要尝试通读我们的 《MSP430 MCU 上常见 eUSCI 和 USCI 串行通信问题解决方案 》文档。

    此外、您基于哪个代码示例?

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

    你好, 

    答复、  
    是的,我已经尝试了 Arduino 它的工作,这意味着我做了写操作 MSP430和读取数据使用 Arduino ,但当我尝试读取与我写的 MSP430相同的数据,我无法读取它。

    我浏览了您提供的文档、并尝试在代码中实施它、似乎没有响应。

    代码是由我从头开始开发,它没有引用任何代码,因为我在轮询方法做它.

    //----- 读取 EEPROM 的代码

    void readFromEEPROM (uint16_t address、uint8_t * data、uint16_t dataSize){
    //发送启动序列
    UCB1CTLW0 |= UCTR | UCTXSTT;//发送启动条件并设置为发送器

    //等待开始条件的发送
    while (UCB1CTLW0和 UCTXSTT);

    //发送从地址,其中 R/W 位为低电平
    UCB1TXBUF =(EEPROM_ADDR << 1)| 0x00;//发送 R/W 位为低电平的从器件地址

    //等待 TX 缓冲区准备就绪
    while (! (UCB1IFG & UCTXIFG));

    //发送寄存器编号
    UCB1TXBUF =(地址>> 8)& 0xFF;//发送寄存器地址的高字节

    //等待 TX 缓冲区准备就绪
    while (! (UCB1IFG & UCTXIFG));

    UCB1TXBUF = ADDRESS & 0xFF;//发送寄存器地址的低字节

    //等待 TX 缓冲区准备就绪
    while (! (UCB1IFG & UCTXIFG));

    //发送重复的启动序列
    UCB1CTLW0 |= UCTXSTT;//发送重复启动条件

    //等待开始条件的发送
    while (UCB1CTLW0和 UCTXSTT);

    //发送从地址,其中 R/W 位为高电平
    UCB1TXBUF =(EEPROM_ADDR << 1)| 0x01;//发送从地址且 R/W 位为高电平

    //等待 TX 缓冲区准备就绪
    while (! (UCB1IFG & UCTXIFG));

    //读取数据字节
    uint16_t i;
    对于(i = 0;i < dataSize;i++){
    //如果是最后一个字节,则在读取前发送停止条件
    如果(i == dataSize - 1){
    UCB1CTLW0 |= UCTXSTP;//发送停止条件

    //等待 RX 缓冲区接收数据
    while (! (UCB1IFG & UCRXIFG));
    //读取接收的数据
    DATA[I]= UCB1RXBUF;





    此代码仅演示了读取函数。 因此,我需要知道什么是我需要做的改变,这对我来说是非常有用的。

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

    即使您使用轮询而不是基于中断的系统、我也强烈建议您以我们的示例之一为基础、例如位于[SDK 安装路径]\examples\devices\MSP430FR5xx_6xx\MSP430FR60x7_MSP430FR60x5_MSP430FR60x5_SD\C 中使用寄存器级编程的 Code_Examples 示例。 这至少将为您提供一个用于器件初始化的已知起点。 除了启用中断和轮询标志的循环之外、轮询与中断也非常相似。  

    此外、您是否探测了 I2C 线路以查看流量是否符合预期? 这将揭示 MSP430代码有问题、还是您的设置的某些其他部分有问题。 到目前为止、我觉得 MSP430可能可以正常工作、但您编码到 MSP430的行为可能与 EEPROM 的写入/读取方式不兼容。 请探测通信线路以测试 MSP430如何进行通信。

    您是否曾尝试调试该项目以查看它是挂起还是卡住? 是否所有代码都执行、但探测的 I2C 线路看起来不像您怀疑的那样? 如果您能提供有关项目无法正常工作的更多信息、而不是发布代码表示无法正常工作、这将非常有用。

    请注意、在发布回复时、可以使用 E2E 对话框中的"插入"->"代码"功能粘贴代码并使其更具可读性。

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

    //-----READ From EEPROM
    #include <msp430.h>
    #include <stdint.h>
    
    #define ENABLE_PINS 0xFFFE
    #define EEPROM_ADDR 0x50  // I2C address of the EEPROM
    #define EEPROM_DATA_ADDR 0 // Starting address to read the data from the EEPROM
    #define DATA_SIZE 12     // Size of data array
    
    uint8_t dataRead[DATA_SIZE]; // Array to store read data
    
    void init_I2C() {
        P8SEL0 |= BIT5 | BIT6;
        P8SEL1 &= ~(BIT5 | BIT6);
        // Initialize I2C module (USCI_B1)
        UCB1CTLW0 |= UCSWRST;          // Enable software reset
        UCB1CTLW0 |= UCSSEL__SMCLK;    // Select SMCLK as clock source
        UCB1BRW = 80;                  // Set clock divider for desired SCL frequency
        UCB1CTLW0 |= UCMODE_3 | UCMST; // I2C mode, Master mode
        UCB1CTLW1 |= UCASTP_2;         // Automatic stop generated after UCB1TBCNT is reached
        UCB1CTLW0 &= ~UCSWRST;         // Clear software reset to start USCI
    }
    
    void UART_init() {
        // Configure UART pins
        P8SEL0 |= BIT2 | BIT3;   // P8.2 = TX, P8.3 = RX
        P8SEL1 &= ~(BIT2 | BIT3);
    
        // Configure UART settings
        UCA3CTLW0 |= UCSWRST;         // Put UART module in reset state
        UCA3CTLW0 |= UCSSEL__SMCLK;   // Select SMCLK as the clock source
        UCA3BR0 = 104;                 // Set Baud rate to 9600 (assuming SMCLK is 1MHz)
        UCA3MCTLW = 0x2000;          // Set modulation (UCBRSx = 4, UCBRFx = 1, UCOS16 = 0)
        UCA3BR1 = 0;
        UCA3CTLW0 &= ~UCSWRST;       // Initialize UART module
    }
    
    void UART_sendInt(int value) {
        // Convert integer to string
        char buffer[6]; // Buffer for storing the integer as a string (assuming max length of 5 digits)
        int i = 0;
        if (value < 0) {
            UCA3TXBUF = '-'; // Send '-' for negative numbers
            value = -value; // Convert value to positive
            i++;
        }
        do {
            buffer[i++] = value % 10 + '0'; // Convert each digit to character
            value /= 10;
        } while (value != 0);
        // Send characters in reverse order
        while (--i >= 0) {
            while (!(UCA3IFG & UCTXIFG)); // Wait until UART buffer is ready
            UCA3TXBUF = buffer[i];         // Transmit character
        }
    }
    
    void readFromEEPROM(uint16_t address, uint8_t *data, uint16_t dataSize) {
        // Set slave address
        UCB1I2CSA = 0x50;
    
        // Send start condition
        UCB1CTLW0 |= UCTR | UCTXSTT;
        __delay_cycles(50000);
        // Wait for start condition to be sent
      //  while (UCB1CTLW0 & UCTXSTT);
    
        // Send memory address to read from
        UCB1TXBUF = (address >> 8) & 0xFF; // High byte
        __delay_cycles(50000);
        // while (!(UCB1IFG & UCTXIFG));     // Wait for TX buffer to be ready
        UCB1TXBUF = address & 0xFF;       // Low byte
        __delay_cycles(50000);    // Wait for TX buffer to be ready
    
        // Send repeated start condition to initiate read
        UCB1CTLW0 &= ~UCTR;                // Set to receive mode
        UCB1CTLW0 |= UCTXSTT;              // Send repeated start condition
    
        // Wait for start condition to be sent
       // while (UCB1CTLW0 & UCTXSTT);
        __delay_cycles(50000);
        uint16_t i;
        // Read data from EEPROM
        for (i = 0; i < dataSize; i++) {
            // Wait for data to be received
            __delay_cycles(50000);
            //  while (!(UCB1IFG & UCRXIFG));
            data[i] = UCB1RXBUF; // Read data byte
    
            // Send N+1 and continue reading
            if (i < dataSize - 1)
            {
                UCB1TXBUF = data[i + 1]; // Send next expected byte
            }
        }
    
        // Send stop condition
        UCB1CTLW0 |= UCTXSTP;
    }
    
    int main(void) {
        WDTCTL = WDTPW | WDTHOLD; // Stop the watchdog timer
        PM5CTL0 = ENABLE_PINS;    // Unlock pins
    
        init_I2C();
        UART_init();
    
        // Read data from EEPROM
    
        readFromEEPROM(EEPROM_DATA_ADDR, dataRead, DATA_SIZE);
        __delay_cycles(2000000);
    
    
        // Send read data over UART as integers
        int i;
        for (i = 0; i < DATA_SIZE; i++) {
            UART_sendInt(dataRead[i]);
        }
    
       while(1); // Infinite loop
    
        return 0;
    }

    我已经尝试探测它生成写入地址、但在涉及到读取时(如 pic 中所示)
    实际上我的任务是存储一些值/数据在 EEPROM 并读取它.

    所以我在轮询模式中第一次从头开始编写代码。  

    我看到了初始化 I2C 的示例代码。 从示例中重写太乏味了、因为我们使用的是定制的 MSP (芯片是相同的引脚不同)
     

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

    我在第一个屏幕截图中看到 MSP 正在正确写入。 除了使用 MSP 进行读取之外、您是否有其他方法可以检查 EEPROM 是否正在正确读取和保存该数据?

    在第二个屏幕截图中、我看到您在 R/W 位为低电平时写入地址、我假设是这样、您可以继续写入寄存器地址? 由于在您发送0之后 SCL 线保持低电平,因此外设可能会时钟延展。 您需要检查器件为什么进行时钟延展。

    您是否曾尝试调试 MSP 代码以了解代码是否按预期运行? 您可能需要利用 NACK 中断来帮助解决问题。

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

    #include <msp430.h>
    #include <stdint.h>
    
    #define ENABLE_PINS 0xFFFE
    
    char data_in;
    uint8_t eeprom_address = 0; // Starting EEPROM address
    
    int main(void) {
        WDTCTL = WDTPW | WDTHOLD; // Stop the watchdog timer
        PM5CTL0 = ENABLE_PINS;    // Unlock pins
    
        UCB1CTLW0 |= UCSWRST;
    
        UCB1CTLW0 |= UCSSEL_3;
        UCB1BRW = 80; // Set clock divider for desired SCL frequency
    
        UCB1CTLW0 |= UCMODE_3;
        UCB1CTLW0 |= UCMST;
        UCB1CTLW0 &= ~UCTR;
        UCB1I2CSA = (0xA0 >>1);
    
        UCB1CTLW1 |= UCASTP_2;
        UCB1TBCNT = 1; // Sending 1 byte (EEPROM address)
    
        P8SEL1 &= ~BIT6;
        P8SEL0 |=  BIT6;
    
        P8SEL1 &= ~BIT5;
        P8SEL0 |=  BIT5;
    
        PM5CTL0 &= ~LOCKLPM5;
    
        UCB1CTLW0 &= ~UCSWRST;
    
        UCB1IE |= UCRXIE0 | UCNACKIE; // Enable RX and NACK interrupts
        __enable_interrupt();
    
    
        while(1){
            // Write EEPROM address to read from
            UCB1TXBUF = eeprom_address;
    
            // Increment EEPROM address for next read operation
            eeprom_address++;
    
            // Wait for transmission to complete
            __delay_cycles(600);
    
            // Initiate start condition for read operation
            UCB1CTLW0 &= ~UCTR; // Switch to RX mode
            UCB1CTLW0 |= UCTXSTT;
    
            // Delay to allow EEPROM to process the request
            __delay_cycles(600);
        }
    
        return 0;
    }
    
    //-----------
    
    #pragma vector = EUSCI_B1_VECTOR
    __interrupt void EUSCI_B1_I2C(void)
    {
        if (UCB1IFG & UCRXIFG)
        {
            data_in = UCB1RXBUF; // Read received data
    
            // TODO: Process received data as needed
        }
        else if (UCB1IFG & UCNACKIFG)
        {
            // NACK received (end of sequential read)
            // Send stop condition
            UCB1CTLW0 |= UCTXSTP;
    
            // Disable further RX and NACK interrupts
            UCB1IE &= ~(UCRXIE0 | UCNACKIE);
        }
    }
    

    使用您建议的读取正在工作的中断编写了一个备用代码  

    但我得到了0xAA 读10次,然后我做了我的书面地址正确,即使我得到了这个。

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

    我很高兴听到新版本正在运行。

    那么、现在您正在探测数据线路、您可以看到读取序列正常执行、但您从 EEPROM 中读取的数据始终为0xAA?

    如果是这样的话、您可能需要检查您所使用 EEPROM 的数据表或用户指南。 您可能还需要验证0xAA 实际上不是存储在您正在读取的地址中的正确数据。  

    如果您调试代码并查看从 EEPROM 接收到的数据、它与您在探针(0xAA)上看到的数据是否匹配?  

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

    #include <msp430.h>
    #include <stdint.h>
    
    #define ENABLE_PINS 0xFFFE
    
    char data_in;
    uint8_t eeprom_address = 0; // Starting EEPROM address
    
    int main(void) {
        int i = 0;
        WDTCTL = WDTPW | WDTHOLD; // Stop the watchdog timer
        PM5CTL0 = ENABLE_PINS;    // Unlock pins
    
        UCB1CTLW0 |= UCSWRST;
    
        UCB1CTLW0 |= UCSSEL_3;
        UCB1BRW = 80; // Set clock divider for desired SCL frequency
    
        UCB1CTLW0 |= UCMODE_3;
        UCB1CTLW0 |= UCMST;
        UCB1CTLW0 |= UCTR;
        UCB1I2CSA = (0xA0 >>1);
    
    //    UCB1CTLW1 |= UCASTP_2;
        //UCB1TBCNT = 1; // Sending 1 byte (EEPROM address)
    
        P8SEL1 &= ~BIT6;
        P8SEL0 |=  BIT6;
    
        P8SEL1 &= ~BIT5;
        P8SEL0 |=  BIT5;
    
        PM5CTL0 &= ~LOCKLPM5;
    
        UCB1CTLW0 &= ~UCSWRST;
    
        UCB1IE |= UCRXIE0 | UCNACKIE; // Enable RX and NACK interrupts
        __enable_interrupt();
    
    
        while(1){
            UCB1CTLW0 |= UCTXSTT;
            __delay_cycles(600);
            UCB1I2CSA = (0xA0 >>1);
            __delay_cycles(600);
            // Write EEPROM address to read from
            UCB1TXBUF = (eeprom_address >> 8);
            __delay_cycles(1200);
    
            // Write EEPROM address to read from
            UCB1TXBUF = eeprom_address;
            __delay_cycles(900);
    
            // Initiate start condition for read operation
            UCB1CTLW0 &= ~UCTR; // Switch to RX mode
            UCB1CTLW0 |= UCTXSTT;
            __delay_cycles(900);
            UCB1I2CSA = (0xA0 >>1) ;
            __delay_cycles(900);
            // Delay to allow EEPROM to process the request
    //        for(i=0;i<10;i++)
            {
                __delay_cycles(600);
                data_in = UCB1RXBUF; // Read received data
            }
            eeprom_address++;
        }
    
        return 0;
    }
    
    //-----------
    
    #pragma vector = EUSCI_B1_VECTOR
    __interrupt void EUSCI_B1_I2C(void)
    {
        if (UCB1IFG & UCRXIFG)
        {
            data_in = UCB1RXBUF; // Read received data
    
            // TODO: Process received data as needed
        }
        else if (UCB1IFG & UCNACKIFG)
        {
            // NACK received (end of sequential read)
            // Send stop condition
            UCB1CTLW0 |= UCTXSTP;
    
            // Disable further RX and NACK interrupts
            UCB1IE &= ~(UCRXIE0 | UCNACKIE);
        }
    }

    谢谢、但我犯的错误是在第25行启用自动停止寄存器(UCASTP_2)、这阻止了我进入内部读取值  
    注释之后、系统将正确读取该行的数据、  
    谢谢你的建议  

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

    感谢您发表您的解决方案、Aravind。 很高兴它现在工作。

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

    主席先生,我还有其他疑问  

    我只能写入少量内容、  

    手动写入1KB 数据应该怎么做  

    IM 不采用任何传感器值。 我只是在尝试将1KB 存储到我的 EEPROM 中。

    这是我做过的写代码!!


    如何操作

    #include <msp430.h>
    #include <stdint.h>
    
    int main (void)
    {
        WDTCTL = WDTPW | WDTHOLD; // Stop the watchdog timer
    
        UCB1CTLW0 |= UCSWRST;
        UCB1CTLW0 |= UCSSEL_3;
        UCB1BRW   = 80;
    
        UCB1CTLW0 |= UCMODE_3;
        UCB1CTLW0 |= UCMST; //master mode
    
        UCB1CTLW0 |=UCTR;//write mode
        UCB1I2CSA |= 0x50;
    
       // UCB1CTLW0 |= UCASTP_2;
        UCB1TBCNT = 1;
    
    
        P8SEL1 &= ~BIT5;
        P8SEL0 |= BIT5;
    
    
        P8SEL1 &= ~BIT6;
           P8SEL0 |= BIT6;
    
           PM5CTL0 &= ~LOCKLPM5;
           UCB1CTLW0 &= ~UCSWRST;
    
           UCB1IE |= UCTXIE0;
           __enable_interrupt();
    
    
    
           while(1)
           {
               UCB1CTLW0 |= UCTXSTT;
               __delay_cycles(1900);
           }
           return 0;
    }
    //---------isr
    #pragma vector = EUSCI_B1_VECTOR
    __interrupt void EUSCI_B1_I2C_ISR(void)
    {
        UCB1TXBUF = 0x88;
    }
    
    
    

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

    你能解释一下你说你只能写一小笔钱的意思吗?  

    如果要手动传输1KB 的数据、最简单的做法可能是将数据放在数组中、然后使用循环来发送数组的每个字节。  

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

    #include <msp430.h>
    #include <stdint.h>
    
    #define DATA_SIZE 1024 // 1 KB
    uint8_t data[DATA_SIZE];
    
    volatile uint16_t bytes_transmitted = 0;
    
    int main(void)
    {
        WDTCTL = WDTPW | WDTHOLD; // Stop the watchdog timer
        int i;
        // Initialize your data array here (if needed)
        // Example: Fill data array with sequential values
        for (i = 0; i < DATA_SIZE; ++i) {
            data[i] = i % 256; // Values from 0 to 255, repeating
        }
    
        // Configure I2C
        UCB1CTLW0 |= UCSWRST;
        UCB1CTLW0 |= UCSSEL_3;
        UCB1BRW = 80;
        UCB1CTLW0 |= UCMODE_3;
        UCB1CTLW0 |= UCMST; // Master mode
        UCB1CTLW0 |= UCTR;  // Write mode
        UCB1I2CSA |= 0x50;
    //    UCB1TBCNT = DATA_SIZE;
    
        // Configure I2C pins
        P8SEL1 &= ~(BIT5 | BIT6);
        P8SEL0 |= (BIT5 | BIT6);
    
        // Release the I2C peripheral for operation
        PM5CTL0 &= ~LOCKLPM5;
        UCB1CTLW0 &= ~UCSWRST;
    
        // Enable interrupts
        UCB1IE |= UCTXIE0;
        __enable_interrupt();
    
        // Start transmission
        UCB1CTLW0 |= UCTXSTT;
    
        // Enter low-power mode
       // __bis_SR_register(LPM0_bits | GIE);
    while(1){}
    
    
    return 0;
    }
    
    // I2C ISR
    #pragma vector = EUSCI_B1_VECTOR
    __interrupt void EUSCI_B1_I2C_ISR(void)
    {
        switch (__even_in_range(UCB1IV, USCI_I2C_UCBIT9IFG))
        {
            case USCI_I2C_UCNACKIFG: // NACK interrupt
                break;
            case USCI_I2C_UCALIFG:   // Arbitration Lost interrupt
                break;
            case USCI_I2C_UCSTTIFG:  // Start bit interrupt
                break;
            case USCI_I2C_UCSTPIFG:  // Stop bit interrupt
                break;
            case USCI_I2C_UCRXIFG0:   // Receive buffer full interrupt
                break;
            case USCI_I2C_UCTXIFG0:  // Transmit buffer empty interrupt
                // Write data to transmit buffer
                if (bytes_transmitted < DATA_SIZE)
                {
                    UCB1TXBUF = data[bytes_transmitted];
                    bytes_transmitted++;
                }
                else
                {
                    // Finished transmitting all data, initiate Stop condition
                    UCB1CTLW0 |= UCTXSTP;
                    // Exit low-power mode
                   // __bic_SR_register_on_exit(LPM0_bits);
                }
                break;
            default:
                break;
        }
    }
    
    

    我从0x00写入0xFF、但它需要高达0x37 (56字节)

    我写入了以存储所有256个字节、但它需要高达0x33。

    以及阵列的最大1KB 范围是多少。

    Im 混淆了256和1024、我需要做什么?

    我已经附上了我所做的示例代码。

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

    1) 1)您发送的前2个字节将被解释为要使用的 EEPROM 地址(高位字节在前)[请参考数据表(DS21754M)第6.1节]。 您发布的代码中是0x0001。 您可能需要扩展到 data[2+data_size]并显式将所需地址放入前2个字节。

    2) 2)您可以在每个事务中写入多达128个字节、但根据页对齐情况(EEPROM 地址的低7位)、可能会写入更小的字节[请参阅数据表第6.2节]。 具体而言、您可以写入(128-(address & 0x7F))个字节。 [设备会接受更多数据、但会将数据放在错误位置。]

    3) 3)在写入事务(停止条件)之后、您需要等待5ms、然后再发送另一个数据块[请参阅数据表表表1-2中的 TWC ]。

    (2)+(3)不适用于读取操作[请参阅数据表第8.3节]。

    在给定上述(1)+(2)和您发布的代码的情况下、我不确定0x33和0x37的来源。 "采取"究竟意味着什么? I2C 事务是否停止? 还是数据回读不正确?

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

    感谢您提出的建议、先生、我更正了写入数据方面的问题、  

    现在、对于读取、我已经使用轮询方法读取了值、
    在将其设置为中断模式时、它不读取数据  

    //------------------------------------------------------------------Working read code in polling
    #include <msp430.h>
    #include <stdint.h>
    
    #define ENABLE_PINS 0xFFFE
    
    uint8_t data_in;
    //static int idx=0;
    uint8_t eeprom_address = 0; // Starting EEPROM address
    
    int main(void) {
        int i = 0;
        WDTCTL = WDTPW | WDTHOLD; // Stop the watchdog timer
        PM5CTL0 = ENABLE_PINS;    // Unlock pins
    
        UCB1CTLW0 |= UCSWRST;
    
        UCB1CTLW0 |= UCSSEL_3;
        UCB1BRW = 80; // Set clock divider for desired SCL frequency
    
        UCB1CTLW0 |= UCMODE_3;
        UCB1CTLW0 |= UCMST;
        UCB1CTLW0 |= UCTR;
        UCB1I2CSA = (0xA0 >>1);
    
    //    UCB1CTLW1 |= UCASTP_2;
        //UCB1TBCNT = 1; // Sending 1 byte (EEPROM address)
    
        P8SEL1 &= ~BIT6;
        P8SEL0 |=  BIT6;
    
        P8SEL1 &= ~BIT5;
        P8SEL0 |=  BIT5;
    
        PM5CTL0 &= ~LOCKLPM5;
    
        UCB1CTLW0 &= ~UCSWRST;
    
        UCB1IE |= UCRXIE0 | UCNACKIE; // Enable RX and NACK interrupts
        __enable_interrupt();
    
    
        while(1){
            UCB1CTLW0 |= UCTXSTT;
            __delay_cycles(600);
            UCB1I2CSA = (0xA0 >>1);
            __delay_cycles(600);
            // Write EEPROM address to read from
            UCB1TXBUF = (eeprom_address >> 8);
            __delay_cycles(1200);
    
            // Write EEPROM address to read from
            UCB1TXBUF = eeprom_address;
            __delay_cycles(900);
    
            // Initiate start condition for read operation
            UCB1CTLW0 &= ~UCTR; // Switch to RX mode
            UCB1CTLW0 |= UCTXSTT;
            __delay_cycles(900);
            UCB1I2CSA = (0xA0 >>1) ;
            __delay_cycles(900);
            // Delay to allow EEPROM to process the request
            for(i=0;i<10;i++)
            {
                __delay_cycles(600);
                data_in = UCB1RXBUF; // Read received data
            }
            eeprom_address++;
        }
    
        return 0;
    }
    
    //-----------
    
    #pragma vector = EUSCI_B1_VECTOR
    __interrupt void EUSCI_B1_I2C(void)
    {
        if (UCB1IFG & UCRXIFG)
        {
            data_in= UCB1RXBUF; // Read received data
            // TODO: Process received data as needed
        }
        else if (UCB1IFG & UCNACKIFG)
        {
            // NACK received (end of sequential read)
            // Send stop condition
            UCB1CTLW0 |= UCTXSTP;
    
            // Disable further RX and NACK interrupts
            UCB1IE &= ~(UCRXIE0 | UCNACKIE);
        }
    }
    //---- code that i wrote using interrupts for read 
    #include <msp430.h>
    #include <stdint.h>
    
    #define ENABLE_PINS 0xFFFE
    
    uint8_t data_in;
    uint8_t eeprom_address = 0; // Starting EEPROM address
    uint8_t bytes_to_read = 50; // Number of bytes to read
    
    int main(void) {
        WDTCTL = WDTPW | WDTHOLD; // Stop the watchdog timer
        PM5CTL0 = ENABLE_PINS;    // Unlock pins
    
        UCB1CTLW0 |= UCSWRST;
    
        UCB1CTLW0 |= UCSSEL_3;
        UCB1BRW = 80; // Set clock divider for desired SCL frequency
    
        UCB1CTLW0 |= UCMODE_3;
        UCB1CTLW0 |= UCMST;
        UCB1CTLW0 |= UCTR;
        UCB1I2CSA = (0xA0 >> 1);
       // UCB1CTLW1 |= UCASTP_2;
    
        P8SEL1 &= ~BIT6;
        P8SEL0 |= BIT6;
    
        P8SEL1 &= ~BIT5;
        P8SEL0 |= BIT5;
    
        PM5CTL0 &= ~LOCKLPM5;
    
        UCB1CTLW0 &= ~UCSWRST;
    
        UCB1IE |= UCRXIE0 | UCNACKIE; // Enable RX and NACK interrupts
        __enable_interrupt();
    
        // Write the EEPROM address to read from
        UCB1TXBUF = (eeprom_address >> 8); // Send high byte of address
        __delay_cycles(50000);
        //while (!(UCB1IFG & UCTXIFG0)); // Wait for TX buffer to be ready
        UCB1TXBUF = eeprom_address & 0xFF; // Send low byte of address
        __delay_cycles(50000);
        //while (!(UCB1IFG & UCTXIFG0)); // Wait for TX buffer to be ready
    
        // Initiate start condition for read operation
        UCB1CTLW0 &= ~UCTR; // Switch to RX mode
        UCB1CTLW0 |= UCTXSTT;
    
        // Enter low-power mode
        //__bis_SR_register(LPM0_bits | GIE);
    
        return 0;
    }
    
    //-----------
    
    #pragma vector = EUSCI_B1_VECTOR
    __interrupt void EUSCI_B1_I2C(void)
    {
        static uint8_t bytes_read = 0;
    
        if (UCB1IFG & UCRXIFG)
        {
            data_in = UCB1RXBUF; // Read received data
            bytes_read++;
    
            if (bytes_read == bytes_to_read)
            {
                // Finished reading desired number of bytes, send stop condition
                UCB1CTLW0 |= UCTXSTP;
    
                // Disable further RX and NACK interrupts
                UCB1IE &= ~(UCRXIE0 | UCNACKIE);
    
                // Exit low-power mode
               // __bic_SR_register_on_exit(LPM0_bits);
            }
        }
        else if (UCB1IFG & UCNACKIFG)
        {
            // NACK received (end of sequential read)
            // Send stop condition
            UCB1CTLW0 |= UCTXSTP;
    
            // Disable further RX and NACK interrupts
            UCB1IE &= ~(UCRXIE0 | UCNACKIE);
    
            // Exit low-power mode
           // __bic_SR_register_on_exit(LPM0_bits);
        }
    }


     尝试读取我写入的50个字节、得到了这些字节  

    我可以获得任何编程步骤建议以便更清晰地理解

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

    在第一个代码的第44行: [不要更改第58行、没问题。]

    > UCB1CTLW0 |= UCTXSTT;

    您未在此处设置 UCTR、因此 EEPROM 永远不会看到您的地址设置。 您看到的字节已经超过了您写入的位置。 请尝试改用:

    > UCB1CTLW0 |= UCTXSTT | UCTR;//开始,写入请求

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

    谢谢你,先生,应用这些。

    实际上、SIR、我的第一个代码在某些方面工作(至少读取值)
    我需要的就是使第二个代码正常工作。  

    请提出建议。

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

    当您运行第二个代码时会出现什么情况?

    ----------------

    第二个代码具有类似的错误、因为它没有启动写入阶段、所以 EEPROM 永远不会看到您的地址请求。 这不会导致程序挂起、但它会得到不正确的数据。

    在第38行附近的某个地方、我预计会看到类似下面的东西:

    > UCB1CTLW0 |= UCTXSTT | UCTR;//开始,写入请求

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

    当我运行代码时、它在所有字节中显示为0xFF、  

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

    我建议添加该行代码之前或之后使用该跟踪吗?

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

    是的,先生

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

    我假定"是"是指"之后"。

    我在这条轨迹中看到了超过0xFF-s——前5个字节是0xAA。 在之前的某个实验中、您似乎写入了这5个字节。  

    现在可能需要返回到写入数据的代码、让它在 EEPROM 地址0写入不同的内容。

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

    您好、先生!

    我在加班时遇到了一些困惑、因此我请求一个用于读取和写入我的端口分配的代码
    P8.5是 SDA、P8.6是 SCL (它是一个定制板)、i2c 模块位于 UCB1中  
    这只是一个示例代码、用于写入10个字节并读取我写入的10个字节。
    我的 i2c 器件地址为0x50。  如果我有一个示例代码、它将会更有帮助。  

    谢谢。

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

    尊敬的 Aravind:

    请查看我们发布的示例代码、并对其进行修改以更改端口和 i2c 器件地址。 您可以在我之前回复中提到的 SDK 路径中找到我们的所有示例。 您还可以通过浏览我们的 TI Resource Explorer 来查找示例