1. Brief explanation of E2Write function
The contents of "E2Write(unsigned char *buf, unsigned char addr, unsigned char len)" in Mr. Song's routines lesson14_3 and lesson14_4 are different. The E2Write function in lesson14_4 is more efficient than the E2Write function in lesson14_3. The E2Write function in lesson14_3 needs to go through the start signal and stop signal for each byte written, and these steps need to be repeated for the next byte written. The E2Write function in lesson14_4 supports EEPROM page writing (refer to Section 14.3.3 of the document "Teaching You to Learn 51 Single-Chip Microcomputers Step by Step"), so we choose the E2Write function in lesson14_4 when creating the file.
We create two new files "iic.c" and "iic.h". We combine the related functions of IIC and EEPROM into the single file "iic.c".
2. Code of iic.c
#include #include #include #define I2CDelay() {_nop_();_nop_();_nop_();_nop_();} /* Generate bus start signal */ void I2CStart() { I2C_SDA = 1; //First make sure SDA and SCL are both high I2C_SCL = 1; I2CDelay(); I2C_SDA = 0; // Pull SDA low first I2CDelay(); I2C_SCL = 0; //Pull SCL low again } /* Generate bus stop signal */ void I2CStop() { I2C_SCL = 0; //First make sure SDA and SCL are both low I2C_SDA = 0; I2CDelay(); I2C_SCL = 1; //Pull SCL high first I2CDelay(); I2C_SDA = 1; //Pull SDA high again I2CDelay(); } /* I2C bus write operation, dat-byte to be written, return value-slave response bit value*/ unsigned char I2CWrite(unsigned char dat) { unsigned char ack; //Used to temporarily store the value of the response bit unsigned char mask; //Mask variable used to detect a certain bit value in a byte for (mask=0x80; mask!=0; mask>>=1) //From high to low { if ((mask&dat) == 0) //The value of this bit is output to SDA I2C_SDA = 0; else I2C_SDA = 1; I2CDelay(); I2C_SCL = 1; //Pull SCL high I2CDelay(); I2C_SCL = 0; //Pull SCL low again to complete a bit cycle } I2C_SDA = 1; //After sending 8 bits of data, the host releases SDA to detect the slave's response I2CDelay(); I2C_SCL = 1; //Pull SCL high ack = I2C_SDA; //Read the SDA value at this time, which is the response value of the slave I2CDelay(); I2C_SCL = 0; //Pull SCL low again to complete the response bit and hold the bus return (!ack); //The response value is inverted to conform to the usual logic: //0 = does not exist or is busy or write failed, 1 = exists and is idle or write succeeded } /* I2C bus read operation, and send a response or non-response signal, return value - the read byte*/ unsigned char I2CReadNAK_OR_ACK(unsigned char nak_or_ack) { unsigned char mask; unsigned char dat; I2C_SDA = 1; //First make sure the host releases SDA for (mask=0x80; mask!=0; mask>>=1) //From high to low { I2CDelay(); I2C_SCL = 1; //Pull SCL high if(I2C_SDA == 0) //Read the value of SDA dat &= ~mask; //When it is 0, the corresponding bit in dat is cleared else dat |= mask; //When it is 1, the corresponding position in dat is 1 I2CDelay(); I2C_SCL = 0; //Pull SCL low again to allow the slave to send out the next bit } I2C_SDA = nak_or_ack; //After the 8-bit data is sent, the parameter NAK_OR_ACK passed in determines whether to respond. If it is 1, it means no response, and if it is 0, it means response. I2CDelay(); I2C_SCL = 1; //Pull SCL high I2CDelay(); I2C_SCL = 0; //Pull SCL low again to complete the non-acknowledge bit and hold the bus return dat; } /* 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, the loop will be exited. If there is no response, the next query will be performed { break; } I2CStop(); } while(1); I2CWrite(addr); //Write the starting address I2CStart(); //Send a repeated start signal I2CWrite((0x50<<1)|0x01); //Address the device, the following is a read operation while (len > 1) //Continuously read len-1 bytes { *buf++ = I2CReadNAK_OR_ACK(0); //Before the last byte is the read operation + response len--; } *buf = I2CReadNAK_OR_ACK(1); //The last byte is read operation + non-acknowledgement 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 > 0) { //Wait for the last write operation to complete do { // Use addressing operations to query whether read and write operations are currently available I2CStart(); if (I2CWrite(0x50<<1)) //If there is a response, the loop will be exited. If there is no response, the next query will be performed { break; } I2CStop(); } while(1); //Continuously write bytes in page write mode I2CWrite(addr); //Write the starting address while (len > 0) { I2CWrite(*buf++); //Write a byte of data len--; //The length to be written counts down addr++; //E2 address increment if ((addr&0x07) == 0) // Check if the address reaches the page boundary. 24C02 has 8 bytes per page. { // So just check if the lower 3 bits are zero break; //When reaching the page boundary, jump out of the loop and end the write operation } } I2CStop(); } } 3. Code of iic.h #ifndef __IIC_H__ #define __IIC_H__ sbit I2C_SCL = P3^7; sbit I2C_SDA = P3^6; void I2CStart(); //Generate bus start signal void I2CStop(); //Generate bus stop signal unsigned char I2CWrite(unsigned char dat); //I2C bus write operation, dat-byte to be written, return value-slave response bit value unsigned char I2CReadNAK_OR_ACK(unsigned char nak_or_ack); //I2C bus read operation, and send a response or non-response signal, return value - the read byte void E2Read(unsigned char *buf, unsigned char addr, unsigned char len); //E2 read function, buf-data receiving pointer, addr-starting address in E2, len-read length void E2Write(unsigned char *buf, unsigned char addr, unsigned char len); //E2 write function, buf-source data pointer, addr-starting address in E2, len-write length #endif 4. Modification of some codes "unsigned char I2CReadACK()" and "unsigned char I2CReadNAK()" Here we synthesize a function as "unsigned char I2CReadNAK_OR_ACK(unsigned char nak_or_ack)" uses the parameter passing to determine whether to generate a response. Then in main.c, the only functions needed are the EEPROM write function "E2Write()" and the read function "E2Read()". Remember to add "iic" to the project file 5.main.c test code #include #include #include #include void main() { unsigned char buf[]={"We can learn SCM well!"}; //We can learn SCM well unsigned char str[sizeof(buf)]; //The array length is the same as buf InitLcd1602(); //Initialize LCD E2Write(buf,0x8E,sizeof(buf)); //Write the contents of the buf array in the EEPROM starting from address 0x8E until all the contents of the array are written in and saved in the EEPROM delay_ms(1000); //Read the contents after 1 second and display them on the LCD screen E2Read(str,0x8E,sizeof(buf)); //Use another array to access the contents read from EEPROM LcdShowStr_len(0, 0,str, 16); LcdShowStr(0, 1, str+16+1); while(1); }
Previous article:51 MCU-EEPROM Simple Use
Next article:51 single chip microcomputer-infrared remote control
- 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
- 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)
- Learn ARM development(15)
- Analysis of the application of several common contact parts in high-voltage connectors of new energy vehicles
- Wiring harness durability test and contact voltage drop test method
- Review summary: Infineon's revolutionary photoacoustic spectroscopy (PAS) CO2 sensor
- UART interface algorithm transplantation encryption chip debugging skills - algorithm debugging
- Get the first experience! Raspberry Pi's first MCU product - Raspberry Pi Pico free review is here~
- What requirements does an industrial-grade 4G router need to meet?
- Automotive Resistive Bridge Pressure Sensor Interface Reference Design
- 【Share】Complete circuit diagram of the safety barrier at the detection end
- EEWorld is hiring! Fuzhou (work from home)/Beijing (work in a busy business district)
- The models currently promoted by TI are:
- What address is the uboot of Ti am335x loaded into memory when running?
- One of the reasons why you cannot enter the main function