簡體   English   中英

如何將串行數據寫入 I2C EEPROM?

[英]How to write serial data ino I2C EEPROM?

我對微控制器真的很陌生,我想問我是否想讀取三個不同傳感器的值並將這些值連續存儲在 I2C EEPROM 中,每個值在地址中占用 6 個字節,我該如何使用I2C總線? 特別是我不確定為每個值指定高字節和低字節。 我找到了一個將值寫入 EEPROM 的示例代碼:

void eeprom_write(uint16_t data){ //Writes to the EEPROM
 LL_I2C_GenerateStartCondition(I2C1); //START
        while(!LL_I2C_IsActiveFlag_SB(I2C1));

        LL_I2C_TransmitData8(I2C1, EEPROMADR); //CONTROL BYTE (ADDRESS + WRITE)
        while(!LL_I2C_IsActiveFlag_ADDR(I2C1));
        LL_I2C_ClearFlag_ADDR(I2C1);

        LL_I2C_TransmitData8(I2C1, 0x00); //ADDRESS HIGH BYTE
        while(!LL_I2C_IsActiveFlag_TXE(I2C1));

        LL_I2C_TransmitData8(I2C1, 0x00); //ADDRESS LOW BYTE
        while(!LL_I2C_IsActiveFlag_TXE(I2C1));

        LL_I2C_TransmitData8(I2C1, (char)(data >> 8)); //DATA HIGH BYTE
        while(!LL_I2C_IsActiveFlag_TXE(I2C1));

 LL_I2C_TransmitData8(I2C1, (char)(data & 0x00FF)); //DATA LOW BYTE
        while(!LL_I2C_IsActiveFlag_TXE(I2C1));

        LL_I2C_GenerateStopCondition(I2C1); //STOP
  }

但我不知道如何寫剩下的兩個。 有人能幫助我嗎? 另外,我在 Keil 軟件上編程並使用了 C 語言。 謝謝!

EEPROM 器件具有可存儲數據的內部地址范圍。 您的eeprom_write使用硬編碼地址 0x0000,這樣每次調用它都會覆蓋地址 0x0000 的先前數據。 您應該更改 function 原型以傳遞地址,以便您可以在整個 EEPROM 中寫入數據。

void eeprom_write_word_at_addr(uint16_t data, uint16_t addr){ //Writes to the EEPROM
    LL_I2C_GenerateStartCondition(I2C1); //START
    while(!LL_I2C_IsActiveFlag_SB(I2C1));

    LL_I2C_TransmitData8(I2C1, EEPROMADR); //CONTROL BYTE (ADDRESS + WRITE)
    while(!LL_I2C_IsActiveFlag_ADDR(I2C1));
    LL_I2C_ClearFlag_ADDR(I2C1);

    LL_I2C_TransmitData8(I2C1, (char)(addr >> 8)); //ADDRESS HIGH BYTE
    while(!LL_I2C_IsActiveFlag_TXE(I2C1));

    LL_I2C_TransmitData8(I2C1, (char)(addr & 0x00FF)); //ADDRESS LOW BYTE
    while(!LL_I2C_IsActiveFlag_TXE(I2C1));

    LL_I2C_TransmitData8(I2C1, (char)(data >> 8)); //DATA HIGH BYTE
    while(!LL_I2C_IsActiveFlag_TXE(I2C1));

    LL_I2C_TransmitData8(I2C1, (char)(data & 0x00FF)); //DATA LOW BYTE
    while(!LL_I2C_IsActiveFlag_TXE(I2C1));

    LL_I2C_GenerateStopCondition(I2C1); //STOP
}

此外,您的 function 寫入一個 2 字節數據值,但我認為您想寫入三個2 字節值。 所以你可以調用上面的 function 三次,每次調用更新地址。 或者您可以編寫另一個 function 接受所有三個值並將它們全部寫入一次 I2C 傳輸。 每次寫入時 EEPROM 的內部地址都會自動遞增,因此您只需指定起始地址。 (閱讀 EEPROM 的數據表以確認自動增量並查看是否有任何分頁限制。)

void eeprom_write_3words_at_addr(uint16_t data1, uint16_t data2, uint16_t data3, uint16_t addr){ //Writes to the EEPROM
    LL_I2C_GenerateStartCondition(I2C1); //START
    while(!LL_I2C_IsActiveFlag_SB(I2C1));

    LL_I2C_TransmitData8(I2C1, EEPROMADR); //CONTROL BYTE (ADDRESS + WRITE)
    while(!LL_I2C_IsActiveFlag_ADDR(I2C1));
    LL_I2C_ClearFlag_ADDR(I2C1);

    LL_I2C_TransmitData8(I2C1, (char)(addr >> 8)); //ADDRESS HIGH BYTE
    while(!LL_I2C_IsActiveFlag_TXE(I2C1));

    LL_I2C_TransmitData8(I2C1, (char)(addr & 0x00FF)); //ADDRESS LOW BYTE
    while(!LL_I2C_IsActiveFlag_TXE(I2C1));

    LL_I2C_TransmitData8(I2C1, (char)(data1 >> 8)); //DATA HIGH BYTE
    while(!LL_I2C_IsActiveFlag_TXE(I2C1));

    LL_I2C_TransmitData8(I2C1, (char)(data1 & 0x00FF)); //DATA LOW BYTE
    while(!LL_I2C_IsActiveFlag_TXE(I2C1));

    LL_I2C_TransmitData8(I2C1, (char)(data2 >> 8)); //DATA HIGH BYTE
    while(!LL_I2C_IsActiveFlag_TXE(I2C1));

    LL_I2C_TransmitData8(I2C1, (char)(data2 & 0x00FF)); //DATA LOW BYTE
    while(!LL_I2C_IsActiveFlag_TXE(I2C1));

    LL_I2C_TransmitData8(I2C1, (char)(data3 >> 8)); //DATA HIGH BYTE
    while(!LL_I2C_IsActiveFlag_TXE(I2C1));

    LL_I2C_TransmitData8(I2C1, (char)(data3 & 0x00FF)); //DATA LOW BYTE
    while(!LL_I2C_IsActiveFlag_TXE(I2C1));

    LL_I2C_GenerateStopCondition(I2C1); //STOP
}

或者,如果我對三個 2 字節數據值有誤,那么您可以像這樣將包含所有數據的數組傳遞給 function。

void eeprom_write_words_at_addr(uint16_t *data, int num_words, uint16_t addr){ //Writes to the EEPROM
    LL_I2C_GenerateStartCondition(I2C1); //START
    while(!LL_I2C_IsActiveFlag_SB(I2C1));

    LL_I2C_TransmitData8(I2C1, EEPROMADR); //CONTROL BYTE (ADDRESS + WRITE)
    while(!LL_I2C_IsActiveFlag_ADDR(I2C1));
    LL_I2C_ClearFlag_ADDR(I2C1);

    LL_I2C_TransmitData8(I2C1, (char)(addr >> 8)); //ADDRESS HIGH BYTE
    while(!LL_I2C_IsActiveFlag_TXE(I2C1));

    LL_I2C_TransmitData8(I2C1, (char)(addr & 0x00FF)); //ADDRESS LOW BYTE
    while(!LL_I2C_IsActiveFlag_TXE(I2C1));

    for (int index = 0; index < num_words; ++index) {        
        LL_I2C_TransmitData8(I2C1, (char)(data[index] >> 8)); //DATA HIGH BYTE
        while(!LL_I2C_IsActiveFlag_TXE(I2C1));

        LL_I2C_TransmitData8(I2C1, (char)(data[index] & 0x00FF)); //DATA LOW BYTE
        while(!LL_I2C_IsActiveFlag_TXE(I2C1));
    }

    LL_I2C_GenerateStopCondition(I2C1); //STOP
}

只要eeprom_read function 使用相同的順序,數據的高字節/低字節順序(即endianness )可能並不重要。 但是,地址的字節順序很重要,因為 I2C EEPROM 設備首先需要地址的高字節。 請參閱 EEPROM 器件的數據表進行確認。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM