EEPROM and STM32
Well you all know what a EEPROM is and that’s why you are here. So let’s get straight to the point
In this tutorial we will interface an I2C based EEPROM with our beloved STM32. To be particular, I am using AT24C256, which is a 256Kb Serial EEPROM utilizing an I2C (2-wire) serial interface. Since we are using I2C, so the code remains same across all the STM32 Devices that supports I2C.
Also I will try to write a more generalized code, so that you can also use it for other EEPROMs that works on I2C.
The code can now write the float values and the integer values to the EEPROM Flash memory.
There is noting special here. Just make sure you enable the I2C
As you can see above, I have selected the fast mode for the I2C. The reason is that this EEPROM can support 400 KHz I2C clock speed and this is mentioned in the datasheet of the device.
This is it for the setup, Now let’s move to the code
I have written a library for the EEPROM. You need to include the EEPROM.c and EEPROM.h files in the src and inc folders respectively. I will explain the functions as we progress in the tutorial
Everything important is in the EEPROM.c obviously, so we will take a look at this file
- As you can see above, first of all we need to define the I2C that we are using for the EEPROM (hi2c1 and &hi2c1)
- Next define thee address for the EEPROM. Make sure you use the 8 bit address (unlike Arduino, which uses 7 bits). These 8 bits include the R/W bit also
The address for the I2C device can be found in it’s datasheet
In the picture above, the address for AT24C256 is 0XA0. The A2, A1 and A0 pins can be modified physically to change the address of the device. This is useful in case if you have more than 1 EEPROM connected to the same I2C. The R/W bit can be kept 0 for write operation, and during Read, HAL functions makes it 1 on their own
- Now we need to define the PAGE size and the number of pages.
The memories are generally divided into pages. You need to fid the division for your memory type in it’s datasheet
In case of AT24C256, the memory is divided into 512 pages, and each page is 64 bytes, making it in total of 256 Kbit in size
Let’s write a function which can write the required data to the EEPROM.
This functions takes the following arguments
- @page is the number of the start page. Range from 0 to PAGE_NUM-1
- @offset is the start byte offset in the page. Range from 0 to PAGE_SIZE-1
- @data is the pointer to the data to write in bytes
- @size is the size of the data
Before we dig deep into the problems that we are going to face in this part and their solutions, let’s take a look at the address distribution for the memory
The problem that we face here is the way in which the data is written to the device. When we write the data in bulk, the Byte Address gets incremented by it’s own, but not the page address.
So we have to manually increment the page address. Let’s see the function now
- Here we first find out the number of the bit, where the page address starts using log(PAGE_SIZE)/log(2). This bit will depend on your Page Size
- then we set the start page and the end page, and calculate the number of pages to be written
- Now inside the for loop, we will calculate the memory location
To do this we will shift the startpage by the page bit position ( 6, if the page size is 64 bytes)
For example, if the start page is 5, it will be shifted by 6 i.e 5<<6
we will add the offset here to set the final memory location
- next calculate the remaining bytes
- now we will write the data to the EEPROM using HAL I2C MEM WRITE function
- we will update the parameters now
- and finally a 5 ms delay for the write cycle
This 5 ms is the time required for the EEPROM to write the data into the non volatile memory
This time is defined in the datasheet
EEPROM_READ is similar to write function. Every step is same here too.
As you can see above the entire function is same with very few changes
- Of course we will be reading data, so HAL I2C MEM READ function is used instead of write function
- And since no write cycle is used here, we don’t need to give the 5 ms delay
EEPROM PAGE ERASE
EEPROM_PageErase can be used to erase a single page in the memory
- Here we will also first calculate the memory location using the page
- then we create a buffer, where we store the data
- and write the data to the memory location
this write operation is limited to a single page, and that’s why the size will be the page size
- since it’s a write cycle, we need to give a 5 ms seconds
- In case you want to erase the entire ROM, call this function in a for loop
Let’s write the main function now
- Here I am first erasing the entire EEPROM
- Then load the data into the write buffer. This data is just the ascii characters
- Now write the data to the EEPROM at the 3rd page with an offset of 10 bytes.
- And finally start reading from the beginning of the first page to see if the offset was set or not
you can see the result for this program below
- You can see in the picture above that the first 10 bytes (0 to 9) are empty. This is because of the offset we set during the write process
- Then we have 100 bytes of data from the 10th Byte to 109th Byte
- After this, the ROM is again empty as there is no data written after 109th Byte
For more details and experiments, check the video