{"id":2041,"date":"2023-10-11T06:08:39","date_gmt":"2023-10-11T06:08:39","guid":{"rendered":"https:\/\/blog.embeddedexpert.io\/?p=2041"},"modified":"2023-10-11T06:08:42","modified_gmt":"2023-10-11T06:08:42","slug":"working-with-stm32-and-at24c32-eeprom-part1-read-write-byte","status":"publish","type":"post","link":"https:\/\/blog.embeddedexpert.io\/?p=2041","title":{"rendered":"Working with STM32 and AT24C32 EEPROM Part1: Read\/Write byte"},"content":{"rendered":"\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"768\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/AdobeStock_90169450-1024x768.jpeg\" alt=\"\" class=\"wp-image-2042\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/AdobeStock_90169450-1024x768.jpeg 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/AdobeStock_90169450-300x225.jpeg 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/AdobeStock_90169450-768x576.jpeg 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/AdobeStock_90169450-1536x1152.jpeg 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/AdobeStock_90169450-2048x1536.jpeg 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/AdobeStock_90169450-1150x863.jpeg 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/AdobeStock_90169450-750x563.jpeg 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/AdobeStock_90169450-400x300.jpeg 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/AdobeStock_90169450-250x188.jpeg 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>In this guide, we shall see what is EEPROM and how to interface AT24C32 EEPROM with STM32F4xx. In part1, we shall cover the single byte read write operation to the eeprom.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>In this guide, we shall cover the following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>What is EEPROM.<\/li><li>Features of AT24C32.<\/li><li>AT24C32 Connection with STM32F4xx.<\/li><li>Developing the Read function.<\/li><li>Developing the write function.<\/li><li>Main code.<\/li><li>Code.<\/li><li>Results.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">1. What is EEPROM:<\/h2>\n\n\n\n<p>EEPROM stands for Electrically Erasable Programmable Read-Only Memory. To gain a better understanding of what these chips do, and what sort of applications EEPROM products are used for, it helps to break down the meaning of each word in its full name:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Electrically Erasable<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\"><li>When connected to a power supply (PSU) via a motherboard or other suitable electronic circuit, the stored contents of EEPROM modules can be erased (deleted), either entirely or on an individual byte-per-section basis<\/li><\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Programmable<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\"><li>PROM, or programmable ROM, indicates a module whose contents are intended to be written to memory after the chip has been installed into a system<\/li><li>When attached to an appropriate circuit, for example as part of a desktop computer system, the application of electrical voltages to EEPROM chips allows users to modify or reprogramme the contents stored on the memory module<\/li><\/ul>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>Read-Only<\/strong><\/h3>\n\n\n\n<ul class=\"wp-block-list\"><li>Read-only memory (ROM and PROM) refers to modules designed for the long-term storage of information that does not change dynamically<\/li><li>Non-dynamic data includes most types of user files, firmware, and some programs or code &#8211; elements that are not intended to receive regular automatic updates<\/li><li>Like most ROM chips, EEPROM modules provide non-volatile functionality. This means any information stored on the chip can still be retrieved after a zero-power state, i.e. after the device or computer it is installed in has been turned off and back on again. This is not the case with RAM (Random Access Memory). RAM is designed for performing dynamic tasks rather than long-term information storage and is effectively wiped at the instant it reverts to a powered-off state<\/li><\/ul>\n\n\n\n<p>In simple terms, EEPROM is a type of memory module that can be used to hold, retrieve and delete information when installed in a computer or other electronic device. (<a rel=\"noreferrer noopener\" href=\"https:\/\/uk.rs-online.com\/web\/content\/discovery\/ideas-and-advice\/eeprom-guide\" data-type=\"URL\" data-id=\"https:\/\/uk.rs-online.com\/web\/content\/discovery\/ideas-and-advice\/eeprom-guide\" target=\"_blank\">source<\/a>).<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">2. Features of AT24C32:<\/h2>\n\n\n\n<p>The features of AT32C32 as following:<\/p>\n\n\n\n<p>\u2022 Low-Voltage and Standard-Voltage Operation<\/p>\n\n\n\n<p>\u2013 2.7 (V CC = 2.7V to 5.5V)<\/p>\n\n\n\n<p>\u2013 1.8 (V CC = 1.8V to 5.5V)<\/p>\n\n\n\n<p>\u2022 Low-Power Devices (I SB = 2 \u00b5A at 5.5V) Available<\/p>\n\n\n\n<p>\u2022 Internally Organized 4096 x 8, 8192 x 8<\/p>\n\n\n\n<p>\u2022 2-Wire Serial Interface<\/p>\n\n\n\n<p>\u2022 Schmitt Trigger, Filtered Inputs for Noise Suppression<\/p>\n\n\n\n<p>\u2022 Bidirectional Data Transfer Protocol<\/p>\n\n\n\n<p>\u2022 100 kHz (1.8V, 2.5V, 2.7V) and 400 kHz (5V) Clock Rate<\/p>\n\n\n\n<p>\u2022 Write Protect Pin for Hardware Data Protection<\/p>\n\n\n\n<p>\u2022 32-Byte Page Write Mode (Partial Page Writes Allowed)<\/p>\n\n\n\n<p>\u2022 Self-Timed Write Cycle (10 ms max)<\/p>\n\n\n\n<p>\u2022 High Reliability<\/p>\n\n\n\n<p>\u2013 Endurance: 1 Million Write Cycles<\/p>\n\n\n\n<p>\u2013 Data Retention: 100 Years<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>The AT24C32\/64 provides 32,768\/65,536 bits of serial electrically erasable and programmable read only memory (EEPROM) organized as 4096\/8192 words of 8 bits each. The device\u2019s cascadable feature allows up to 8 devices to share a common 2wire bus. The device is optimized for use in many industrial and commercial applications where low power and low voltage operation are essential.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Pin Configurations:<\/h4>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"661\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.36.21-AM-1024x661.png\" alt=\"\" class=\"wp-image-2043\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.36.21-AM-1024x661.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.36.21-AM-300x194.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.36.21-AM-768x496.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.36.21-AM-1150x742.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.36.21-AM-750x484.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.36.21-AM-400x258.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.36.21-AM-250x161.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.36.21-AM.png 1382w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h4 class=\"wp-block-heading\">Block Diagram:<\/h4>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"741\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.37.41-AM-1024x741.png\" alt=\"\" class=\"wp-image-2044\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.37.41-AM-1024x741.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.37.41-AM-300x217.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.37.41-AM-768x556.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.37.41-AM-1536x1112.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.37.41-AM-1150x832.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.37.41-AM-750x543.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.37.41-AM-400x289.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.37.41-AM-250x181.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.37.41-AM.png 1882w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">3. AT24C32 Connection with STM32F4xx:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>Since the EEPROM came with the RTC3231 module, you can share the same i2c bus with EEPROM and RTC.<\/p>\n\n\n\n<p>Hence, the connection as following:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"715\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screen-Shot-2021-10-19-at-8.03.15-AM-2048x1430-1-1024x715.png\" alt=\"\" class=\"wp-image-2045\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screen-Shot-2021-10-19-at-8.03.15-AM-2048x1430-1-1024x715.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screen-Shot-2021-10-19-at-8.03.15-AM-2048x1430-1-300x209.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screen-Shot-2021-10-19-at-8.03.15-AM-2048x1430-1-768x536.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screen-Shot-2021-10-19-at-8.03.15-AM-2048x1430-1-1536x1073.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screen-Shot-2021-10-19-at-8.03.15-AM-2048x1430-1-1150x803.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screen-Shot-2021-10-19-at-8.03.15-AM-2048x1430-1-750x524.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screen-Shot-2021-10-19-at-8.03.15-AM-2048x1430-1-400x279.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screen-Shot-2021-10-19-at-8.03.15-AM-2048x1430-1-250x175.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screen-Shot-2021-10-19-at-8.03.15-AM-2048x1430-1.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-table is-style-stripes\"><table><tbody><tr><td>STM32F411 Nucleo64<\/td><td>AT24C32<\/td><\/tr><tr><td>5V<\/td><td>Vcc<\/td><\/tr><tr><td>GND<\/td><td>GND<\/td><\/tr><tr><td>PB8<\/td><td>SCL (Pull to 5V with 4.7K)<\/td><\/tr><tr><td>PB9<\/td><td>SDA (Pull to 5V with 4.7K)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. Developing the Read Function:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>Before heading into developing the driver, take a look at this <a rel=\"noreferrer noopener\" href=\"https:\/\/blog.embeddedexpert.io\/?p=416\" data-type=\"URL\" data-id=\"https:\/\/blog.embeddedexpert.io\/?p=416\" target=\"_blank\">guide<\/a> what is I2C and how to configure it.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>To start off, create new header file with name of AT24C32.h <\/p>\n\n\n\n<p>Within the header file, include the header guard:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#ifndef AT24C32_H_\n#define AT24C32_H_\n\n\n\n\n\n#endif \/* AT24C32_H_ *\/<\/pre><\/div>\n\n\n\n<p>Include stdint library:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;stdint.h&quot;<\/pre><\/div>\n\n\n\n<p>Declare the read function as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void AT24C32_ReadByte(uint16_t address, uint8_t *data);<\/pre><\/div>\n\n\n\n<p>The function takes the following two arguments:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>uint16_t to indicate which address to be read.<\/li><li>Pointer to hold the data to be read.<\/li><\/ul>\n\n\n\n<p>For write function:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void AT24C32_WriteByte(uint16_t address, uint8_t data);<\/pre><\/div>\n\n\n\n<p>Takes similar parameters except that the data as value rather than pointer.<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>Now, create new source file with name of AT24C32.c<\/p>\n\n\n\n<p>With in the source file, include the following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;AT24C32.h&quot;\n\n#include &quot;stm32f4xx.h&quot;<\/pre><\/div>\n\n\n\n<p>Declare a macro that holds the address of the AT24C32, by default, it is 0x57.<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#define AT24C32Address 0x57<\/pre><\/div>\n\n\n\n<p>For the read function, the steps as following:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Check if the bus is busy and wait until it is free.<\/li><li>Send start condition and wait until the start flag is set.<\/li><li>Send the slave address with R\/W bit set to 0 for write operation.<\/li><li>Send the MSB of the address and wait until the TX buffer is empty.<\/li><li>Send the LSB of the address and wait until the TX buffer is empty.<\/li><li>Generate restart condition.<\/li><li>Wait until the start flag is set.<\/li><li>Send the slave address with R\/W set to 1 to indicate read operation.<\/li><li>Wait until the address flag is set.<\/li><li>Disable acknowledgment.<\/li><li>Generate stop condition and read back the DR register.<\/li><\/ul>\n\n\n\n<p><\/p>\n\n\n\n<p>Since the EEPROM has 4096 address, we need to split the address to two bytes by sending the MSB first (bit 8 to 12\/13) followed by the LSB (bit 0 to bit 7) as shown below:<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"281\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.58.56-AM-1024x281.png\" alt=\"\" class=\"wp-image-2046\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.58.56-AM-1024x281.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.58.56-AM-300x82.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.58.56-AM-768x211.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.58.56-AM-1536x422.png 1536w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.58.56-AM-2048x562.png 2048w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.58.56-AM-1150x316.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.58.56-AM-750x206.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.58.56-AM-400x110.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.58.56-AM-250x69.png 250w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><\/p>\n\n\n\n<p>Hence, the byte read code as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void AT24C32_ReadByte(uint16_t address, uint8_t *data)\n{\n\twhile (I2C1-&gt;SR2 &amp; I2C_SR2_BUSY);           \/\/wait until bus not busy\n\n\tI2C1-&gt;CR1 |= I2C_CR1_START;                 \/\/generate start\n\n\twhile (!(I2C1-&gt;SR1 &amp; I2C_SR1_SB)){;}\t    \/\/wait until start is generated\n\n\tI2C1-&gt;DR = AT24C32Address&lt;&lt; 1;              \/\/ Send slave address\n\n\twhile (!(I2C1-&gt;SR1 &amp; I2C_SR1_ADDR)){;}        \/\/wait until address flag is set\n\n\t(void) I2C1-&gt;SR2; \t\t\t\t\t\t      \/\/Clear SR2\n\n\twhile (!(I2C1-&gt;SR1 &amp; I2C_SR1_TXE));           \/\/Wait until Data register empty\n\n\tI2C1-&gt;DR=address&gt;&gt;8;\t\t\t\t\t\t\/\/Send MSB of the address\n\n\twhile(!(I2C1-&gt;SR1&amp;I2C_SR1_TXE)){;}\t\t\t\/\/Wait until Data register empty\n\n\tI2C1-&gt;DR=address&amp;0x0F;\t\t\t\t\t\t\/\/ send LSB of the address\n\n\twhile(!(I2C1-&gt;SR1&amp;I2C_SR1_TXE)){;}\t\t\t\/\/Wait until Data register empty\n\n\n\tI2C1-&gt;CR1 |= I2C_CR1_START;                 \/\/generate start\n\n\twhile (!(I2C1-&gt;SR1 &amp; I2C_SR1_SB)){;}\t    \/\/wait until start is generated\n\n\tI2C1-&gt;DR = (AT24C32Address&lt;&lt; 1)|1;          \/\/ Send slave address with read operation\n\n\twhile(!(I2C1-&gt;SR1&amp;I2C_SR1_ADDR)){;}\t\t\t\/\/Wait for address flag to set\n\n\tI2C1-&gt;CR1&amp;=~I2C_CR1_ACK;\t\t\t\t\t\/\/Disable acknowledgment\n\n\t(void)I2C1-&gt;SR2;\t\t\t\t\t\t\t\/\/ Clear SR2\n\n\tI2C1-&gt;CR1|=I2C_CR1_STOP;\t\t\t\t\t\/\/ Generate stop condition\n\n\twhile(!(I2C1-&gt;SR1&amp;I2C_SR1_RXNE)){;}\t\t\t\/\/Wait for receiver buffer to be filled\n\n\t*data=I2C1-&gt;DR;\t\t\t\t\t\t\t\t\/\/Store the I2C bus.\n\n}<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">5. Developing the Write Function:<\/h2>\n\n\n\n<p>It is similar to the read operation until the LSB address then:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Send the data.<\/li><li>Wait until the transfer has completed by checking BTF flag.<\/li><li>Generate stop condition.<\/li><\/ul>\n\n\n\n<p>Hence, the write function as following:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">void AT24C32_WriteByte(uint16_t address, uint8_t data)\n{\n\twhile (I2C1-&gt;SR2 &amp; I2C_SR2_BUSY);           \/\/wait until bus not busy\n\n\tI2C1-&gt;CR1 |= I2C_CR1_START;                 \/\/generate start\n\n\twhile (!(I2C1-&gt;SR1 &amp; I2C_SR1_SB)){;}\t    \/\/wait until start is generated\n\n\tI2C1-&gt;DR = AT24C32Address&lt;&lt; 1;              \/\/ Send slave address\n\n\twhile (!(I2C1-&gt;SR1 &amp; I2C_SR1_ADDR)){;}        \/\/wait until address flag is set\n\n\t(void) I2C1-&gt;SR2; \t\t\t\t\t\t      \/\/Clear SR2\n\n\twhile (!(I2C1-&gt;SR1 &amp; I2C_SR1_TXE));           \/\/Wait until Data register empty\n\n\tI2C1-&gt;DR=address&gt;&gt;8;\t\t\t\t\t\t\/\/Send MSB of the address\n\n\twhile(!(I2C1-&gt;SR1&amp;I2C_SR1_TXE)){;}\t\t\t\/\/Wait until Data register empty\n\n\tI2C1-&gt;DR=address&amp;0x0F;\t\t\t\t\t\t\/\/ send LSB of the address\n\n\twhile(!(I2C1-&gt;SR1&amp;I2C_SR1_TXE)){;}\t\t\t\/\/Wait until Data register empty\n\n\tI2C1-&gt;DR = data; \t\t\t\t\t\t\t\/\/Write the data to the EEPROM\n\n\twhile (!(I2C1-&gt;SR1 &amp; I2C_SR1_BTF));      \t\/\/wait until transfer finished\n\n\tI2C1-&gt;CR1 |=I2C_CR1_STOP;\t\t\t\t\t\/\/Generate Stop\n\n}\n<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">6. Main code.<\/h2>\n\n\n\n<p>In main.c:<\/p>\n\n\n\n<div class=\"wp-block-codemirror-blocks-code-block code-block\"><pre class=\"CodeMirror\" data-setting=\"{&quot;showPanel&quot;:true,&quot;languageLabel&quot;:&quot;language&quot;,&quot;fullScreenButton&quot;:true,&quot;copyButton&quot;:true,&quot;mode&quot;:&quot;clike&quot;,&quot;mime&quot;:&quot;text\/x-csrc&quot;,&quot;theme&quot;:&quot;dracula&quot;,&quot;lineNumbers&quot;:false,&quot;styleActiveLine&quot;:false,&quot;lineWrapping&quot;:false,&quot;readOnly&quot;:true,&quot;fileName&quot;:&quot;&quot;,&quot;language&quot;:&quot;C&quot;,&quot;maxHeight&quot;:&quot;400px&quot;,&quot;modeName&quot;:&quot;c&quot;}\">#include &quot;i2c.h&quot;\n#include &quot;time_base.h&quot;\n#include &quot;uart.h&quot;\n#include &quot;stdio.h&quot;\n#include &quot;AT24C32.h&quot;\n\nuint8_t data_read;\n\nuint8_t data_write=20;\n\nuint16_t address=100;\n\n\nint main(void)\n{\n\tTicks_Init(16000000);\n\n\tuart2_rxtx_init();\n\n\ti2c_init();\n\n\tAT24C32_WriteByte(address,data_write);\n\n\tprintf(&quot;Data written to address %d is %d \\r\\n&quot;,address,data_write);\n\n\tAT24C32_ReadByte(address,&amp;data_read);\n\n\tprintf(&quot;Data read from address %d is %d \\r\\n&quot;,address,data_read);\n\n\n\n\twhile(1)\n\t{\n\t}\n\n}\n<\/pre><\/div>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">7. Code:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>You may download the code from here:<\/p>\n\n\n\n<div class=\"wp-block-file\"><a href=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/AT24C32_EEPROM.zip\">AT24C32_EEPROM<\/a><a href=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/AT24C32_EEPROM.zip\" class=\"wp-block-file__button\" download>Download<\/a><\/div>\n\n\n\n<p><\/p>\n\n\n\n<p><\/p>\n\n\n\n<h2 class=\"wp-block-heading\">8. Results:<\/h2>\n\n\n\n<p><\/p>\n\n\n\n<p>Open serial terminal and set the buadrate to be 115200 and you should get the following results:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"876\" src=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.14.42-AM-1024x876.png\" alt=\"\" class=\"wp-image-2047\" srcset=\"https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.14.42-AM-1024x876.png 1024w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.14.42-AM-300x257.png 300w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.14.42-AM-768x657.png 768w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.14.42-AM-1150x983.png 1150w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.14.42-AM-750x641.png 750w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.14.42-AM-400x342.png 400w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.14.42-AM-250x214.png 250w, https:\/\/blog.embeddedexpert.io\/wp-content\/uploads\/2023\/10\/Screenshot-2023-10-11-at-8.14.42-AM.png 1284w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p>Happy coding \ud83d\ude42<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this guide, we shall see what is EEPROM and how to interface AT24C32 EEPROM with STM32F4xx. In part1, we shall cover the single byte read write operation to the eeprom. In this guide, we shall cover the following: What is EEPROM. Features of AT24C32. AT24C32 Connection with STM32F4xx. Developing the Read function. Developing the [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2,11,12],"tags":[],"class_list":["post-2041","post","type-post","status-publish","format-standard","hentry","category-embedded-systems","category-peripheral-drivers","category-stm32"],"_links":{"self":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2041"}],"collection":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2041"}],"version-history":[{"count":1,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2041\/revisions"}],"predecessor-version":[{"id":2049,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=\/wp\/v2\/posts\/2041\/revisions\/2049"}],"wp:attachment":[{"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2041"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2041"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.embeddedexpert.io\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2041"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}