51 MCU-IIC&EEPROM synthesis file

Publisher:纸扇轻摇Latest update time:2021-08-27 Source: eefocus Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

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

12.7.png

5.main.c test code


#include

#include //See Chapter 6, Lecture 8 for details

#include //See Chapter 11, Lecture 3 for details

#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);

}

Reference address:51 MCU-IIC&EEPROM synthesis file

Previous article:51 MCU-EEPROM Simple Use
Next article:51 single chip microcomputer-infrared remote control

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号