I2C总线

1. 定义方法

  a.定义起始信号

  b.定义终止信号

  c.定义单片机写入函数

  d.定义单片机读出函数

  e.写入到指定元器件

  f.从指定元器件读出

  g.写一个头文件作为中转

  h.写一个主函数实现对写入读出的调用

 

2. 定义起始信号

  a.SDA 高电平延时

  b.SCL高电平延时

  c.SDA低电平延时

  d.SCL低电平延时

  

    SDA = 1;
    Delay10us();
    SCL = 1;
    Delay10us();
    SDA = 0;
    Delay10us();
    SCL = 0;
    Delay10us();
View Code

  

 

 

3. 终止信号

  a.SDA低电平延时

  b.SCL高电平延时

  c.SDA高电平延时

  

    SDA = 0;
    Delay10us();
    SCL = 1;
    Delay10us();
    SDA = 1;
    Delay10us();
View Code

 

  

4. 单片机写入函数

  a.定义函数需要返回值,需要一个8位形式参数

  b.for循环8次,每次发送一个数据,通过数据左移右移实现,每次写入SDA后要把SCL电平拉低

  c.循环完成后拉高SDA延时后拉高SCL让SDA保持不变

  d.while(SDA)循环等待元器件应答,应答后SDA会被拉低跳出循环

  e.返回值

unsigned char sendaddr(unsigned char dat)
{
    unsigned char a=0,b=0;
    for(a=0;a<8;a++)
    {    SDA=dat>>7;
        dat<<=1;
        Delay10us();
        SCL = 1;
        Delay10us();
        SCL = 0;
        Delay10us();            
    }
    SDA = 1;
    Delay10us();
    SCL = 1;    
    while(SDA)
    { b++;
      if(b>200)
      { SCL = 0;
        Delay10us();
          return 0;
      }
    }
    SCL = 0;
    Delay10us();
    return 1;
}
View Code

5. 单片机读出函数  

  a.定义函数需要返回值不需要形式参数

  b.定义变量作为容器接收数据

  c.for循环8次,先拉高电平保持SDA稳定,num<<=1,num|=SDA 拉低电平

  e.返回num

unsigned char reader()
{
 unsigned char a,num;
  num = 0;
 //SDA = 1;
  Delay10us();
  for(a=0;a<8;a++)
  {
      SCL = 1;
     Delay10us();
     num<<=1;
     num|=SDA;
     Delay10us();
     SCL=0;
     Delay10us();
  }
    return num;
}
View Code

6. 写入元器件函数

  a.定义函数不需要返回值,需要两个形式参数

  b.起始信号>>写入函数(元器件地址0)>>写入函数(元器件首地址)>>写入函数(写入值)>>终止信号

void A204write(unsigned char addr,unsigned char dat)
{
    start();
    sendaddr(0xa0);
    sendaddr(addr);
    sendaddr(dat);
    stop();    

}
View Code   

7. 从元器件读出函数

  a.定义带返回值的函数不需要形式参数

  b.起始信号>>写入函数(元器件地址0)>>写入函数(元器件首地址)>>起始信号>>写入函数(元器件地址1)>>接收SDA的值>>终止信号

  c.返回值  

unsigned char A204read(unsigned char addr)
{
    unsigned char num;
    start();
    sendaddr(0xa0);    
    sendaddr(addr);
    start();
    sendaddr(0xa1);
    num = reader();
    stop();
    return num;
}
View Code

 

8.总代码

  a.主函数 

#include<reg52.h>
#include"i2c.h"
/*
  1.延时函数
  2.定义每个按键的作用
  3.根据num选择数码管的值赋值给P0
*/

typedef unsigned char u8;
typedef unsigned int u16;

sbit LA=P2^2;
sbit LB=P2^3;
sbit LC=P2^4;

sbit K1=P3^1;
sbit K2=P3^0;
sbit K3=P3^2;
sbit K4=P3^3;

u8 num=0;
u8 disp[4];
u8 code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};

//延时函数
void lay10us(i)
{
     while(i--);
}
//独立按键函数
void Keypros()
{
    if(K1==0)
    {
        lay10us(10);
        if(K1==0)
        {
            A204write(1,num);
        }
        while(!K1);
    }
    if(K2==0)
    {
        lay10us(10);
        if(K2==0)
        {
            num = A204read(1);
        }
        while(!K2);    
    }    
    if(K3==0)
    {
        lay10us(10);
        if(K3==0)
        {
            num++;
        }
        while(!K3);
    }
    if(K4==0)
    {
        lay10us(10);
        if(K4==0)
        {
            num=0;
        }
    }
    while(!K4);

}
//num按键次数转换为数码管段函数
void dat()
{
    disp[0]=smgduan[num%1000%100%10];
    disp[1]=smgduan[num%1000%100/10];
    disp[2]=smgduan[num%1000/100];
    disp[3]=smgduan[num/1000];
}
//点亮数码管函数
void dispaly()
{
    u8 a;
    for(a=0;a<4;a++)
    {
        switch(a)
        {
            case(0):
                LA=0;LB=0;LC=0;    break;     //数码管第0个
            case(1):
                LA=1;LB=0;LC=0;    break;
            case(2):
                LA=0;LB=1;LC=0;    break;
            case(3):
                LA=1;LB=1;LC=0;        //数码管第4个
        }
        P0=disp[a];
        lay10us(100);
        P0=0x00;                   //数码管消隐
    }    
}

void main()
{
    while(1)
    {
    Keypros();
    dat();
    dispaly();
    }    
}
View Code

  b.子函数

#include<reg52.h>
#include"i2c.h"
unsigned char u8;

/*
  1.起始函数
  2.终止函数
  3.写入函数
  4.接收函数
  5.芯片发送函数
  6.芯片接收函数
*/


/*
  延时函数,延时6us
*/
void Delay10us()
{
    unsigned char a,b;
    for(b=1;b>0;b--)
        for(a=2;a>0;a--);

}

/*
  这是起始信号函数
*/
void start()
{
    SDA = 1;
    Delay10us();
    SCL = 1;
    Delay10us();
    SDA = 0;
    Delay10us();
    SCL = 0;
    Delay10us();
} 

/*void start()
{
    SDA=1;
    Delay10us();
    SCL=1;
    Delay10us();//建立时间是SDA保持时间>4.7us
    SDA=0;
    Delay10us();//保持时间是>4us
    SCL=0;            
    Delay10us();        
}  */
/*
  这是终止信号函数
*/
void stop()
{
    SDA = 0;
    Delay10us();
    SCL = 1;
    Delay10us();
    SDA = 1;
    Delay10us();
} 




/*
    写入函数,将主机内容发送到芯片中
            
*/
unsigned char sendaddr(unsigned char dat)
{
    unsigned char a=0,b=0;
    for(a=0;a<8;a++)
    {    SDA=dat>>7;
        dat<<=1;
        Delay10us();
        SCL = 1;
        Delay10us();
        SCL = 0;
        Delay10us();            
    }
    SDA = 1;
    Delay10us();
    SCL = 1;    
    while(SDA)
    { b++;
      if(b>200)
      { SCL = 0;
        Delay10us();
          return 0;
      }
    }
    SCL = 0;
    Delay10us();
    return 1;
}



/*
  读出函数,将芯片的数据读出到主机中
*/

unsigned char reader()
{
 unsigned char a,num;
  num = 0;
 //SDA = 1;
  Delay10us();
  for(a=0;a<8;a++)
  {
      SCL = 1;
     Delay10us();
     num<<=1;
     num|=SDA;
     Delay10us();
     SCL=0;
     Delay10us();
  }
    return num;
}

/*
  写入芯片
  1.起始函数
  2.写入函数发送地址
  3.写入函数发送器件内部地址
  4.写入函数发送数据
  5.终止函数
*/

void A204write(unsigned char addr,unsigned char dat)
{
    start();
    sendaddr(0xa0);
    sendaddr(addr);
    sendaddr(dat);
    stop();    

}


unsigned char A204read(unsigned char addr)
{
    unsigned char num;
    start();
    sendaddr(0xa0);    
    sendaddr(addr);
    start();
    sendaddr(0xa1);
    num = reader();
    stop();
    return num;
}
View Code

  c.头文件

  

#ifndef _I2C_H
#define _I2C_H
#include<reg52.h>
sbit SCL = P2^1;
sbit SDA = P2^0;

void delay6us(void);
void start();
void stop();
unsigned char sendaddr(unsigned char dat);
unsigned char reader();
void A204write(unsigned char addr,unsigned char dat);
unsigned char A204read(unsigned char addr);

#endif

 

 

 

 

 

 

 

转载于:https://www.cnblogs.com/mycgy/p/8977895.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值