EEPROM data organization:
EEPROM devices divide their storage matrix into pages:
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:
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.
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)
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
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Keysight Technologies Helps Samsung Electronics Successfully Validate FiRa® 2.0 Safe Distance Measurement Test Case
- Innovation is not limited to Meizhi, Welling will appear at the 2024 China Home Appliance Technology Conference
- Innovation is not limited to Meizhi, Welling will appear at the 2024 China Home Appliance Technology Conference
- Huawei's Strategic Department Director Gai Gang: The cumulative installed base of open source Euler operating system exceeds 10 million sets
- Download from the Internet--ARM Getting Started Notes
- Learn ARM development(22)
- Learn ARM development(21)
- Learn ARM development(20)
- Learn ARM development(19)
- Learn ARM development(14)
- When the STM32F407 PWM is outputting, one interrupt is not completed and the next interrupt is entered, resulting in a disordered output waveform
- 【Example】Wireless serial port module star network networking case
- 【GD32F310G-START Review】Review 2: GD32F301 driving Nokia 5110LCD
- Studying Things to Gain Knowledge 03: In DC circuits, energy is not transmitted by wires either
- [TI recommended course] #TI's new generation C2000? microcontroller: full support for servo and motor drive applications#
- Does anyone have a PDF of Analog Filter and Circuit Design Handbook (US)?
- [Xianji HPM6750 Review IX] Detailed Optimization Methods for Performance Improvement
- Undergraduate students from the University of Science and Technology of China designed a processor chip in 9 months! Decoding the story behind it
- The Raspberry Pi discount quota is full. Check out other e-selected products to participate in the event
- Go your own way and let the SI engineer decide