51 MCU Series - I2C Communication Method - Application of 24C02 (E2PROM)

Publisher:ikfnpoLatest update time:2021-12-24 Source: eefocus Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

The simulation circuit is as follows:
figure 1

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:
1. Press K3, the digital tube display number will automatically increase by 1, press 3 times to display:
figure 2

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.

Reference address:51 MCU Series - I2C Communication Method - Application of 24C02 (E2PROM)

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

pic16f877A software simulates I2C communication to read and write 24C02
;The test function is  to reset the microcontroller  once, automatically read data from 24C02 to the digital tube display, then add 1 to the value and write it into 24C02. Finally, the data in the digital tube is the number of times the machine is turned on, which has certain practical significance  ; The 24C02 used 
[Microcontroller]
ATmega16 uses TWI module to read and write 24C02 program
/****************************************************** ******* Project name: AT_Mega16_master Creation date: 2007.10.21 Programming: Zhu Haifeng Contact: 543376422 (QQ) 13405100406 (mobile phone) AT24C02 stores a byte and reads it back for verification. If it is correct, the buzzer will sound once, and if it is i
[Microcontroller]
IIC realizes reading and writing of EEPROM (24C02)
Overview: The EEPROM chip model is 24C02. The total capacity of the chip is 256 bytes. The chip is connected to the outside through the IIC bus. Experimental function: Use the KEY1 button to control the writing of 24C02, and use another button KEY0 to control the reading of 24C02. Hardware circuit: IIC configu
[Microcontroller]
IIC realizes reading and writing of EEPROM (24C02)
Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号