It is very simple to read EEPROM. EEPROM directly sends out data according to the timing we send, but writing EEPROM is not so simple. After sending data to EEPROM, it is first saved in the EEPROM cache. EEPROM must move the data in the cache to the "non-volatile" area to achieve the effect of not losing data when power is off. Writing to the non-volatile area requires a certain amount of time, and each device is not exactly the same. The writing time of ATMEL's 24C02 does not exceed 5ms at most. In the process of writing to the non-volatile area, EEPROM will no longer respond to our access. Not only will it not receive our data, but even if we use the I2C standard addressing mode to address it, EEPROM will not respond, as if there is no such device on this bus. After the data is written to the non-volatile area, EEPROM returns to normal again and can be read and written normally.
Careful students will find that in the code for writing data, we actually read the ACK bit, but we did not do anything after reading the ACK bit. This is because we only write one byte of data at a time. When we power on again next time, the time will definitely exceed 5ms. However, if we write several bytes continuously, we must consider the ACK bit. After writing one byte, before writing the next byte, we must wait for the EEPROM to respond again. Please pay attention to the way we write the program and learn it.
We have already known the convenience of writing multiple .c files for porting. The program in this section is exactly the same as the Lcd1602.c file and I2C.c file in the previous section. Therefore, this time we will only send you the main.c file to help you analyze it clearly.
But you can't do this. You are just beginners and need to practice more to consolidate a lot of knowledge and skills. Therefore, it is recommended that you type out each program one code at a time on your Keil software.
/********************************I2C.c file program source code*******************************/
(Omitted here, please refer to the code in the previous section)
/***************************Lcd1602.c file program source code********************************/
(Omitted here, please refer to the code in the previous section)
/********************************main.c file program source code******************************/
#include
extern void InitLcd1602();
extern void LcdShowStr(unsigned char x, unsigned char y, unsigned char *str);
extern void I2CStart();
extern void I2CStop();
extern unsigned char I2CReadACK();
extern unsigned char I2CReadNAK();
extern bit I2CWrite(unsigned char dat);
void E2Read(unsigned char *buf, unsigned char addr, unsigned char len);
void E2Write(unsigned char *buf, unsigned char addr, unsigned char len);
void MemToStr(unsigned char *str, unsigned char *src, unsigned char len);
void main(){
unsigned char i;
unsigned char buf[5];
unsigned char str[20];
InitLcd1602(); //Initialize LCD
E2Read(buf, 0x90, sizeof(buf)); //Read a piece of data from E2
MemToStr(str, buf, sizeof(buf)); //Convert to hexadecimal string
LcdShowStr(0, 0, str); //Display on LCD
for (i=0; i buf[i] = buf[i] + 1 + i; } E2Write(buf, 0x90, sizeof(buf)); //Write back to E2 while(1); } /* Convert a piece of memory data into a hexadecimal string. str- string pointer, src- source data address, len- data length*/ void MemToStr(unsigned char *str, unsigned char *src, unsigned char len){ unsigned char tmp; while (len--){ tmp = *src >> 4; // first take the high 4 bits if (tmp <= 9){ //Convert to 0-9 or AF *str++ = tmp + '0'; }else{ *str++ = tmp - 10 + 'A'; } tmp = *src & 0x0F; //Get the lower 4 bits if (tmp <= 9){ //Convert to 0-9 or AF *str++ = tmp + '0'; }else{ *str++ = tmp - 10 + 'A'; } *str++ = ' '; //Add a space after converting a byte src++; } } /* E2 read function, buf-data receiving pointer, addr-starting address in E2, len-read length*/ void E2Read(unsigned char *buf, unsigned char addr, unsigned char len){ do { // Use addressing operations to query whether read and write operations are currently available I2CStart(); if (I2CWrite(0x50<<1)){ //If there is a response, jump out of the loop, otherwise proceed to the next query break; } I2CStop(); } while(1); I2CWrite(addr); //Write the starting address I2CStart(); //Send a repeated start signal I2CWrite((0x50<<1)|0x01); //Address the device, then read the operation while (len > 1){ //Continuously read len-1 bytes *buf++ = I2CReadACK(); //Before the last byte is the read operation + response only--; } *buf = I2CReadNAK(); //The last byte is read operation + non-response I2CStop(); } /* E2 write function, buf-source data pointer, addr-starting address in E2, len-write length*/ void E2Write(unsigned char *buf, unsigned char addr, unsigned char len){ while (len--){ do { // Use addressing operations to query whether read and write operations are currently available I2CStart(); if (I2CWrite(0x50<<1)){ //If there is a response, jump out of the loop, otherwise proceed to the next query break; } I2CStop(); } while(1); I2CWrite(addr++); //Write the starting address I2CWrite(*buf++); //Write a byte of data I2CStop(); //End the write operation to wait for the write to complete } } Function MemToStr: can convert a section of memory data into a hexadecimal string. Since what we read from the EEPROM is normal data, and the 1602 LCD receives ASCII code characters, we must first convert the data to display it through the LCD. The algorithm is very simple, which is to separate the high 4 bits and low 4 bits of each byte of data and compare them with 9. If it is less than or equal to 9, directly add "0" to convert it to ASCII code 0 to 9; if it is greater than 9, first subtract 10 and then add "A" to convert it to ASCII code A to F. Function E2Read: Before reading, we need to check whether the read and write operations can be performed. The EEPROM can only respond normally. After reading, all the bytes before the last byte will be given ACK, and after reading the last byte, we need to give a NAK. Function E2Write: Before each write operation, we need to query to determine whether the current EEPROM responds. Data can only be written after a normal response.
Previous article:Single-byte read and write operation timing of single-chip EEPROM
Next article:Integrated programming of MCU I2C and EEPROM
- Popular Resources
- Popular amplifiers
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
- Industry first! Xiaopeng announces P7 car chip crowdfunding is completed: upgraded to Snapdragon 8295, fluency doubled
- P22-009_Butterfly E3106 Cord Board Solution
- 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)
- [Qinheng RISC-V core CH582] Constant temperature control heater
- The brushless drive solution for the 17th Smart Car Competition sponsored by Lingdong is now open source
- Texas Instruments CC1310 Synchronous Transmit and Receive
- [National Technology N32G457 Review] RT_Thread Studio drives CAN and STM32F103VE communication
- 16 Years of Taiwanese New Year
- 【Project Source Code】Digital Signal Processing Learning——Mixer
- Chapter 4: Use of Timers and PWM
- Ask an outrageous question, why do we need to use a resistor to form a discharge path for the capacitor to discharge?
- An annular solar eclipse is coming. Have those in the annular eclipse zone seen it?
- How to set differential traces for high-speed USB positive and negative in AD16 PCB