1. 程式人生 > >I2C總線

I2C總線

div reg 函數 style i2c splay lB 定義變量 按鍵

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

 

I2C總線