⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 i2c.c

📁 C文件 I2C总线型芯片操作 向芯片写数 读回所写数据 在流水灯上表现所读 较难 较有用 经常
💻 C
字号:
//严格的时序
#include<reg52.h>
#include<intrins.h>//_nop_()函数所在库
#define uchar unsigned char
#define uint unsigned int//简写宏定义
sbit sda=P2^0;//数据总线
sbit scl=P2^1;//时钟总线
void delay()//延时函数〉4.7US
{
   _nop_();
   _nop_();
   _nop_();
   _nop_();
   _nop_();
  
} 
void delay1(uchar x)
{
    uchar a,b;
    for(a=x;a>0;a--)
        for(b=2;b>0;b--);
}

void init_I2C()//初始I2C总线,都释放为高,SCL 为高电平时,SDA数据要稳定
{
	  sda=1;
	  scl=1;
}

void start_I2C()//开始信号,在SCL为高电平时SDA出现下跳变为开始;
{
    sda=1;
    delay();
    scl=1;
    delay();
    sda=0;
    delay();
}

void stop_I2C()//停止信号,在SCL为高电平时SDA出现上跳变为停止;
{
    sda=0;
    delay();
    scl=1;
    delay();
    sda=1;
    delay();
}

void write_byte(uchar dat)//写一个字节到24C02
{
    uchar i;//数据是串行的,高位在前
    for(i=0;i<8;i++)
       {
          scl=0;
          delay();
          dat=dat<<1;//移出的位到PSW的CY位
          sda=CY;
          scl=1;
          delay();//在数据送出后置高SCL并延时保证SDA稳定
          scl=0;
          delay();
       }
    sda=1;//写完数据后习惯性释放数据线以等待回应
}

uchar read_I2C()//读一个字节注意将位移为完整字节的技巧
{
   uchar i,renum;
        
      
    for(i=0;i<8;i++)
       {
          scl=0;
          delay();
          sda=1;
          delay();
          scl=1;
          delay();
          renum=(renum<<1)|sda;//¥
          scl=0;
          delay();
          sda=0;
          delay();
          
       }
    return renum;
    sda=1;//释放数据线
}

void ack_I2C()//应答信号,在SCL为高时24C02收到SDL上的低电平信号
{             //若未收到则在一定时间之后默认已收到
   uchar i;
   scl=1;
   delay();
   while((sda==1)&&(i<250))i++;//SDA从0到1,或一定时间后都可使之跳出循环
   scl=0;
   delay();
}
 
void write_I2C(uchar add,uchar sta)//按照时序向24C04写数据主要函数 
{                                  //要严格按照时序,特别注意应答信号必不可少
   
   start_I2C();//开始信号
   write_byte(add);//存储器地址
   ack_I2C();//应答
   write_byte(2);//写存储器中欲写的单元
   ack_I2C();//应答
   write_byte(sta);//写数据
   ack_I2C();//应答
   stop_I2C();//停止信号
}

uchar readmain()//按照时序读24C04中数据主函数,注意读时也要写清读的地址
{
   uchar temp;//读回数据暂存
   start_I2C();
   write_byte(0xa0);//要读的存储器地址
   ack_I2C();
   write_byte(2);//读存储器中欲写的单元
   ack_I2C();
   start_I2C();
   write_byte(0xa1);//数据流向选择0xa1,1为读
   ack_I2C();
   temp=read_I2C();
   stop_I2C();
   return temp;
}

void main()
{ 
   while(1)
  {
    init_I2C();
    write_I2C(0xa0,0xee);//数据流向选择0xa0,0为写,0Xee为欲写数
    delay1(200);//读写;大的数据流向或单元改变要添置延时,否则将会造成整个程序的失败
    P1=readmain();
    while(1);
  }

    
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -