The master will teach you how to get started quickly: the standard 80C51 microcontroller simulates the host program of the I2C bus

Publisher:快乐航程Latest update time:2024-03-14 Source: elecfans Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

I2C bus protocol program

When I was working on the program, I found Zhou Ligong's program on the Internet. I thought it was pretty good and reprinted it by the way; during use, I must pay attention to timing and time issues.


"i2c.h file"

//I2C bus comprehensive sending function, sending multiple bytes of data to the slave

I2C read and write EEPROM flow chart

The master will teach you how to get started quickly: the standard 80C51 microcontroller simulates the host program of the I2C bus

bit I2C_Puts(

unsigned char SlaveAddr,

unsigned int SubAddr,

unsigned char SubMod,

char*dat,

unsigned int Size

);

//I2C bus comprehensive receiving function, receives multiple bytes of data from the slave

bit I2C_Gets

(

unsigned char SlaveAddr,

unsigned int SubAddr,

unsigned char SubMod,

char*dat,

unsigned int Size

);

#endif

"i2c.c file"

#include “I2C.h”

//Define delay variables for macro I2C_Delay()

unsigned char I2C_Delay_t;

#define I2C_Delay(){I2C_Delay_t = (I2C_DELAY_VALUE);while (--I2C_Delay_t != 0);}

void I2C_Start()

{

I2C_SDA = 1;I2C_Delay();

I2C_SCL = 1;I2C_Delay();

I2C_SDA = 0;I2C_Delay();

I2C_SCL = 0;I2C_Delay();

}

void I2C_Write(char dat)

{

unsigned char t = 8;

do

{

I2C_SDA = (bit) (dat & 0x80);

dat "《= 1;

I2C_SCL = 1; I2C_Delay();

I2C_SCL = 0; I2C_Delay();

} while ( --t != 0 );

}

char I2C_Read()

{

char dat;

unsigned char t = 8;

I2C_SDA = 1;//Before reading data, SDA should be pulled high

do

{

I2C_SCL = 1;

I2C_Delay();

dat "《= 1;

if (I2C_SDA) dat |= 0x01;

I2C_SCL = 0;

I2C_Delay();

} while ( --t != 0 );

return dat;

}

bit I2C_GetAck()

{

bit ack;

//Bus preparation, accept response

I2C_SDA = 1;I2C_Delay();

I2C_SCL = 1;I2C_Delay();

ack = I2C_SDA;

I2C_SCL = 0;

I2C_Delay();

return ack;

}

/****************************************************** *****************************

Function: I2C_PutAck()

Function: The host generates an acknowledge bit or a non-acknowledge bit

parameter:

ack=0: The host generates an acknowledge bit

ack=1: The host generates a non-acknowledge bit

illustrate:

After receiving each byte of data, the host should generate a response bit

After receiving the last byte of data, the host should generate a non-acknowledge bit

*************************************************** ****************************/

void I2C_PutAck(bit ack)

{

I2C_SDA = ack;I2C_Delay();

I2C_SCL = 1;I2C_Delay();

I2C_SCL = 0;I2C_Delay();

}

/************

Function: I2C_Stop()

Function: Generate the stop state of the I2C bus

illustrate:

Stop the I2C bus when SDA has a rising edge while SCL is high

No matter what level state SDA and SCL are in, this function can always correctly generate the stop state.

After this function is executed, the I2C bus is in an idle state

*************/

void I2C_Stop()

{

unsigned int t = I2C_STOP_WAIT_VALUE;

I2C_SDA = 0;I2C_Delay();

I2C_SCL = 1;I2C_Delay();

I2C_SDA = 1I2C_Delay();

while (--t != 0); //Add a certain delay before generating Start next time

}

/****

Function: I2C_Puts()

Function: I2C bus comprehensive sending function, sending multiple bytes of data to the slave

parameter:

SlaveAddr: Slave address (7-bit pure address, excluding read and write bits)

SubAddr: Subaddress of the slave machine

SubMod: sub-address mode, 0-no sub-address, 1-single-byte sub-address, 2-double-byte sub-address

*dat: data to be sent

Size: number of bytes of data

return:

0: Sent successfully

1: An exception occurred during the sending process

illustrate:

This function works well with all common I2C devices, regardless of whether they have subaddresses or not.

When the slave has no sub-address, the parameter SubAddr is arbitrary, and SubMod should be 0

*****/

bit I2C_Puts

(unsigned char SlaveAddr, unsigned int SubAddr, unsigned char SubMod,

char *dat, unsigned int Size)

{

//Define temporary variables

unsigned char i;

char a[3];

if (Size == 0) return 0;//Check the length

a[0] = (SlaveAddr《《1);//Prepare the slave address

if (SubMod 》 2) SubMod = 2; //Check subaddress mode

//Determine subaddress

switch(SubMod)

{

case 0:

break;

case 1:

a[1] = (char)(SubAddr);

break;

case 2:

a[1] = (char)(SubAddr 》》 8);

a[2] = (char)(SubAddr);

break;

default:

break;

}

//Send the slave address (a[0]), then send the sub-address (if there is a sub-address) (a[1], a[2])

I2C_Start();

for ( i=0; i《=SubMod; i++ )

{

I2C_Write(a[i]);

if(I2C_GetAck())

{

I2C_Stop();

return 1;

}

}

//send data

do

{

I2C_Write(*dat++);

if (I2C_GetAck()) break;

} while ( --Size != 0 );

//After sending, stop the I2C bus and return the result

I2C_Stop();

if(Size==0)

{

return 0;//sent successfully

}

else

{

return 1;//An exception occurred during the sending process

}

}

/******

Function: I2C_Gets()

Function: I2C bus comprehensive receiving function, receiving multiple bytes of data from the slave

parameter:

SlaveAddr: Slave address (7-bit pure address, excluding read and write bits)

SubAddr: Subaddress of the slave machine

SubMod: sub-address mode, 0-no sub-address, 1-single-byte sub-address, 2-double-byte sub-address

*dat: save the received data

Size: number of bytes of data

return:

0: Reception successful

1: An exception occurred during the reception process

illustrate:

This function works well with all common I2C devices, regardless of whether they have subaddresses or not.

When the slave has no sub-address, the parameter SubAddr is arbitrary, and SubMod should be 0

*****/

bit I2C_Gets

(unsigned char SlaveAddr, unsigned int SubAddr, unsigned char SubMod,

char *dat, unsigned int Size)

{

//Define temporary variables

unsigned char i;

char a[3];

if (Size == 0) return 0; //Check the length and receive successfully

a[0] = (SlaveAddr《《1);//Prepare the slave address

if (SubMod 》 2) SubMod = 2; //Check subaddress mode

//If it is a slave with a sub-address, the slave address and sub-address must be sent first

if (SubMod != 0 )

{

//Determine subaddress

if(SubMod==1)

{

a[1] = (char)(SubAddr);

}

else

{

a[1] = (char)(SubAddr 》》 8);

a[2] = (char)(SubAddr);

}

//Send the slave address to write, and then send the sub-address

I2C_Start();

for ( i=0; i《=SubMod; i++ )

{

I2C_Write(a[i]);

if(I2C_GetAck())

{

I2C_Stop();

return 1;

}

}

}

//The I2C_Start() here is a repeated start state for slaves with sub-addresses

//For slaves without subaddresses, it is the normal starting state.

I2C_Start();

//Send slave address to read

I2C_Write(a[0]+1);

if(I2C_GetAck())

{

I2C_Stop();

return 1;

}

//Receive data

for (;;)

{

*dat++ = I2C_Read();

if ( --Size == 0 )

{

I2C_PutAck(1);

break;

}

I2C_PutAck(0);

}

//After receiving, stop the I2C bus and return the result

I2C_Stop();

return 0;

}


Reference address:The master will teach you how to get started quickly: the standard 80C51 microcontroller simulates the host program of the I2C bus

Previous article:The structure and working principle of the timing counter of 80C51 microcontroller
Next article:Data acquisition LM12H458 and 80C51 interface circuit - circuit diagrams read every day (153)

Latest Microcontroller Articles
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号