#define uchar unsigned char
#define DELAY5US _nop_(); _nop_(); _nop_(); _nop_(); //Delay 5us
#define WriteDeviceAddress 0xa0 //Write the addressing address of the I2C peripheral device
#define ReadDeviceAddress 0xa1 //Read the addressing address of the I2C peripheral device
//Note: The addressing address of the I2C peripheral device is the device address, and the read address is the device address plus 1
uchar E0; //Non-acknowledgement signal flag
uchar NACK=0; //Error flag
//**************************Parts to be modified when modifying hardware********************************
sbit SDA = P1^0; //Analog data line
sbit SCL = P1^1; //Analog clock line
void Start(void) //Start I2C bus sub-function
{
SDA=1;
SCL=1;
DELAY5US
SDA=0;
DELAY5US
SCL=0;
}
void Stop(void) //Stop I2C bus data transmission sub-function
{
SDA=0;
SCL=1;
DELAY5US
SDA=1;
DELAY5US
SCL=0;
}
void Ack(void) //Send response bit subroutine
{
SDA=0;
SCL=1;
DELAY5US
SCL=0;
SDA=1;
}
void NoAck(void) //Send non-acknowledgement bit subroutine
{
SDA=1;
SCL=1;
DELAY5US
SCL=0;
SDA=0;
}
void TestAck(void) //Response bit check subroutine, if no non-response signal is detected, set E0
{
SDA=1;
SCL=1;
E0=0;
_nop_(); //Short delay
if(SDA==1) //If SDA is 1, it indicates non-response, set non-response flag E0
E0=1;
SCL=0;
}
void Write8Bit(uchar n) //Write a byte data subroutine, n is the data to be sent
{
uchar i;
for(i=8;i>0;i--)
{
SDA=(bit)(n&0x80);
SCL=1;
DELAY5US
SCL=0;
SDA=0;
n=n<<1;
}
}
void WriteI2C(uchar *Wdata,uchar RomAddress,uchar number) // Write n bytes of data subroutine
{ //*Wdata is the first address of the data to be sent, RomAddress is the first address of the data to be written to the I2C peripheral device, number is the number of bytes to be written
Start(); // Start
Write8Bit(WriteDeviceAddress); // Write the addressing address of the device
TestAck(); // Response check
if(E0==1)
{
NACK=1; // If the non-response indicates that the device is wrong or broken, set the error flag NACK
return;
}
Write8Bit(RomAddress); // Write the first address of the data storage of the I2C device
TestAck(); // Response check
if(E0==1)
{
NACK=1; // If the non-response indicates that the device is wrong or broken, set the error flag NACK
return;
}
for(;number!=0;number--) // Loop, send bytes one by one
{
Write8Bit(*Wdata); // Write a byte
TestAck(); // Response check
if(E0==1)
{
NACK=1; //If the non-response indicates that the device is wrong or broken, set the error flag NACK
return;
}
Wdata++; //Increase the pointer to point to the next data
}
Stop(); //Stop after all transmissions are completed
}
uchar Read8Bit(void) //Read a byte of data subroutine
{
uchar temp,rbyte=0;
for(temp=8;temp>0;temp--)
{
SDA=1;
SCL=1;
_nop_(); //Short delay
rbyte=rbyte<<1;
rbyte=rbyte|((uchar)(SDA));
SCL=0;
}
return(rbyte);
}
void ReadI2C(uchar *RamAddress,uchar RomAddress,uchar bytes) // Read n bytes of data subroutine
{ //RamAddress is the first address of the receive data buffer, RomAddress is the first address of the data to be read from the I2C peripheral device, bytes is the number of bytes to be written
Start(); // Start
Write8Bit(WriteDeviceAddress); // Write the addressing address of the device
TestAck(); // Response check
if(E0==1)
{
NACK=1; // If the non-response indicates that the device is wrong or broken, set the error flag NACK
return;
}
Write8Bit(RomAddress); // Write the first read address of the internal data of the I2C device
TestAck(); // Response check
if(E0==1)
{
NACK=1; // If the non-response indicates that the device is wrong or broken, set the error flag NACK
return;
}
Start(); // Restart
Write8Bit(ReadDeviceAddress); // Write the addressing address of the device
TestAck(); // Response check
if(E0==1)
{
NACK=1; //If the non-response indicates that the device is wrong or broken, set the error flag NACK
return;
}
while(bytes!=1) //Loop to read byte data
{
*RamAddress=Read8Bit(); //Read a byteAck
(); //Response
RamAddress++; //Address pointer increments
bytes--; //Number of data to be read
}
*RamAddress=Read8Bit(); //Read the last byte of dataNoAck
(); //Non-responseStop
(); //Stop
}
Previous article:I2S bus principle and examples
Next article:Discussion on Portable Programs
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
- 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
- AD19AD19, on a PCB that has already been copper-plated, I deleted the copper and changed the layout to redraw a PCB, but when I entered the 3D view, the original copper outline would be displayed. How can I delete this outline?
- STM32F4 hardware I2C driver 0.96 OLED screen
- Analog electronics course selection test + isolation course learning
- Why can't my INT function enter the interrupt?
- [RT-Thread Reading Notes] Part 2 (3) Semaphores and Mutexes
- What software do I use for schematic illustrations?
- Problems encountered in debugging B-U585I-IOT02A WIFI module
- 2021 National Undergraduate Electronic Design Competition Restart Notice and Schedule
- MicroPython 1.18 released
- Last day: Let's play together, AI development board based on Allwinner R329 chip