STM32 I2C_EEPROM read and write

Publisher:丝路老君Latest update time:2018-07-15 Source: eefocusKeywords:STM32 Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

EEPROM data organization: 
EEPROM devices divide their storage matrix into pages: 
Write the picture description here

The AT24C02 EEPROM is divided into 32 pages, and each page can store 8 bytes of data. If more than 8 bytes are written to the same page, the excess will be written at the starting address of the page (that is, the part written at the beginning will be overwritten). 
In order to write a continuous buffer array to the EEPROM by page, the buffer needs to be paged. I2C_EE_BufferWrite() calculates how many pages need to be written and the write position based on the input buffer size parameter NumByteToWrite. 
After the paging is processed, I2C_EE_PageWrite() is called. This function is the lowest-level function for I2C communication with the EEPROM (it calls STM32 library functions)

EEPROM write I2C_EE_BufferWrite(); 
u8 I2c_Buf_Write[256]; 
//#define EEP_Firstpage 0x00 (add // to avoid font enlargement)

void I2C_EE_BufferWrite(u8* pBuffer, u8 WriteAddr, u16 NumByteToWrite) 

u8 NumOfPage = 0, NumOfSingle = 0, Addr = 0, count = 0;

/*Calculate the number of pages to be written and the paging*/

Addr = WriteAddr % I2C_PageSize; 

count = I2C_PageSize - Addr;

NumOfPage = NumByteToWrite / I2C_PageSize; 


if(Addr == 0)

{

    if(NumOfPage == 0)

    {

        I2C_EE_PageWrite(pBuffer,WriteAddr,NumOfSingle);

        I2C_EE_WaitEepromStandbyState(); //Check if it is in Standby state before proceeding to the next step

    }

    else

    {

        while(NumOfPage--)

        {

            I2C_EE_PageWrite(pBuffer,WriteAddr,I2C_PageSize);

            I2C_EE_WaitEepromStandbyState();

            WriteAddr += I2C_PageSize;

            pBuffer += I2C_PageSize;

        }


        if(NumOfSingle!=0)

        {

            I2C_EE_PageWrite(pBuffer,WriteAddr,NumOfSingle);

            I2C_EE_WaitEepromStandbyState();

        }

    }

}


else

{

    if(NumOfPage == 0)

    {

        I2C_EE_PageWrite(pBuffer,WriteAddr,NumOfSingle);

        I2C_EE_WaitEepromStandbyState();

    }


    else

    {

        NumByteToWrite -= count;

        NumOfPage = NumByteToWrite / I2C_PageSize;

        NumOfSingle = NumByteToWrite % I2C_PageSize;


        if(count != 0)

        {

            I2C_EE_PageWrite(pBuffer,WriteAddr,count)

            I2C_EE_WaitEepromStandbyState();

            WriteAddr += count;

            pBuffer += count;

        }


        while(NumOfPage--)

        {

            I2C_EE_PageWrite(pBuffer,WriteAddr,I2C_PageSize);

            I2C_EE_WaitEepromStandbyState();

            WriteAddr += I2C_PageSize;

            pBuffer += I2C_PageSize;

        }


        if(NumOfSingle != 0)

        {

            I2C_EE_PageWrite(pBuffer,WriteAddr,NumOfSingle);

            I2C_EE_WaitEepromStandbyState();

        }

    }

}


Here, after each call to I2C_EE_PageWrite(), an I2C_EE_WaitEepromStandbyState() is called;


void I2C_EE_WaitEepromStandbyState(void) 

vu16 SR1_Tmp = 0;


    do

    {

        I2C_GenerateSTART(I2C1, ENABLE);


        SR1_Tmp = I2C_ReadRegister(I2C1, I2C_Register_SR1);


        I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);

    }while(!(I2C_ReadRegister(I2C1, I2C_Register_SR1) & 0x0002));


    I2C_ClearFlag(I2C1, I2C_FLAG_AF);


    I2C_GenerateSTOP(I2C1, ENABLE);


Here, the characteristic of EEPROM that it will not respond to the host's request during the time of starting the data writing cycle after receiving the data is utilized. This library function is used to send the start signal in a loop. If the EEPROM's response is detected, it means that the EEPROM has completed the data writing in the previous step and entered the Standby state, and the next step can be performed.


The lowest level function of EEPROM for I2C communication is I2C_EE_PageWrite() 

void I2C_EE_PageWrite(u8* pBuffer, u8 WriteAddr, u8 NumByteToWrite) 

/ Make sure the SDA bus is idle before doing I2C communication / 

while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));


I2C_GenerateSTART(I2C1, ENABLE);

while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));


I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);

while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));


I2C_SendData(I2C1, WriteAddr);

while(! I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));


while(NumByteToWrite--)

{

    I2C_SendData(I2C1, *pBuffer);


    pBuffer++;


    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMIT)TED));

}

I2C_GenerateSTOP(I2C1, ENABLE);


}


The page write of this EEPROM is written according to the page write timing of the EEPROM: 

Write the picture description here

In the I2C_EE_PageWrite() function, regardless of the loop detection of the while statement, you can clearly see that the entire code flow is the EEPROM page write timing flow

I2C_GenerateSTART(I2C1, ENABLE); 
Generates the I2C communication start signal S.

I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter); 
Send the variable EEPROM_ADDRESS address assigned in the previous conditional variation through the I2C1 interface, and the data transmission direction is ST32's I2C send data (I2C_Direction_Transmitter). 
(The EEPROM_ADDRESS address here is the addressing of the EEPROM as a device mounted on the I2C bus, not the address of the EEPROM memory storage matrix)

I2C_SendData(I2C1, WriteAddr); 
Here the data is transferred to the data register, and then sent out by the I2C module according to the I2C protocol. However, please note that the input parameter here is WriteAddr. According to the page write timing of EEPROM, the first data after sending the I2C address does not necessarily have to be written into the EEPROM. EEPROM interprets this data as the address to be written to the storage matrix. WriteAddr is input as a parameter in the I2C_EE_PageWrite() function, and is calculated by I2C_EE_BufferWrite() in this example.

I2C_SendData(I2C1, *pBuffer); 
Here is to send the data to be written to the EEPROM. According to the page write timing of the EEPROM, these data are written to the page address sent previously. If the continuous writing exceeds the maximum number of bytes of a page (here is 8), the extra data will be re-written from the starting address of the page, overwriting the previous data.

I2C_GenerateSTOP(I2C1, ENABLE); 
Generates the I2C transmission end signal and completes an I2C communication.

I2C event detection:

There are many event detections in I2C_EE_PageWrite, which are all necessary. According to the sequence diagram of the STM32 reference manual, a series of events will occur during the I2C communication process, and flags will be generated in the corresponding registers after the occurrence of the event. 
Write the picture description here

The meaning of this diagram is: 
1. After the start signal is sent, event 5 (EV5) will be generated, that is, the I2C of STM32 becomes the host mode; 
2. After the I2C device addressing is completed and the response is received, EV6 will be generated, that is, the I2C of STM32 becomes the data transmitter; 
3. After the data transmission is completed, EV8 will be generated; 
Therefore, when performing I2C communication operations, you can query the events by cyclically calling the library function I2C_CheckEvent() to ensure that the next operation is performed after the previous operation is completed.

For example: after determining that the SDA bus is idle, the STM32 as the master transmitter sends a start signal, and EV5 will be generated after success. Therefore, the statement: 
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT)); 
is used to detect this event to ensure that the next operation is executed after detection. I2C_EVENT_MASTER_MODE_SELECT is the type of event. All related events can be found in the Keil environment.

EEPROM读取函数 I2C_EE_BufferRead(); 
void I2C_EE_BufferRead(u8* pBuffer, u8 ReadAddr, u16 NumByteToRead) 

while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));

I2C_GenerateSTART(I2C1, ENABLE); //Send the start signal for the first time

while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));


I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Transmitter);

while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));


I2C_Cmd(I2C1, ENABLE);


I2C_SendData(I2C1, ReadAddr);

while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));


I2C_GenerateSTART(I2C1, ENABLE); //This is the second time to send the start signal

while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));


I2C_Send7bitAddress(I2C1, EEPROM_ADDRESS, I2C_Direction_Receiver);

while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));


while(NumByteToRead)

{

    if(NumByteToRead == 1)

    {

    /* Disable Acknowledgement */

    I2C_AcknowledgeConfig(I2C1, DISABLE);

    /* Send STOP Condition */

    I2C_GenerateSTOP(I2C1, ENABLE);

    }

/* Test on EV7 and clear it */

    if(I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED))

    {

    /* Read a byte from the EEPROM */

    *pBuffer = I2C_ReceiveData(I2C1);

    /* Point to the next location where the byte read will be

    pBuffer++;

    /* Decrement the read bytes counter */

    NumByteToRead--;

    }

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

Here, I2C_CheckEvent() is also used to ensure that the communication is normal. It should be noted that according to the I2C standard protocol, the main transmitter STM32 needs to send two start signals I2C signals to establish communication.


PS: 

Summarize the I2C reading and writing process: 

Configure the I/O port, determine and configure the I2C mode, enable GPIO and I2C clock. (Must do this first) 

Write: 

1. Check whether SDA is idle; 

2. Send a start signal according to the I2C protocol; 

3. Issue 7-bit period address and write mode; 

4. The first address of the storage area to be written; 

5. Write data using page write mode or byte write mode; 

6. Send I2C communication end signal; 

(After each operation, check whether the event is successful, and after writing, check whether the EEPROM has entered the Standby state)


read: 

1. Check whether SDA is idle; 

2. Send a start signal according to the I2C protocol; 

3. Issue 7-bit period address and write mode (pseudo write); 

4. Send the first storage address to be read; 

5. Resend the start signal (remember); 

6, issue 7 as the device address and read mode; 

7, receive data; 

(After each operation, an event must be detected to determine whether it is successful)


Keywords:STM32 Reference address:STM32 I2C_EEPROM read and write

Previous article:STM32 simulates I2C timing to read and write EEPROM Lite
Next article:ARM Interrupt --IRQ and FIQ Configuration --External Configuration

Recommended ReadingLatest update time:2024-11-15 17:41

STM32 encoder interface mode
What is an encoder? It is a fun thing and an indispensable gadget for measuring the speed of a car. Below, I will start from the principle of the encoder and talk about how to use the encoder interface mode of stm32 to measure the motor speed and direction. 1. Encoder Figure 1 Encoder schematic diagram       Figure
[Microcontroller]
STM32 encoder interface mode
GPIO used by STM32
//****************************************************************************** //******************************************************************* /*********************************************************************** main file, GPIO operation, complete the simplest IO operation experiment, which is to control t
[Microcontroller]
Using STM32 to complete the design of intelligent motor protector
0 Preface Motors are the main driving source in the field of industrial production. How to effectively monitor the operating status of motors, protect motor circuits, increase motor operating time, and reduce motor failures is critical to the operation of the factory's overall power grid. There are many kinds of mot
[Microcontroller]
Using STM32 to complete the design of intelligent motor protector
STM32 UID global unique identification code summary
UID: unique id is different from the Device ID of the microcontroller (distinguishing whether it is a stm32f103 or stm32f030 microcontroller) The stm32f103 series microcontrollers all have UID, 96 bits, which are placed in three 32-bit registers. The base address is 0x1ffff7e8, and the offset addresses are 0, 4, and 8
[Microcontroller]
STM32 EXTI external interrupt
External interrupt pin configuration initialization: Take PA0 as an example 1. Peripheral port clock is turned on  RCC->APB2ENR|=1 2. Port is set as input  GPIOA->CRL&=0XFFFFFFF0; //PA0 is set as input     GPIOA->CRL|=0X00000008;  3. Port selects pull-up/pull-down mode  GPIOA->ODR&=0xFFFFFFFE; //A0 defaults to p
[Microcontroller]
STM32 Nor Flash DFU
This time I will talk about how to implement Nor Flash upgrade. Nor Flash's DFU project is modified based on the previous flash DFU project. The project directory is as follows:   The Nor Flash chip I use is M29W128F, which has a total of 128Mb of space and is mounted on BANK0 through FSMC. There are also examples o
[Microcontroller]
STM32 Nor Flash DFU
STM32 HAL library study notes ------- (system clock configuration)
Using the CubeMX tool, developers don’t need to worry about the underlying implementation, making the entire configuration simpler 1. Prepare the tool STM32_CubeMX ST official website can be downloaded http://www.st.com/content/st_com/en/search.html#q=cubemx-t=tools-page=1 2. Open STM32_CubeMX and start configuration.
[Microcontroller]
Interface design of bank queuing system based on I2C bus
This paper takes the existing queueing system of the bank as an example and proposes the interface design of the single-chip microcomputer queueing system based on the IIC bus. Through the simulation test of the system, it not only simplifies the design circuit, reduces the circuit board area, saves components in the
[Microcontroller]
Interface design of bank queuing system based on I2C bus
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号