STM32F103驅動M24256 256k存儲芯片進行讀寫


0 摘要

M24256 是一個256k的存儲芯片,本文將主要講解如何采用模擬IIC實現對M24256的讀寫驅動操作。並且使用Proteus進行仿真驗證。處理器采用STM32F103,使用STM32CubeMX和Keil5進行聯合開發。

1 所使用的軟件

2 M24256介紹

M24256ST公司的一款256k EEPROM存儲芯片,其具有以下特點。

  • M24256具有256kbit EEPROM內容,每頁可寫入的內容為64bytes(Page Size = 64 bytes)
  • Single supply voltage and high speed
  • Write:
    • – Byte Write within 5 ms
    • – Page Write within 5 ms
  • Random and sequential Read modes
  • Write protect of the whole memory array 所有內存整列均可以進行寫保護
  • Enhanced ESD/Latch-Up protection
  • More than 4 million Write cycles
  • More than 200-years data retention

       

M24256引腳接口如表2-1所示:

表2-1 芯片引腳定義

Signal name

Function

Direction

E2E1E0

Chip Enable

Input

SDA

Serial Data

I/O

SCL

Serial Clock

Input

WC(低電平有效)

Write Control

Input

VCC

Supply voltage

  

VSS

Ground

  

   

通過控制E2E1E0的電平關系來修改芯片的地址,也就是說每一個IIC總線上最多可以掛接8個M24256存儲芯片。

Write Control引腳用於保護寫操作,可以用來保護存儲器的整個內容免受意外寫操作。將寫控制(WC)驅動為高電平時,將禁止對整個存儲器陣列進行寫操作。 當寫控制(WC)被驅動為低電平或懸空時,使能寫操作。 將寫控制(WC)驅動為高電平時,確認器件選擇和地址字節,不確認數據字節。

3 M24256設備地址

   

表3-1 芯片地址(設備選擇代碼)

通過硬件電路定義E2E1E0的電平來定義設備的地址,其中最低位為讀寫標志位,當bit0=1時處於Read模式,反之處於Write模式。而高八位為固定地址,通常使用的是Memory array情況,所以高八位為A

如果在設備選擇代碼上發生匹配,則相應的設備會在第9位時間內給出串行數據(SDA)的確認。 如果設備與設備選擇代碼不匹配,則會從總線上取消選擇自身,並進入待機模式。

   

4 M24256寫操作

當芯片處於非寫保護狀態,即WC為0時對應的時序圖如圖4-1所示。

表4-1 M24256寫時序(WC為低電平)

由圖可以看出,M24256支持兩種形式的寫操作,分別是按字節寫入和按頁寫入。接下來將針對其時序圖逐一進行分析。

4.1 Byte Write Mode

按字節寫入的時序圖如圖4-2所示。

圖4-2 Byte Write Mode 時序圖

由圖可知,該模式下,設備僅向指定地址中寫入一個字節的數據。其包含的時序過程如下:

Start

發送設備地址

1010 E2E1E0 0

ACK

待寫入的設備地址高8位

Byte addr

ACK

待寫入的設備地址低8位

Byte addr

ACK

待寫入的八位數據

Data in

ACK

Stop

對應的寫入代碼如下:

uint8_t W24256_Byte_Write(uint8_t WriteData,uint16_t address)

{

    uint16_t usAddr;

    usAddr = address;  

    /* 第1步:I2C總線啟動 */

    IIC_Start();

    /* 第2步:起控制字,高7bit是地址,bit0是讀寫控制位,0表示1表示 */

    IIC_Send_Byte(EEPROM_DEV_ADDR | I2C_WR);    /* 此指令 */

    /*第3步:等待ACK信*/

    if (IIC_Wait_Ack() != 0)

    {

        goto cmd_fail;  /* EEPROM器件無 */

    }

    /* 第4步:送字地址,送地址直接高八位*/

    IIC_Send_Byte((uint8_t)(usAddr>> 8));

    /*第5步:等待ACK信*/

    if (IIC_Wait_Ack() != 0)

    {

        goto cmd_fail;  /* EEPROM器件無 */

    }

    /* 第6步:送字地址,送地址直接低八位*/

    IIC_Send_Byte((uint8_t)(usAddr&0x00ff));

    /*第7步:等待ACK信*/

    if (IIC_Wait_Ack() != 0)

    {

        goto cmd_fail;  /* EEPROM器件無 */

    }

    /* 第8步: */

    IIC_Send_Byte(WriteData);

    /*第7步:等待ACK信*/

    if (IIC_Wait_Ack() != 0)

    {

        goto cmd_fail;  /* EEPROM器件無 */

    }

    IIC_Stop();

    return 1;

cmd_fail: /* 命令行失后,切記發送停止信,避免影I2C總線上其他設備 */

    /* I2C總線停止信 */

    IIC_Stop();

    return 0;

}

4.2 Page Write Mode

按頁寫入的時序圖如圖4-3所示。

圖4-3 Page Write Mode

由圖可知,該模式下,設備可以向指定頁中寫入指定字節的數據,可寫入的字節數小於等於64byte。其包含的時序過程如下:

Start

發送設備地址

1010 E2E1E0 0

ACK

待寫入的設備地址高8位

Byte addr

ACK

待寫入的設備地址低8位

Byte addr

ACK

待寫入的八位數據

Data in

如果繼續寫入,則ACK

停止寫入,則NACK

STOP

對應的按頁寫入代碼如下:

uint8_t W24256_Page_Write(uint8_t *WriteBuf, uint16_t Page, uint16_t Size)

{

    uint16_t i,m;

    uint16_t usAddr;

      

    /*

     * 串行EEPROM不像操作可以連續讀多字,每次操作只能在同一page。

     * 24xx02,page size = 8

     * 簡單理方法:按字節寫操作模式,沒寫1,都送地址

     * 了提高連續寫的效率: 本函采用page wirte操作。

     */

   

    usAddr = Page * 0x0040;

    for (i = 0; i < Size; i++)

    {

        /* 當發送第1或是面首地址,需要重新啟動和地址 */

        if ((i == 0) || (usAddr & (EEPROM_PAGE_SIZE - 1)) == 0)

        {

//          /* 第0步:停止信啟動內操作 */

//          IIC_Stop();

              

            /* 通過檢查器件答的方式,判斷內操作是否完成, 一般小於 10ms            

                CLK200KHz查詢數為30次左右

            */

            for (m = 0; m < 1000; m++)

            {              

                /* 第1步:I2C總線啟動 */

                IIC_Start();

                  

                /* 第2步:起控制字,高7bit是地址,bit0是讀寫控制位,0表示1表示 */

                IIC_Send_Byte(EEPROM_DEV_ADDR | I2C_WR);    /* 此指令 */

                  

                /* 第3步:送一個時鍾,判器件是否正確應 */

                if (IIC_Wait_Ack() == 0)

                {

                    break;

                }

            }

            if (m  == 1000)

            {

                goto cmd_fail;  /* EEPROM器件 */

            }

          

            /* 第4步:送字地址,送地址直接高八位*/

            IIC_Send_Byte((uint8_t)(usAddr>> 8));

            /*第五步:等待ACK信*/

            if (IIC_Wait_Ack() != 0)

            {

                goto cmd_fail;  /* EEPROM器件無 */

            }

            /* 第6步:送字地址,送地址直接低八位*/

            IIC_Send_Byte((uint8_t)(usAddr&0x00ff));

            /* 第5步:等待ACK */

            if (IIC_Wait_Ack() != 0)

            {

                goto cmd_fail;  /* EEPROM器件無 */

            }

        }

      

        /* 第6步: */

        IIC_Send_Byte(WriteBuf[i]);

      

        /* 第7步:ACK */

        if (IIC_Wait_Ack() != 0)

        {

            goto cmd_fail;  /* EEPROM器件無 */

        }

   

        usAddr++;   /* 地址增1 */      

    }

      

    /* 命令行成功,I2C總線停止信 */

    IIC_Stop();

    return 1;

   

cmd_fail: /* 命令行失后,切記發送停止信,避免影I2C總線上其他設備 */

    /* I2C總線停止信 */

    IIC_Stop();

    return 0;

}

注:M24256有256kbit空間,每一頁的大小Page Size =64,所以計算可得頁的取值范圍為:256*1024/8/64 = 512 頁。

5 M24256讀操作

WC引腳的電平狀態對讀操作無效,所以其對應的時序圖入圖5-1所示。

圖5-1 Read mode sequences

由圖5-1可知,M24256共有三種模式的讀操作,包括隨機地址讀取(Random Address Read)、當前地址(Current Address Read)、順序讀取(Sequential Read)

下面主要針對隨機地址讀取和順序讀取兩種模式進行分析。其余分析類似。

5.1 Random Address Read

圖5-2 Random Address Read 時序圖

由圖可知,該模式下,僅從設備的指定地址中讀取一個字節的數據。其包括的時序如下:

Start

設備地址和控制字

1010 E2E1E0 0

ACK

待寫入的設備地址高8位

Byte addr

ACK

待寫入的設備地址低8位

Byte addr

ACK

Start

重啟IIC總線

設備地址和控制字

1010 E2E1E0 1

ACK

讀出的數據

Data out

NACK

Stop

對應的代碼如下:

uint8_t W24256_Byte_Read( uint16_t Address)

{

    uint16_t uAddress;

    uint8_t ReadData;

    uAddress = Address;

    /* 第1步:I2C總線啟動 */

    IIC_Start();    

    

    /* 第2步:起控制字,高7bit是地址,bit0是讀寫控制位,0表示1表示 */

    IIC_Send_Byte(EEPROM_DEV_ADDR | I2C_WR);    /* 此指令 */  

    

    /* 第3步:等待ACK */

    if (IIC_Wait_Ack() != 0)

    {

        IIC_Stop(); /* EEPROM器件無 */

    }

    

    /* 第4步:送字地址高8位 */

    IIC_Send_Byte((uint8_t)(uAddress>>8));  

    

    /* 第5步:等待ACK */

    if (IIC_Wait_Ack() != 0)

    {

        IIC_Stop(); /* EEPROM器件無 */

    }  

    /* 第6步:送字地址低八位 */

    IIC_Send_Byte((uint8_t)uAddress&0xff);  

    

    /* 第7步:等待ACK */

    if (IIC_Wait_Ack() != 0)

    {

        IIC_Stop(); /* EEPROM器件無 */

    }

    /* 第8步:重新啟動I2C總線。前面的代的目的向EEPROM送地址,下面 */

    IIC_Start();    

    

    /* 第9步:起控制字,高7bit是地址,bit0是讀寫控制位,0表示1表示 */

    IIC_Send_Byte(EEPROM_DEV_ADDR | I2C_RD);    /* 此指令 */

      

    /* 第10步:ACK */

    if (IIC_Wait_Ack() != 0)

    {

        IIC_Stop(); /* EEPROM器件無 */

    }  

      

   

    /* 第11步:保存*/

    ReadData = IIC_Read_Byte(); /* 1 */

    /*第12步:NACK命令*/    

    IIC_NAck(); /* 最后1節讀完后,CPUNACK信(驅動SDA = 1) */

   

    /*第13步:I2C總線停止信 */

    IIC_Stop();

    return ReadData;    /* 行成功 */

}

5.2 Sequention Random Read

圖5-3 Sequention Random Read 時序圖

由圖可知,該模式下,可以向指定地址中讀取指定數目的數據。其包括的時序如下:

Start

設備地址和控制字

1010 E2E1E0 0

ACK

待寫入的設備地址高8位

Byte addr

ACK

待寫入的設備地址低8位

Byte addr

ACK

Start

重啟IIC總線

設備地址和控制字

1010 E2E1E0 1

ACK

讀出的數據

Data out

如果到達要讀取數據個數,發送NACK,反之發送ACK

Stop

其對應的代碼如下:

/**

  * 函功能: 串行EEPROM指定地址處開取若干

  * 參數: ReadBuf : 存放到的據的緩沖區

  *           Address : 起始地址  

  *           Size : 度,

  * 返 回 :  0 表示失1表示成功

  *     明:無

  */

uint8_t W24256_Page_Read(uint8_t *ReadBuf, uint16_t Page, uint16_t Size)

{

    uint16_t i;

    uint16_t uAddress;

    /* 采用串行EEPROM隨即讀取指令序列,連續讀取若干字 */

    uAddress = Page * 0x0040;

    /* 第1步:I2C總線啟動 */

    IIC_Start();    

    

    /* 第2步:起控制字,高7bit是地址,bit0是讀寫控制位,0表示1表示 */

    IIC_Send_Byte(EEPROM_DEV_ADDR_Page | I2C_WR);   /* 此指令 */  

    

    /* 第3步:等待ACK */

    if (IIC_Wait_Ack() != 0)

    {

        goto cmd_fail;  /* EEPROM器件無 */

    }

    

    /* 第4步:送字地址高8位 */

    IIC_Send_Byte((uint8_t)(uAddress>>8));  

    

    /* 第5步:等待ACK */

    if (IIC_Wait_Ack() != 0)

    {

        goto cmd_fail;  /* EEPROM器件無 */

    }  

    /* 第6步:送字地址低八位 */

    IIC_Send_Byte((uint8_t)uAddress&0xff);  

    

    /* 第7步:等待ACK */

    if (IIC_Wait_Ack() != 0)

    {

        goto cmd_fail;  /* EEPROM器件無 */

    }

    /* 第8步:重新啟動I2C總線。前面的代的目的向EEPROM送地址,下面 */

    IIC_Start();    

    

    /* 第7步:起控制字,高7bit是地址,bit0是讀寫控制位,0表示1表示 */

    IIC_Send_Byte(EEPROM_DEV_ADDR_Page | I2C_RD);   /* 此指令 */

      

    /* 第8步:ACK */

    if (IIC_Wait_Ack() != 0)

    {

        goto cmd_fail;  /* EEPROM器件無 */

    }  

      

    /* 第9步:循環讀 */

    for (i = 0; i < Size; i++)

    {

        ReadBuf[i] = IIC_Read_Byte();   /* 1 */

          

        /* 每1后,需要Ack, 最后一不需要Ack,Nack */

        if (i != Size - 1)

        {

            IIC_Ack();  /* 中節讀完后,CPUACK信(驅動SDA = 0) */

        }

        else

        {

            IIC_NAck(); /* 最后1節讀完后,CPUNACK信(驅動SDA = 1) */

        }

    }

    /* I2C總線停止信 */

    IIC_Stop();

    return 1;   /* 行成功 */

   

cmd_fail: /* 命令行失后,切記發送停止信,避免影I2C總線上其他設備 */

    /* I2C總線停止信 */

    IIC_Stop();

    return 0;

}

   

6 M24256讀寫測試

使用Proteus 和Stm32CubeMX keil 聯合開發,對M24256的讀寫測試進行仿真分析。

圖6-1 仿真搭建

6.1 按字節讀寫測試結果

代碼如下

W24256_Byte_Write(0x01,0x0000);

HAL_Delay(100);

W24256_Byte_Read(0x0000);

HAL_Delay(500);

圖6-2 仿真結果

第一行

S

A0

A

00

A

00

A

01

A

P

向1101 000x設備的0x0000地址寫入0x01數據

   

第二行

S

A0

A

00

A

00

A

Sr

A1

A

01

N

P

從1101 000x設備的0x0000地址讀出數據,讀出的數據為0x01

   

6.2 按頁讀寫測試結果

uint8_t Data[3]={0x01,0x05,0xff};

uint8_t DataRead[3]={0x00,0x00,0x00};

W24256_Page_Write(Data,10,3);

HAL_Delay(100);

W24256_Page_Read(DataRead,10,3);

HAL_Delay(500);

圖6-3 仿真結果

第一行

S

A0

A

02

A

80

A

01

A

05

A

FF

A

P

向1101 000x設備的第10頁(0X0280)寫入0x01、0X05、0XFF三個字節數據

   

第二行

S

A0

A

02

A

80

A

Sr

A1

A

01

A

05

A

FF

N

P

從1101 000x 設備的第10頁(0x0280)讀取3個字節數據,讀出的數據為 0x01、0x05、0xff

   

6.3 按字節讀寫多個字節測試

    uint8_t Data[3]={0x01,0x05,0xff};

    uint8_t DataRead[3]={0x00,0x00,0x00};

    W24256_Write(0x0000,Data,3);

    HAL_Delay(100);

    W24256_Read(0x0000,DataRead,3);

    HAL_Delay(500);

   

圖6-4 仿真結果

第一行

S

A0

A

00

A

00

A

01

A

P

向1010 000x設備的0x0000地址寫入0x01數據

第二行

S

A0

A

00

A

01

A

05

A

P

向1010 000x設備的0x0001地址寫入0x05數據

第三行

S

A0

A

00

A

02

A

FF

A

P

向1010 000x設備的0x0002地址寫入0xFF數據

   

第四行

S

A0

A

00

A

00

A

Sr

A1

A

01

N

P

從1010 000x設備的0x0000地址讀取數據,結果為0x01

第五行

S

A0

A

00

A

01

A

Sr

A1

A

05

N

P

從1010 000x設備的0x0001地址讀取數據,結果為0x05

第六行

S

A0

A

00

A

02

A

Sr

A1

A

FF

N

P

從1010 000x設備的0x0002地址讀取數據,結果為0xFF

 

 

制作不易,如有錯誤或者不好理解的地方請留言

如果需要仿真源文件,請聯系EMAIL:whl1457139188@163.com

並添加QQ:975107705

請注明M24256 讀寫測試


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM