I2c总线驱动

/******************************************************************
/*驱动名称:I2c总线驱动
/*函数原型:  (每个函数的都有返回值,函数返回"1"则函数的操作成功,否则失败)
/*bit SendByte_I2c_OneAd(unsigned char Ad,unsigned char Data)
/*功能描述:向器件地址为Ad的器件发送数据"Data",这里Ad为器件的高7为地址,最后一位(读写控制位)按0处理,
/*   在相应的函数中会对最后一位进行处理
/*
/*bit SendBytes_I2c_SonAds(unsigned char Chip_Ad,unsigned char Ad,unsigned char *s,unsigned char SendByte_Num )
/*功能描述:向器件地址为"Chip_Ad",子地址为Ad开始的空间依次存放"SendByte_Num"个字符,存放的内容从"S"指向的地址里的内容
/*
/*bit RevByte_I2c_OneAd(unsigned char Ad,unsigned char *s)
/*功能描述:从器件地址为Ad的器件接收一个字节数据,接收的数据放到S指向的空间
/*
/*bit RevBytes_I2c_SonAds(unsigned char Chip_Ad,unsigned char Ad,unsigned char *s,unsigned char SendByte_Num)
/*功能描述:从器件地址为"Chip_Ad"的器件的子地址"Ad"处读出"SendByte_Num"个字节数据存到"s"指向的空间
/*
/*编程人:LT
/*编程时间:2010.5
/*参考资料:周立功---增强型80C51单片机速成与实战
/*          郭天翔---新概念51单片机C语言教程
/*********************************************************************/
#include <reg51.h>
#include <intrins.h>
#define _Nop() _nop_()
#define Delay_5us _Nop();_Nop();_Nop();_Nop();_Nop();
#define Delay_2us _Nop();_Nop();
#define Delay_1us _Nop();
#define High 1
#define Low     0
sbit SDA=P2^1;
sbit SCL=P2^0;
bit  Ask_I2c;

void Start_I2c()//起始信号,启动I2c
{
 SDA=High;//SCL高电平期间,SDL一个下降沿启动I2c
 Delay_1us;
 SCL=High;
 Delay_5us;
 SDA=Low;
 Delay_5us;
 SCL=Low;//拉低I2c,准备发送或接收数据
 Delay_2us;
}

void Stop_I2c()//结束I2c数据传输
{
 SDA=Low;//SCL高电平期间,SDL一个上升沿终止I2c
 Delay_1us;
 SCL=High;
 Delay_5us;
 SDA=High;
 Delay_5us;
}

void SendByte_I2c(unsigned char SendData)//向I2c总线上传输一个字节数据,传输成功则标志 "Ask_I2c" 置1
{           //根据标志可判断是否传输成功
 unsigned char BitNum;
 for(BitNum=0;BitNum<8;BitNum++)
  {
   if((SendData<<BitNum)&0x80)
    SDA=1;
   else
    SDA=0;
   Delay_1us;
   SCL=High;
   Delay_5us;//数据送到SDA上后,SCL高电平必须保持4.5us以上,数据才能被从机接收
   SCL=Low;
  }
 Delay_2us;
 SDA=High;
 Delay_2us;
 SCL=High;
 Delay_5us;
 if(SDA==High)
  Ask_I2c=0;
 else
  Ask_I2c=1;
 SCL=Low;
 Delay_2us;
}

unsigned char RevByte_I2c()//从总线上接收一个字节的数据
{
 unsigned char RevByte;
 unsigned char BitNum;
 RevByte=0;
 SDA=High;
 for(BitNum=0;BitNum<8;BitNum++)
  {
   Delay_1us;
   SCL=Low;//拉低SCL等待SDA上数据的变化
   Delay_5us;
   SCL=High;//拉高SCL让SDA上数据稳定,在稳定期间把SDA上的数据读走
   Delay_2us;
   RevByte=RevByte<<1;
   if(SDA==High)
    RevByte=RevByte+1;
   Delay_2us;
  
  }
 SCL=Low;
 Delay_2us;
 return(RevByte);
}


void SendAsk_I2c(bit n)//发送应答信号
{
 if(n==0)
  SDA=Low;
 else
  SDA=High;
 Delay_2us;
 SCL=High;
 Delay_5us;
 SCL=Low;
 Delay_2us;
}

bit SendByte_I2c_OneAd(unsigned char Ad,unsigned char Data)//向无子地址的设备发送一个字节数据,
{
 Start_I2c();
 SendByte_I2c(Ad);
 if(Ask_I2c==0)
  return(0);
 SendByte_I2c(Data);
 if(Ask_I2c==0)
  return(0);
 Stop_I2c();
 return(1);

}


bit SendBytes_I2c_SonAds(unsigned char Chip_Ad,unsigned char Ad,unsigned char *s,unsigned char SendByte_Num)
{
 unsigned char i;// 发送时Chip_Ad的最后一位为0;
 Start_I2c();
 SendByte_I2c(Chip_Ad);
 if(Ask_I2c==0)
  return(0);
 SendByte_I2c(Ad);
 if(Ask_I2c==0)
  return(0);
 for(i=0;i<SendByte_Num;i++)
  {
   SendByte_I2c(*s);
   if(Ask_I2c==0)
   return(0);
   s++;
  }
 Stop_I2c();
 return(1);
}

bit RevByte_I2c_OneAd(unsigned char Ad,unsigned char *s)//从无子地址的设备接收一个字节数据,
{
 Start_I2c();
 SendByte_I2c(Ad+1);//Ad可以事先定义好,以后的操作就不用考虑最后一位
 if(Ask_I2c==0)
  return(0);
 *s=RevByte_I2c();
 SendAsk_I2c(1);
 Stop_I2c();
 return(1);
}


bit RevBytes_I2c_SonAds(unsigned char Chip_Ad,unsigned char Ad,unsigned char *s,unsigned char SendByte_Num)
{
 unsigned char i;// 发送时Chip_Ad的最后一位为0;
 Start_I2c();
 SendByte_I2c(Chip_Ad);
 if(Ask_I2c==0)
  return(0);
 SendByte_I2c(Ad);
 if(Ask_I2c==0)
  return(0);
 Start_I2c();
 SendByte_I2c(Chip_Ad+1);
 if(Ask_I2c==0)
  return(0);
 for(i=0;i<SendByte_Num-1;i++)
  {
   *s=RevByte_I2c();
   SendAsk_I2c(0);
   s++;
  }
 *s=RevByte_I2c();//特别注意这里,因为每次接收一个字节是数据后要发送一个"应答信号",因为这里数据要连续
 SendAsk_I2c(1);  //接收数据,所以接收时一直是发送的"非应答信号",而最后一个字节数据接收完了以后要发送
 Stop_I2c();   //一个"应答信号",所以这里不能把接收部分全部放入循环中,而要单独放在外面
 return(1);   //呵呵。。。。。
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值