博客 / 詳情

返回

GT25C16的eeprom芯片使用

EEPROM
相關配置信息

在使用時需要置高WP和HOLD,
image

WP : 拉低進入寫保護

HOLD :拉低掛起芯片,忽略總線上通信內容

狀態寄存器

image
當RDY=0時,設備已準備好接收指令。

當RDY=1時,設備正忙。由於繁忙,設備只接受讀取狀態寄存器命令

WEN : 這表示設備的寫保護狀態。當WEN=0時,無論WPEN、WP引腳或塊保護的設置如何,都不能修改狀態寄存器和整個陣列。寫入啓用命令(WREN)可用於將WEN設置為1。在加電階段,WEN重置為0。
WREN命令為寫使能

BP0 BP1 為寫保護塊,可通過
image
選擇是否保護所選區域,內部地址為 0x000 - 0x7FF

WPEN可與WP硬件引腳一起啓用寫保護,注意 內存陣列不受此模式的保護。硬件寫保護要求設置WP=0和WPEN=1。否則,它將被禁用。如果WP已設置為低,則WPEN不能從1更改為0。
image
圖為寫保護控制
image
使用時可以直接接高電平,默認不保護,此時WPEN不起作用,由WEN控制

控制寄存器

image
依次
寫使能
寫失能
讀狀態寄存器
寫狀態寄存器
讀數據
寫數據

具體使用

設置控制寄存器

#define SPI_READ           0x03
#define SPI_WRITE          0x02
#define EEP_WREN           0x06
#define EEP_WRDI           0x04
#define SPI_READ_STATUS    0x05
#define SPI_WRITE_STATUS   0x01

e2讀狀態寄存器

static uint8_t EEPROM_Read_Status(void)
{
    uint8_t EEPROM_25LC160_CMD;
    uint8_t EEPROM_25LC160_Data;

    EEPROM_CS_ENABLE;           /* CS as low */
    EEPROM_25LC160_CMD = SPI_READ_STATUS;
    SPI_Send(SPI0_SFR, &EEPROM_25LC160_CMD, 1U);
    SPI_Receive_Process(SPI0_SFR, &EEPROM_25LC160_Data);
    EEPROM_CS_DISABLE;          /* CS as high */
    EEPROM_25LC160_Data &= 0x0F;

    return EEPROM_25LC160_Data;
}

設置保護

void EEP_set_array_protection(EEPROM_Protect_E data)
{
    /* 0x00 non protection */
    /* 0x04 upper 1/4 (180h - 1ffh) protection */
    /* 0x08 upper 1/2 (100h - 1ffh) protection */
    /* 0x0C all (000h - 1ffh) protection */
    uint8_t EEPROM_25LC160_CMD;

    Check_EEPROM_Busy();     
    EEPROM_CS_ENABLE;  /* CS as low */
    EEPROM_25LC160_CMD = EEP_WREN;  /* Write WEL */
    SPI_Send(SPI0_SFR, &EEPROM_25LC160_CMD, 1U);
    EEPROM_CS_DISABLE; /* CS as high */

    delay_us(4U);
    EEPROM_CS_ENABLE;   /* CS as low */
    EEPROM_25LC160_CMD = SPI_WRITE_STATUS;
    SPI_Send(SPI0_SFR, &EEPROM_25LC160_CMD, 1U);
    EEPROM_25LC160_CMD = (uint8_t)(data);
    SPI_Send(SPI0_SFR, &EEPROM_25LC160_CMD, 1U);
    EEPROM_CS_DISABLE;  /* CS as high */
}

主機發送 1字節

//使用輪詢方式,在頭次發送之後等待發送完成標誌和是否繁忙
 void SPI_Send_Process(SPI_SFRmap *SPIx, uint8_t *Databuf, uint8_t DataLength)
{
    uint8_t Databuf_Index = 0U;

    /* 輪詢發送數據 */
    while (Databuf_Index < DataLength)
    {
        SPI_I2S_SendData8(SPIx, Databuf[Databuf_Index]);   /* 發送數據 */
        while (SET == SPI_Get_Transmit_Buf_Flag(SPIx))
        {
            ;/* Waiting for the sending buffer to be empty */
        }

        while (SET == SPI_Get_BUSY_Flag(SPIx))
        {
            ;/* 等待SPI數據發送完成 */
        }
        Databuf_Index++;
    }
}

主機接收 1字節

static void SPI_Receive_Process(SPI_SFRmap *SPIx, uint8_t *Databuf)
{
    SPI_I2S_SendData8(SPI0_SFR, 0xFF);  /* 產生接收SCK */
    while (RESET == SPI_Get_Receive_Buf_Flag(SPI0_SFR))
    { /* 等待SPI0接收BUFFER不為空 */; }
    *Databuf = (uint8_t)SPI_I2S_ReceiveData(SPI0_SFR);
}

發送接收函數

SPI_I2S_SendData8(SPI, data)
{
  SPI->address = data;
}
 uint8_t SPI_I2S_ReceiveData(SPI)
{
uint8_t data;
  data = SPI->address;
return data;
}

等待是否忙碌,狀態寄存器0位

void Check_EEPROM_Busy(void)
{
    /* WIP(Write-In-Process),若為1則表示寫入正在進行,反之則沒有寫入正在進行 */
    while (EEPROM_Read_Status()&0x01)
    {
        ;
    }
}

寫數據

void SPI_Write_EEPROM_Process(uint16_t Address, uint8_t *Data, uint16_t Length)
{
    uint8_t Cycle_Times = 0U;
    uint16_t Data_Length = Length;
    uint8_t Address_Offset = 0U;
    uint8_t EEPROM_25LC160_CMD;
    uint16_t EEPROM_Address = Address;

    /* INT_All_Enable(FALSE); */  /* 禁止所有全局可屏蔽中斷使能位 */
    while ((Data_Length > 0U)&&(EEPROM_Address < 0x0800U))
    {
        Address_Offset = (16U - (EEPROM_Address % 16U));
        if (Data_Length > Address_Offset)
        {
            Cycle_Times = Address_Offset;
        }else{ Cycle_Times = Data_Length; }

        Check_EEPROM_Busy();
        EEPROM_CS_ENABLE;  /* CS as low */
        EEPROM_25LC160_CMD = EEP_WREN;  /* Write WEL */
        SPI_Send_Process(SPI0_SFR, &EEPROM_25LC160_CMD, 1U);
        EEPROM_CS_DISABLE; /* CS as high */

        EEPROM_CS_ENABLE;  /* CS as low */
        EEPROM_25LC160_CMD = SPI_WRITE;
        SPI_Send_Process(SPI0_SFR, &EEPROM_25LC160_CMD, 1U);

        /* 發送地址高8位 */
        EEPROM_25LC160_CMD = (uint8_t)(EEPROM_Address >> 8U);
        SPI_Send_Process(SPI0_SFR, &EEPROM_25LC160_CMD, 1U);

        /* 發送地址低8位 */
        EEPROM_25LC160_CMD = (uint8_t)EEPROM_Address;
        SPI_Send_Process(SPI0_SFR, &EEPROM_25LC160_CMD, 1U);

        while ((Cycle_Times > 0U)&&(Data_Length > 0U)&&(EEPROM_Address < 0x0800U))
        {
            SPI_Send_Process(SPI0_SFR, Data, 1U);
            Data++; Cycle_Times--; Data_Length--; EEPROM_Address++;
        }
        EEPROM_CS_DISABLE; /* CS as high */
    }
    /* INT_All_Enable(TRUE); */   /* 啓用所有全局可屏蔽中斷使能位 */
}

讀數據

void SPI_Read_EEPROM_Process(uint16_t Address, uint8_t *Data, uint16_t Length)
{
    uint8_t EEPROM_25LC160_CMD;

    /* INT_All_Enable(FALSE); */  /* 禁止所有全局可屏蔽中斷使能位 */
    Check_EEPROM_Busy();
    EEPROM_CS_ENABLE;  /* CS as low */
    EEPROM_25LC160_CMD = SPI_READ;
    SPI_Send_Process(SPI0_SFR, &EEPROM_25LC160_CMD, 1U);

    /* 發送地址高8位 */
    EEPROM_25LC160_CMD = (uint8_t)(Address >> 8U);
    SPI_Send_Process(SPI0_SFR, &EEPROM_25LC160_CMD, 1U);

    /* 發送地址低8位 */
    EEPROM_25LC160_CMD = (uint8_t)Address;
    SPI_Send_Process(SPI0_SFR, &EEPROM_25LC160_CMD, 1U);

    while (Length > 0U)
    {
        SPI_Receive_Process(SPI0_SFR, Data);
        Data++; Length--;
    }
    EEPROM_CS_DISABLE; /* CS as high */
    /* INT_All_Enable(TRUE); */   /* 啓用所有全局可屏蔽中斷使能位 */
}

user avatar
0 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.