首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

IIC总线协议程序

IIC总线协议程序

网上搜索了一篇IO口模拟的IIC代码,能更好的研究IIC总线协议:
SDA线上的数据在时钟“高”期间必须是稳定的,只有当SCL线上的时钟信号为低时,数据线上的“高”或“低”状态才可以改变。输出到SDA线上的每个字节必须是8位,每次传输的字节不受限制,每个字节必须有一个应答为ACK。

数据传送具有应答是必须的。与应答对应的时钟脉冲由主控器产生,发送器在应答期间必须下拉SDA线。当寻址的被控器件不能应答时,数据保持为高,接着主控器产生停止条件终止传输。
ACK:  SDA=0;SCL=1;udelay();SCL=0;
NOACK: SDA=1;SCL=1;udelay();SCL=0;

(改自周立功软件包)
#include<reg51.h>
#include<intrins.h>
#define   uchar unsignedchar  
#define  uint   unsigned int
extern void Delay1us(unsigned char);
sbitSDA=P1^6;            
sbitSCL=P1^7;            
bitack;           

void Start_I2c()
{
  SDA=1;   
  Delay1us(1);
  SCL=1;
  Delay1us(5);     
   
  SDA=0;   
  Delay1us(5);     
      
  SCL=0;   
  Delay1us(2);
}

void Stop_I2c()
{
  SDA=0;   
  Delay1us(1);   
  SCL=1;   
  Delay1us(5);

  SDA=1;   
  Delay1us(4);
}

void   SendByte(uchar c)
{
uchar BitCnt;
for(BitCnt=0;BitCnt<8;BitCnt++)  
    {
     if((c<<BitCnt)&0x80)SDA=1;   
       else  SDA=0;               
     Delay1us(1);
     SCL=1;               
     
     Delay1us(5);            
            
     SCL=0;
    }
   
    Delay1us(2);
    SDA=1;               
    Delay1us(2);  
    SCL=1;
    Delay1us(3);
    if(SDA==1)ack=0;   
       elseack=1;        
    SCL=0;
    Delay1us(2);
}

uchar   RcvByte()
{
  uchar retc;
  uchar BitCnt;

  retc=0;
  SDA=1;               
  for(BitCnt=0;BitCnt<8;BitCnt++)
      {
        Delay1us(1);  
        SCL=0;                  
      
        Delay1us(5);                 
      
        SCL=1;                  
        Delay1us(3);
        retc=retc<<1;
        if(SDA==1)retc=retc+1;  
        Delay1us(2);
      }
  SCL=0;   
  Delay1us(2);
  return(retc);
}

void Ack_I2c(bit a)
{

  if(a==0)SDA=0;           
        else SDA=1;
  Delay1us(3);     
  SCL=1;

  Delay1us(5);                    
   
  SCL=0;                     
  Delay1us(2);   
}

bit ISendStr(uchar sla,uchar suba,uchar*s,uchar no)
{
    uchar i;
   Start_I2c();               
   SendByte(sla);            
   if(ack==0)return(0);
   SendByte(suba);            
   if(ack==0)return(0);
   for(i=0;i<no;i++)
   {  
     SendByte(*s);            
     if(ack==0)return(0);      // 检测从机发送过来的应答位,ack由sendbyte函数返回
     s++;
    }
   Stop_I2c();               
   return(1);
}

bit IRcvStr(uchar sla,uchar suba,uchar*s,uchar no)
{
    uchar i;
   Start_I2c();                  
   SendByte(sla);               
   if(ack==0)return(0);
   SendByte(suba);               
   if(ack==0)return(0);
   Start_I2c();   
   SendByte(sla+1);
   if(ack==0)return(0);
   for(i=0;i<no-1;i++)
   {  
     *s=RcvByte();               
      Ack_I2c(0);                 
     s++;
    }
   *s=RcvByte();
   Ack_I2c(1);                  
   Stop_I2c();                  
   return(1);
}
继承事业,薪火相传
返回列表