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.

[参考译文] MSP430FR5969:I2C 至 FT24C256A EEPROM 不起作用

Guru**** 2445440 points
Other Parts Discussed in Thread: MSP430FR5969

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

https://e2e.ti.com/support/microcontrollers/msp-low-power-microcontrollers-group/msp430/f/msp-low-power-microcontroller-forum/1517023/msp430fr5969-i2c-to-ft24c256a-eeprom-wont-work

器件型号:MSP430FR5969

工具/软件:

您好:

我目前正在使用 MSP430FR5969和 I2C 协议在 FT24C256A EEPROM 上写入数据。 我正在使用 MSP430FR5969 LaunchPad、并且将 P1.6和 P1.7用于我的 SCL 和 SDA。  

我已将 a0、A1和 A2引脚连接到 GND、从而使地址为1010000 (0x50)。 当我尝试使用我代码中的写函数(代码如下)发送数据时   、我一直卡在第二个 while (!(UCB0IFG 和 UCTXIFG));该函数与我所做的研究意味着 EEPROM 不会发回 ACK。 如何解决此问题?

我还测量了 SCL 和 SDA 线、并观察到 SCL 上没有我预期的块信号。 同样、当我测量 SDA 线时、线路上的信号为高电平、当我发送一个起始位(使用 UCB0CTLW0 |= UCTR + UCTXSTT;)时、信号也会变为低电平。  我的问题是、我的代码是否有问题?

#include

#define EEPROM_ADDR 0x50


void i2c_init (void){
// zet pinfunctie voor I2C
P1SEL1 || BIT6 + BIT7;
P1SEL0且=~Ω(BIT6 + BIT7);

// zet eUSCI_B0 in 复位
UCB0CTLW0 = UCSWRST;

//配置器:I2C 主器件
UCB0CTLW0 |= UCMODE_3 + UCMST + UCSYNC + UCSSEL_SMCLK;
UCB0BRW = 160;// SCL = SMCLK/160 =~100kHz bij 16 MHz
UCB0I2CSA = EEPROM_ADDR;
UCB0CTLW0 &&~UCSWRST;// Haal uit 复位
}

void i2c_write_byte (unsigned int mem_addr、unsigned char 数据){
while (UCB0STATW 和 UCBBUSY);// wacht tot bus vrij is
UCB0CTLW0 |= UCTR + UCTXSTT;//主发送器、开始

while (!(UCB0IFG 和 UCTXIFG));
UCB0TXBUF =(mem_addr >> 8)& 0xFF;

while (!(UCB0IFG 和 UCTXIFG));
UCB0TXBUF = mem_addr 和0xFF;// LAG 字节

while (!(UCB0IFG 和 UCTXIFG));
UCB0TXBUF = DATA;// Gegevensbyte

while (!(UCB0IFG 和 UCTXIFG));
UCB0CTLW0 |= UCTXSTP;//停止

(UCB0CTLW0和 UCTXSTP);
}

unsigned char i2c_read_byte (unsigned int mem_addr){
unsigned char val;

(UCB0STATW 和 UCBBUSY);
UCB0CTLW0 |= UCTR + UCTXSTT;//传输开始

while (!(UCB0IFG 和 UCTXIFG0));
UCB0TXBUF = mem_addr >> 8;

while (UCB0IFG 和 UCTXIFG0);
UCB0TXBUF = mem_addr 和0xFF;

while (UCB0IFG 和 UCTXIFG0);
UCB0CTLW0 &=~UCTR;//开关导航接收
UCB0CTLW0 |= UCTXSTT;//重复启动

while (UCB0CTLW0和 UCTXSTT);// wacht tot start klaar
UCB0CTLW0 |= UCTXSTP;

VAL = UCB0RXBUF;

返回值;
}

int main (void){
WDTCTL = WDTPW | WDTHOLD;// Stop DE WATCHDOG TIMER
PM5CTL0 &=~LOCKLPM5;// ZET GPIO 引脚活动(特定于 VOOR FRAM)

// zet P1.3、P1.4、P1.5 en P3.0 als 在 Trek ze Laag 中输出
P1DIR |= BIT3 | BIT4 | BIT5;//输出
P1OUT &=~(BIT3 | BIT4 | BIT5);// zet omlaag

P3DIR |= BIT0;
P3OUT &=~BIT0;

// zet p4.3 als 在 Trek die omhog
P4DIR |=位3;
P4OUT |= BIT3;

I2C_init ();// Initializeer I2C
//__delay_cycles (160000);// EEPROM 预热 tijd
//
//// Schrijf een byte naar de EEPROM op geheugenadres 0x00
// StartStopTest (0x00);

__delay_cycles (320000);// EEPROM 预热 tijd

// Schrijf een byte naar de EEPROM op geheugenadres 0x00
I2C_WRITE_BYTE (0x50、0x42);

__delay_cycles (320000 );/// wacht even voor de EEPROM om te schrijven

// Lees de byte terug van geheugenadres 0x00
unsigned char val = i2c_read_byte (0x0000);

// Stop de uitvoering、gebruik een breakpoint hier om "val" te bekijken
while (1);

}

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

    i2c_write_byte 中第二个 UCTXIFG 检查的挂起与获得 NACK 一致。 如果您暂停在调试器中、您是否看到 UCB0IFG:UCNACKIFG=1?

    -----

    您是否相当确定它是 i2c_write_byte()而不是 i2c_read_byte()挂起?

    我在问,因为我在 i2c_read_byte ()中看到了这个(两次):

    while (UCB0IFG & UCTXIFG0);

    其中应该是:

    > while (!(UCB0IFG & UCTXIFG0));

    性能。

    -----

    我不太确定您的意思是" SCL 上没有块信号"。 您指的是时钟延展吗?

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

    我已经检查了 UCB0IFG:UCNACKIFG、该值等于1。  
    是的,我确信它是 i2c_write_byte(),因为我使用中断点来确定程序被卡住的位置,它在 i2c_write_byte()中。  
    我在 i2c_read_byte ()中尝试了一些操作,但它确实运行了哪些操作不应该正确?

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

    好的、抱歉。 借助 SCL 上的块信号、我意味着时钟将其从高电平拉至低电平、然后从低电平拉至高电平。 当我测量它时、它只是保持在高电平

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

    NACK (以及 SCL 上明显缺乏活动)表明存在更基本的内容。 PSEL 设置看起来正确。 我(亲自)还要确保 EEPROM 器件已通电、A0-A2和上拉电阻紧密连接、并且我没有无意中使 SDA/SCL 反向。  

    听起来您有一个示波器轨迹。 这是你可以发布的东西吗?

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

    第一个 UCTXIFG 在 STT 之后很快出现;后续的 UCTXIFG 根据 SCL 速度进行起搏。  READ 函数中的正测试(while (UCTXIFG))可能会在 TXIFG 再次置位之前发生、因此根本不会旋转。 尤其如此、因为 I2C 时钟太慢。

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

    其中:当 BRW=160时、1MHz 时钟为(I2C/160)=6.25kHz、这非常慢。 I2C 不要求最低时钟速度、并且数据表(DS24C256-A2)未指定最低时钟速度。 同样、您可能需要设置例如 BRW=10 (100kHz);我建议这样做是因为大约一个小时前我从未听说过这家制造商/设备、我们想知道最低时钟是否是他们不会测试的临界情况。

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

    未经请求:看起来您正在写入 EEPROM 位置0x50、但正在读取 位置0x00。 听起来你还没有遇到这种差异,但我想你最终会.

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

    尊敬的 Sytze:
    我提出了使时钟频率为100KHz 的建议、因为这是我们建议用于 I2C 通信的最低频率。

    此致、

    Diego Abad

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

    我已经查看了所有连接、发现我已将 A0、A1、A2、WP 设置为高电平。 这是个问题、因此现在我已将它们连接到 GND、并检查了其余的连接、所有连接都应该正确连接。  SDA 和 SCL 也正确连接。

    我还设置了 BRW = 10。 我在某处读到 SMCLK 是16MHz、但我可能是错的、这就是为什么是160。 我已经根据你的建议改变了一切。  

    我可以给您展示示波器的图片、只是它只显示 SDA 为高电平、SCL 为高电平。 当我发送起始位时、SDA 线为低电平、SCL 仍为高电平。 所以我认为这与没有得到承认有关、但我不知道如何解决这个问题。

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

    我已经重新连接了 SCL 和 SDA 线、出于某种原因、它现在都可以正常工作。 感谢您的帮助!!

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

    我很高兴您能让它正常工作。

    同时、我尝试了 CAT24C512的代码、并注意到我需要添加:

    > UCB0IFG &=~(UCRXIFG | UCTXIFG );

    添加额外的读取和写入函数。 症状是由于陈旧的 IFG 而错误回读。