Analog I2C Programming

Publisher:会弹琴的鲸鱼3312Latest update time:2016-09-25 Source: eefocus Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere
#include 

#include

#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
}

Reference address:Analog I2C Programming

Previous article:I2S bus principle and examples
Next article:Discussion on Portable Programs

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号