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.

[参考译文] MSP430FR6928:AT24C256与 MSP430FR6928连接

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1372596/msp430fr6928-at24c256-interfacing-with-msp430fr6928

器件型号:MSP430FR6928

工具与软件:

您好、我正在向 EEPROM 写入4字节(AT24C256)、但无法写入一个以上的字节。 一个字节可以写入读取、但多个字节无法写入。 请参考以下代码。请同时回复

void InitI2C (unsigned char EEPROM_i2c_address)


UCB1CTLW0 = UCSWRST;//启用软件复位
UCB1CTLW0 |= UCMODE_3 | UCMST | UCSSEL__SMCLK | UCSYNC;// I2C 主模式、SMCLK
UCB1BRW = 160;// fSCL = SMCLK/160 =~100kHz
UCB1I2CSA = SLAVE_ADDR;//从地址
UCB1CTLW0 &=~μ s UCSWRST;//清除软件复位、恢复操作
UCB1IE |= UCNACKIE

}

I2C_Mode I2C_ADC Master_Read (unsigned char dev_addr、unsigned char reg_addr、unsigned char 计数)

/*初始化状态机*/
MasterMode = TX_REG_ADDRESS_MODE;
// TransmitRegAddr = reg_addr;
//P4OUT |=(BIT3);
P3OUT |=(BIT0);

TransmitRegAddr_1 =(reg_addr >> 8);//MSB
TransmitRegAddr_2 =(reg_addr & 0xFF);// LSB

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

/*初始化从机地址和中断*/
UCB1I2CSA = dev_addr;
UCB1IFG 并且=~(UCTXIFG + UCRXIFG);//清除任何挂起的中断
UCB1IE &&~μ P UCRXIE;//禁用 RX 中断
UCB1IE |= UCTXIE;//启用 TX 中断

UCB1CTLW0 |= UCTR + UCTXSTT;// I2C TX、启动条件
___ enable_interrupt ();
__bis_SR_register (LPM0_bits + GIE);//随着中断进入 LPM0

返回 MasterMode;

}
void CopyArray (unsigned char *来源、unsigned char *目标、unsigned char 计数)

unsigned char copyIndex = 0;
对于(copyIndex = 0;copyIndex < count;copyIndex++)

dest[copyIndex]= source[copyIndex];
}
}


I2C_Mode I2C_ADC Master_Write (unsigned char dev_addr、unsigned int reg_addr、unsigned char * reg_data、unsigned char 计数)
//I2C_Mode I2C_LaunchPad Master_Write (uint8_t dev_addr、uint8_t reg_addr、uint8_t * reg_data、uint8_t count)

/*初始化状态机*/
MasterMode = TX_REG_ADDRESS_MODE;
// TransmitRegAddr = reg_addr;
// P4OUT &=~(BIT3);
P3OUT &=~Ω(BIT0);
TransmitRegAddr_1 =(reg_addr >> 8);//MSB
TransmitRegAddr_2 =(reg_addr & 0xFF);// LSB

//将寄存器数据复制到 TransmitBuffer
// unsigned char dt =88;
// putstr("\nstr");
CopyArray (reg_data、TransmitBuffer、count);

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

/*初始化从机地址和中断*/
UCB1I2CSA = dev_addr;
UCB1IFG 并且=~(UCTXIFG + UCRXIFG);//清除任何挂起的中断
UCB1IE &&~μ P UCRXIE;//禁用 RX 中断
UCB1IE |= UCTXIE;//启用 TX 中断

UCB1CTLW0 |= UCTR + UCTXSTT;// I2C TX、启动条件
___ enable_interrupt ();
__bis_SR_register (LPM0_bits + GIE);//随着中断进入 LPM0

返回 MasterMode;
}

#if defined (__TI_Compiler_version__)|| defined (__IAR_SYSTEMS_ICC__)
#pragma vector = USCI_B1_VECTOR
_interrupt void USCI_B1_ISR (void)
#elif defined (_GNUC__)
void __attribute__(((interrupt (USCI_B0_vector))) USCI_B1_ISR (void)
#else
错误编译器不受支持!
#endif
必须从 UCB2RXBUF 读取

//putch ('B');
unsigned char rx_val = 0;
开关(__EVEN_IN_RANGE (UCB1IV、USCI_I2C_UCBIT9IFG))

case USCI_NONE:break;//向量0:无中断
case USCI_I2C_UCALIFG:break;// Vector 2:ALIFG
case USCI_I2C_UCNACKIFG:// Vector 4:NACKIFG
休息;
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
实例 USCI_I2C_UCRXIFG0://矢量22:RXIFG0
Rx_val = UCB1RXBUF;
IF (RXByteCtr)

ReceiveBuffer[ReceiveIndex++]= Rx_val;

RXByteCtr --;
}

if (RXByteCtr =1)

UCB1CTLW0 |= UCTXSTP;
}
否则为(RXByteCtr =0)

UCB1IE &=~UCRXIE;
MasterMode = IDLE_MODE;
_BIC_SR_REGISTER_ON_EXIT (CPUOFF);//退出 LPM0
}
休息;

case USCI_I2C_UCTXIFG0:// Vector 24:TXIFG0

开关(MasterMode)

实例 TX_REG_ADDRESS_MODE:
如果(UCB1I2CSA = 0x50)

UCB1TXBUF = TransmitRegAddr_1;//0x32 MSB
//UCB1TXBUF = TransmitRegAddr;
MasterMode = TX_LSB_MODE;
}
设计

UCB1TXBUF = TransmitRegAddr;
IF (RXByteCtr)
MasterMode = SWITCH_TO_RX_MODE;//现在需要开始接收
设计
MasterMode = TX_DATA_MODE;//继续传输发送缓冲器中的数据
}
休息;
案例 TX_LSB_MODE:
UCB1TXBUF = TransmitRegAddr_2;//LSB
//UCB1TXBUF = TransmitRegAddr_1;//LSB
IF (RXByteCtr)
MasterMode = SWITCH_TO_RX_MODE;//现在需要开始接收
设计
MasterMode = TX_DATA_MODE;//继续传输发送缓冲器中的数据
休息;
案例 SWITCH_TO_RX_MODE:
UCB1IE |= UCRXIE;//启用 RX 中断
UCB1IE &&~μ P UCTXIE;//禁用 TX 中断
UCB1CTLW0并且=~Ω UCTR;//切换到接收器
MasterMode = RX_DATA_MODE;//状态状态是接收数据
UCB1CTLW0 |= UCTXSTT;//发送重复启动
if (RXByteCtr =1)

因为这是 N-1字节,所以必须发送 STOP
while ((UCB1CTLW0和 UCTXSTT));
UCB1CTLW0 |= UCTXSTP;//发送停止条件
}
休息;

实例 TX_DATA_MODE:
IF (TXByteCtr)

UCB1TXBUF = TransmitBuffer[TransmitIndex+];// DATA=9
// UCB2CTLW0 |= UCTXSTP;
TXByteCtr --;
}
设计

//完成传输
UCB1CTLW0 |= UCTXSTP;//发送停止条件
MasterMode = IDLE_MODE;
UCB1IE &&~μ P UCTXIE;//禁用 TX 中断
_BIC_SR_REGISTER_ON_EXIT (CPUOFF);//退出 LPM0
}
休息;

默认值:
___ no_operation();
休息;
}
休息;
默认值:中断;
}
}

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

    如果您有逻辑分析仪、那么最好在这里放置信号、例如 Saeae、这样可以轻松地识别问题  

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

    我不说寄存器、但如果您使用4线模式、CS 线路会针对每个字节进行切换。 这可能会取消 EEPROM 端的事务。 您可能需要使用3线模式并手动控制 CS 的 GPIO。

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

    在我看来、如果你正好读取1个字节、你不会发出一个停止(UCTXSTP)并且总线将挂起。 否则、我不会看到任何明显错误的内容。 [如果使用"插入"->"代码"、阅读会更容易]

    我在这里看不到您的 main()程序。

    如何判断写入超过1个字节失败? NACK? 读回不匹配? 断点? 示波器?

    人们经常会遇到的问题:

    1)使用"页面写入"时、EEPROM 地址很重要、因为只能在单个(64字节)页面内写入。 [参考文献 DOC0670、第10页]。 (如果您想知道、字节写入只是一个1字节的页写入;由于它不能跨越页边界、因此说明更简单。)

    2) 2)在执行任何写入操作后、需要等待 TWR=5ms [请参阅表4]然后再与器件通信。 在此期间、器件将 NACK。

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

    int main (void)

    unsigned int guiDigit1=0、guiDigit2=0;

    无符号长整型数据= 0;

    I2C_4.54 Master_Write (0x50、0x05,5555、4);
    __delay_cycles (1000);


    I2C_4.54 Master_Read (0x50、地址、1);
    __delay_cycles (500);
    guiDigit1=(unsigned int)((unsigned int)(ReceiveBuffer[1]<<8)|ReceiveBuffer[0]);

    guiDigit2=(unsigned int)(((ReceiveBuffer[3]<<8)|ReceiveBuffer[2]));

     data = ((unsigned long)((unsigned long)((unsigned long) guiDigit2<<8)<<8)|guiDigit1));

    返回0;

    }

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

    1)我看不到你在哪里调用 InitI2C()

    2)迟早你需要做一个"PM5CTL0 &=~μ s LOCKLPM5;"

    3) 1000周期延迟(在1MHz 处)为1ms、而不是 TWR=5ms。

    4) >  I2C_NFC Master_Write (0x50、0x05,5555、4);

       根据您之前的帖子、5555是"unsigned char *"、而不是整数。 我怀疑您没有在地址5555输入任何内容。 您可能想要这样的东西:

       > unsigned long dat = 5555;

       >  I2C_SON Master_Write (0x50、0x05、(unsigned char *)&dat、4);

    5) > I2C_I2C Master_Read (0x50、地址、1);

       写入的是4个字节、但读回1。 (另外、如何定义"地址"?) 也许您的意思是:

       > I2C_4.05(0x50,Address,4 Master_Read );

    ——

    我有点惊讶的是,编译器没有告诉你(2)和(4)特别是.