The simulation circuit is as follows:
code show as below:
i2c.h
#ifndef _I2C_H //Fixed format for writing header files
#define _I2C_H //Fixed format for writing header files
#include sbit SCL=P1^2; //Pin definition of E2PROM24C02 sbit SDA=P1^3; //Pin definition of E2PROM24C02 sbit WP=P1^4; //Read and write protection unsigned char I2CSendByte(unsigned char dat); unsigned char I2CReadByte(); void I2CStop(); void I2CStart(); void At24c02Write(unsigned char addr,unsigned char dat); //Declare in the header file and call it in the main function unsigned char At24c02Read(unsigned char addr); #endif //Fixed format for writing header files i2c.c #include "i2c.h" void delay5us(void) //error 0us { unsigned char a; for(a=1;a>0;a--); } void I2CStart(){ //I2C start signal, strictly follow the timing diagram SDA=1; SCL=1; delay5us(); SDA=0; delay5us(); SCL=0; delay5us(); } void I2CStop(){ //Stop signal SDA=0; SCL=1; delay5us(); SDA=1; delay5us(); //The rest can be ignored, because it has already played the role of stop } unsigned char I2CSendByte(unsigned char dat){ //Write a byte function unsigned char a=8,b; for(a=8;a>0;a--){ SDA=dat>>7; dat=dat<<1; delay5us(); SCL=1; //Data can only be transmitted when the clock line is low, and the data is required to remain unchanged when the clock line is high delay5us(); //Check if SDA is 0 and whether it responds SCL=0; delay5us(); } SDA=1; //Release the clock line and data line, wait for response delay5us(); SCL=1; while(SDA){ //Check whether it responds, if SDA=0, it will exit the loop, if SDA=1, it will not respond b++; //SDA=1, set a time to jump out of the loop and return 0 if(b>20){ SCL=0; delay5us(); return 0; } } SCL=0; delay5us(); return 1; //Send successfully returns 1 } unsigned char I2CReadByte(){ //Read one byte of data unsigned char a=8,dat=0; SDA=1; //Pull high to prepare for reading delay5us(); for(a=8;a>0;a--){ SCL=1; //Data is stable during SCL, data must be stable during reading delay5us(); dat<<=1; //The order of reading and writing is different here, read: shift ---> read number; write: write number --> shift dat|=SDA; //Why can we directly shift and AND the data here? The shift clock line and data line are not the same line delay5us(); SCL=0; //When SCL is zero, the data on SDA can be changed delay5us(); } return dat; } /* I2CSendByte and I2CReadByte are two functions used to determine under what conditions 8-bit byte data can be read and written*/ /*You can think of the two functions I2CSendByte and I2CReadByte as a small environment*/ /*After satisfying the reading and writing of the small environment (continuous transmission of 8 bits of a byte), it is necessary to create the large environment (that is, how this overall device transmits data under what conditions*/ /*Or it can be understood as first writing the data read and write method that satisfies I2C according to the timing diagram, and then writing the data method that satisfies the device read and write*/ void At24c02Write(unsigned char addr,unsigned char dat){ //Write the address first to determine the location where the data is stored; then write the data (write this function according to the device's data writing process) I2CStart(); I2CSendByte(0xa0); //Determine the device address and which device I2CSendByte(addr); //Write the first address in the device to determine the first address location for storing data I2CSendByte(dat); //After confirming the address, send the data //The response part has been written in the sending function, which is equivalent to a whole I2CStop(); //Send a stop signal } unsigned char At24c02Read(unsigned char addr){ //Reading data requires a return value, which makes it easier to write data unsigned char num; I2CStart(); I2CSendByte(0xa0); //Pseudo write when reading I2CSendByte(addr); //Pseudo write includes two parts: determining the device address and determining the first address in the device I2CStart(); //During the transmission process, when the direction of data transmission needs to be changed, the start signal and slave address will be generated repeatedly, but the reading and writing directions are exactly opposite. I2CSendByte(0xa1); //These two parts are very important num=I2CReadByte(); //Get the read data I2CStop(); return num; } main.c #include #include "i2c.h" typedef unsigned int u16; typedef unsigned char u8; /*Control the reading and writing process*/ sbit K1=P3^1; //Save display data, that is, write data to E2Prom for storage sbit K2=P3^0; //Read the saved data sbit K3=P3^2; //Accumulate sbit K4=P3^3; //clear sbit LSA=P2^2; //38 decoder pin settings sbit LSB=P2^3; sbit LSC=P2^4; u8 code segment[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; u8 num=0,disp[4]; //disp can also be written as a buffer pool: disp[4]={1,1,2,3}; void delay(u16 i){ while(i--); } void Keypros(){ //Key processing function if(K1==0){ delay(100); //debounce if(K1==0){ WP=0; /*turn off protection*/ At24c02Write(2,num); //Write the first address and data to be stored (AT24C02 has 256 addresses, 2 is one of them, num can be a value you set) delay(100);/*Wait for read to complete*/ WP=1; /*Open protection*/ } while(!K1); //This is very important, to determine whether the switch is disconnected } if(K2==0){ delay(100); //debounce if(K2==0){ num=At24c02Read(2); //The address written before is 2, so read 2, num finally equals the return value of the read } while(!K2); } if(K3==0){ delay(100); //debounce if(K3==0){ num++; // num accumulated if(num>255){ num=0; } } while(!K3); } if(K4==0){ delay(100); //debounce if(K4==0){ num=0; } while(!K4); } } void datapros(){ //Data processing function, converts the number in the memory into a digital management number disp[0]=segment[num/1000]; //highest bit disp[1]=segment[num%1000/100]; disp[2]=segment[num%1000%100/10]; disp[3]=segment[num%1000%100%10]; } void Dispiay(){ //Display function u8 i; for(i=0;i<4;i++){ switch(i){ case 0:LSA=0;LSB=0;LSC=0;break; //Display bit 0 case 1:LSA=1;LSB=0;LSC=0;break; //Display the first bit case 2:LSA=0;LSB=1;LSC=0;break; //Display the second digit case 3:LSA=1;LSB=1;LSC=0;break; //Display the third bit } //Which bit is selected above, the following will pass the disconnection data P0=disp[3-i]; //According to the data processing function, the number to be displayed is obtained. Under the condition of the loop, a number is displayed using 4 digital tubes. delay(100); P0=0x00; //Blanking } } void main(){ // Enter the main function call while(1){ Keypros(); //First determine whether the key is operated datapros(); //Determine whether the acquired data needs to be processed after playing Dispiay(); //The data can be displayed after processing } } Simulation result diagram: 2. Press K1, the number displayed on the digital tube is automatically saved to 24C02 (the address in this program is 2), then press K3 several times to change the displayed value of the digital tube, and then press K1, the digital tube displays the saved number "3". Press K4 to clear the digital tube. **Note:** In this project, the master-slave response part of I2C is directly programmed in the unsigned char I2CSendByte(unsigned char dat) function, and there is no separate sub-function to verify the master-slave response.
1. Press K3, the digital tube display number will automatically increase by 1, press 3 times to display:
Previous article:51 MCU Experiment 2——I2C Communication——24C01 Extension Experiment
Next article:51 single chip microcomputer series - single bus communication method - DS18B20 temperature detection design
Recommended ReadingLatest update time:2024-11-16 12:01
- Popular Resources
- Popular amplifiers
- 西门子S7-12001500 PLC SCL语言编程从入门到精通 (北岛李工)
- Plant growth monitoring system source code based on Raspberry Pi 5
- 100 Examples of Microcontroller C Language Applications (with CD-ROM, 3rd Edition) (Wang Huiliang, Wang Dongfeng, Dong Guanqiang)
- Principles and Applications of Single Chip Microcomputers and C51 Programming (3rd Edition) (Xie Weicheng, Yang Jiaguo)
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- Innolux's intelligent steer-by-wire solution makes cars smarter and safer
- 8051 MCU - Parity Check
- How to efficiently balance the sensitivity of tactile sensing interfaces
- What should I do if the servo motor shakes? What causes the servo motor to shake quickly?
- 【Brushless Motor】Analysis of three-phase BLDC motor and sharing of two popular development boards
- Midea Industrial Technology's subsidiaries Clou Electronics and Hekang New Energy jointly appeared at the Munich Battery Energy Storage Exhibition and Solar Energy Exhibition
- Guoxin Sichen | Application of ferroelectric memory PB85RS2MC in power battery management, with a capacity of 2M
- Analysis of common faults of frequency converter
- In a head-on competition with Qualcomm, what kind of cockpit products has Intel come up with?
- Dalian Rongke's all-vanadium liquid flow battery energy storage equipment industrialization project has entered the sprint stage before production
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- Has your iPhone 13 arrived? Here comes the real iPhone 13 series disassembly
- EEWORLD University Hall ---- Industrial innovation applications based on DLP
- About the test of Gaoyun Yunyuan software ERROR (PA2050): Module 'xx' is instantiated but n...
- About the power consumption optimization design in embedded DSP design
- About the peripheral circuit of single chip microcomputer to measure the frequency of alternating current
- Why does TPS92691 recommend adding resistors and capacitors to the Vin design?
- Static Timing Analysis Basics and Applications
- How much do you know about the performance improvement of Wi-Fi 6 routers?
- What is the problem with amplifier instability?
- 【RPi PICO】Breathing light