I2C通讯的C语言程序


I2C通讯的C语言程序

I2C通讯的C语言程序
I2C通讯的C语言程序

#include <INTRINS.H>
#include <stdio.h>
#include <reg51.h>

sbit SCK=0x91;//时钟线端口
sbit SDA=0x90;//数据线端口

#define  I2C_Address 0xa0 //I2C芯片地址
#define  nop _nop_()  
#define  NOP nop;nop;nop;nop;nop;nop//延时应大于4.7us

//开始信号
//在时钟线为高电平时,数据线由高向低跳变. 
void StartI2C(void)
  SCK=1;
    SDA=1;
    NOP;
    SDA=0;
    NOP;
    SCK=0;
    NOP;
}
//停止信号
//在时钟线为高电平时,数据线由低向高跳变.
void StopI2C(void)
  SDA=0;
    NOP;
    SCK=1;
    NOP;
    SDA=1;
}

//发送一个字节.
bit SendChar(unsigned char SendData)
  unsigned char i;
    bit ACK;
    for(i=0;i<8;i++)
    {   if((SendData<<i)&0x80)SDA=1;
        else SDA=0;
        SCK=1;
        NOP;
        SCK=0;
        NOP;
    }
//发送一个字节后,读取来自I2C芯片的响应.
//即在发送完8个字节后,在第九个时钟内,SDA总线应为低电平,表示I2C芯片已经读取了数据.
//否则为高电平.即发送收败.
    SDA=1;
    SCK=1;
    NOP;
    ACK=SDA;
    SCK=0;
    NOP;
    return ACK;

}
//在读取完来自I2C的8位数据后,发出读取正确位.
//即发送一个低电平,表示已经读取到来自I2C的数据,并允许I2芯片发送下一字节.
void ACK(void)
  SDA=0;
    NOP;
    SCK=1;
    NOP;
    SCK=0;
}
//在读取完来自I2C的8位数据后,发送不响应位.
//即发送一个高电平,表示已经读取完来自I2C的数据,并且不允许I2C发送下一字节.
void NAK(void)
{
    SDA=1;
    NOP;
    SCK=1;
    NOP;
    SCK=0;
}
//读入一个字节的数据.
unsigned char ReadChar(void)
  unsigned char i,BackData;
    BackData=0;
    SDA=1;
    for(i=0;i<8;i++)
    {   SCK=1;
        nop;nop;nop;
        BackData=BackData<<1;
        if(SDA)BackData++;
        SCK=0;
    }
    return BackData;
}

//以下所有为测试使用...
//应注意,在读I2C芯片时,在发送完I2C片内地址后,
//一定要发送一个重开始信号,然后再发送读命令.

bit WriteI2C(unsigned char Address,unsigned char WriteData)
  SENDSTART:
    StartI2C();
    if(SendChar(I2C_Address)) goto SENDSTART;
    SENDADD:
    if(SendChar(Address)){StartI2C;goto SENDADD;}
    SENDDATA:
    if(SendChar(WriteData)){StartI2C;goto SENDDATA;}
    if(SendChar(WriteData)){StartI2C;goto SENDDATA;}
    StopI2C();
    return 0;
}


unsigned char ReadI2C(unsigned char Address)
  unsigned char BackData;
    ReadSTART:
    StartI2C();
    if(SendChar(I2C_Address)) goto ReadSTART;
    ReadADD:
    if(SendChar(Address)){StartI2C;goto ReadADD;}
    ReadSTART2:
    StartI2C();
    if(SendChar(I2C_Address+1)) goto ReadSTART2;
    BackData=ReadChar();
    ACK();
    BackData=ReadChar();
    NAK();
    StopI2C();
    return BackData;
}

void Delay(unsigned int ms)
  unsigned int i,j;
    for(i=0;i<ms;i++)
    for(j=0;j<240;j++);
}

void main(void)
  bit j;
    unsigned char i,BackData=0;
    unsigned char Address=0x00,ReadData=0x00;
    while(1)
    {   ResetI2C;
        ReadData=ReadI2C(Address);
        ReadData++;
        Delay(5);
        WriteI2C(Address,ReadData);
        Delay(5);
        Address++;Address++;

    }
}



I2C 程序(已经验证 )

#define  _I2C_C_
#include "include_all.h"

/**************************
 AT24C02????

//Author:   Yuki 
//Last modified : 2008-6-8  
**************************/

#define  NOPS();{_nop_();_nop_();_nop_();_nop_();_nop_();}
 
sbit SCL = P3^4; //pin16
sbit SDA = P3^5;    //pin17
sbit TLED = P3^6;

unsigned char SystemError;

void Delay(int TIME)
{
   while(TIME--);
}

//---------------------------------
//  Function: void I2C_Start(void)
//  Discrption:
//----------------------------------
void I2C_Start(void)
{
  SDA = 1;
  SCL = 1; 
  NOPS(); //Initial
  SDA = 0;
  NOPS();       //START
  SCL = 0;
}

//---------------------------------
//  Function: void I2C_Stop(void)
//  Discrption:
//----------------------------------
void I2C_Stop(void)
{
  SCL = 0; 
  SDA = 0;
  NOPS();     //Initial
  SCL = 1;
  NOPS();       //STOP   
  SDA = 1;
}

//---------------------------------
//  Function: void I2C_Start(void)
//  Discrption:
//----------------------------------

WaitAck(void)
{
  unsigned char errtime = 255;
  SDA = 1;
  NOPS();
  SCL = 1;
  NOPS();
  SystemError = 0x10;
  while(SDA)
  {
    errtime--;
    if(!errtime)
    {
      I2C_Stop();
      SystemError = 0x11;
      return;
    }
  }
  SCL = 0;
}

//---------------------------------
//  Function: void SendAck(void)
//  Discrption:
//----------------------------------
void SendAck(void)

  SDA =0 ;
  NOPS();
  SCL = 1;
  NOPS();
  SCL = 0;
}

//---------------------------------
//  Function: void SendNotAck(void)
//  Discrption:
//----------------------------------
void SendNotAck(void)

  SDA =1 ;
  NOPS();
  SCL = 1;
  NOPS();
  SCL = 0;
}

//-----------------------------------------------------
//  Function: void I2CSendByte(unsigned char send_data)
//  Discrption:
//-----------------------------------------------------
void I2CSendByte(unsigned char send_data)
{
  unsigned char count = 8;
  for(count = 0;count<8;count++)
  {
    SCL = 0;
    _nop_();
   SDA = (bit)(send_data & 0x80);
   send_data <<= 1;
   NOPS();
   SCL = 1;
   NOPS();  
  }
  SCL = 0;
}

//-----------------------------------------------------
//  Function: unsigned char I2CReceiveByte(void)
//  Discrption:
//-----------------------------------------------------
unsigned char I2CReceiveByte(void)
{
  unsigned char count = 8;
  unsigned char dat = 0;   
  SDA = 1;
  for(count = 0;count<8;count++)
  {   
   dat <<= 1;
   SCL = 0;
   NOPS();
   SCL = 1;
   NOPS();
   dat |= SDA;    
  }
  SCL = 0;
  return(dat);
}

//--------------------------------------------------------------------------
//  Function: void WriteCharToChip(unsigned int address,unsigned char dat)
//  Discrption:
//--------------------------------------------------------------------------
void WriteCharToChip(unsigned int address,unsigned char dat)
{
  I2C_Start();
  I2CSendByte(0xA0);
  WaitAck();
  I2CSendByte((char)(address)>>8);  //????AT24C02,AT24C64,AT24C128,AT24C256??,??????????
  Delay(300);
  WaitAck();
  I2CSendByte((char)(address));
  WaitAck();  
  I2CSendByte(dat);
  Delay(300);
  WaitAck(); 
  I2C_Stop(); 
}
//--------------------------------------------------------------------------
//  Function: unsigned char ReadCharFromChip(unsigned int Address)
//  Discrption:
//--------------------------------------------------------------------------
unsigned char ReadCharFromChip(unsigned int Address)
{
   unsigned char recv_data;
   I2C_Start();
   I2CSendByte(0xA0);
   WaitAck();
   I2CSendByte((char)(Address>>8));//????AT24C02,AT24C64,AT24C128,AT24C256??,??????????
   WaitAck();
   I2CSendByte((char)(Address));
   WaitAck();
   I2C_Start();
   I2CSendByte(0xA1);
   WaitAck();
   recv_data = I2CReceiveByte();
   SendNotAck();
   I2C_Stop();
   return(recv_data);  
}

main()
{
  unsigned char Read_data;
  for(;;)
  {
    WriteCharToChip(0x10,0xA3);
    Read_data = ReadCharFromChip(0x10);
  }
}


  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我明白了,以下是基于MCU的模拟I2C通讯程序C语言代码示例: ``` #include <stdio.h> #include <stdlib.h> #define SDA_PIN 0 //定义SDA引脚 #define SCL_PIN 1 //定义SCL引脚 #define SDA_HIGH() (SDA_PORT |= (1 << SDA_PIN)) //SDA高电平 #define SCL_HIGH() (SCL_PORT |= (1 << SCL_PIN)) //SCL高电平 #define SDA_LOW() (SDA_PORT &= ~(1 << SDA_PIN)) //SDA低电平 #define SCL_LOW() (SCL_PORT &= ~(1 << SCL_PIN)) //SCL低电平 #define I2C_ACK 0 //接收ACK信号 #define I2C_NACK 1 //不接收ACK信号 void I2C_Start(void); void I2C_Stop(void); unsigned char I2C_WriteByte(unsigned char data); unsigned char I2C_ReadByte(unsigned char ack); void I2C_Start(void) { SDA_HIGH(); SCL_HIGH(); _delay_us(4); SDA_LOW(); _delay_us(4); SCL_LOW(); } void I2C_Stop(void) { SDA_LOW(); SCL_HIGH(); _delay_us(4); SDA_HIGH(); _delay_us(4); } unsigned char I2C_WriteByte(unsigned char data) { unsigned char i; for (i = 0; i < 8; i++) { if (data & 0x80) { SDA_HIGH(); } else { SDA_LOW(); } SCL_HIGH(); _delay_us(4); SCL_LOW(); _delay_us(4); data <<= 1; } SDA_HIGH(); SCL_HIGH(); _delay_us(4); if (SDA_PIN) { return I2C_NACK; } else { return I2C_ACK; } } unsigned char I2C_ReadByte(unsigned char ack) { unsigned char i, data = 0; SDA_HIGH(); for (i = 0; i < 8; i++) { data <<= 1; SCL_HIGH(); _delay_us(4); if (SDA_PIN) { data |= 0x01; } SCL_LOW(); _delay_us(4); } if (ack) { SDA_LOW(); } else { SDA_HIGH(); } SCL_HIGH(); _delay_us(4); SCL_LOW(); _delay_us(4); return data; } ``` 以上代码是一个基本的模拟I2C通讯程序,你可以根据自己需要进行修改和扩展。需要注意的是,代码的SDA_PORT和SCL_PORT要根据具体情况进行定义。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值