/
此程序是I2C操作渠道(主方法的软件渠道)的底层的C子程序,如发送数据
及接纳数据,应对位发送,并供给了几个直接面临器材的操作函数,它很便利的
与用户程序衔接并扩展…..
通过自己验,肯定好用!
/
bit ack; /*应对标志位*/
/*
起动总线函数
函数原型: void Start_I2c();
功用: 发动I2C总线,即发送I2C开端条件.
/
void Start_I2c()
{
SDA=1; /*发送开端条件的数据信号*/
_Nop();
SCL=1;
_Nop(); /*开端条件树立时刻大于4.7us,延时*/
_Nop();
_Nop();
_Nop();
_Nop();
SDA=0; /*发送开端信号*/
_Nop(); /* 开端条件确定时刻大于4μs*/
_Nop();
_Nop();
_Nop();
_Nop();
SCL=0; /*钳住I2C总线,预备发送或接纳数据 */
_Nop();
_Nop();
}
/*
完毕总线函数
函数原型: void Stop_I2c();
功用: 完毕I2C总线,即发送I2C完毕条件.
/
void Stop_I2c()
{
SDA=0; /*发送完毕条件的数据信号*/
_Nop(); /*发送完毕条件的时钟信号*/
SCL=1; /*完毕条件树立时刻大于4μs*/
_Nop();
_Nop();
_Nop();
_Nop();
_Nop();
SDA=1; /*发送I2C总线完毕信号*/
_Nop();
_Nop();
_Nop();
_Nop();
}
/*
字节数据传送函数
函数原型: void SendByte(uchar c);
功用: 将数据c发送出去,可所以地址,也可所以数据,发完后等候应对,并对
此状况位进行操作.(不应对或非应对都使ack=0 假)
发送数据正常,ack=1; ack=0一共被控器无应对或损坏。
/
void SendByte(uchar c)
{
uchar BitCnt;
for(BitCnt=0;BitCnt<8;BitCnt++) /*要传送的数据长度为8位*/
{
if((c<
_Nop();
SCL=1; /*置时钟线为高,告诉被控器开端接纳数据位*/
_Nop();
_Nop(); /*确保时钟高电平周期大于4μs*/
_Nop();
_Nop();
_Nop();
SCL=0;
}
_Nop();
_Nop();
SDA=1; /*8位发送完后开释数据线,预备接纳应对位*/
_Nop();
_Nop();
SCL=1;
_Nop();
_Nop();
_Nop();
if(SDA==1)ack=0;
else ack=1; /*判别是否接纳到应对信号*/
SCL=0;
_Nop();
_Nop();
}
/*
字节数据传送函数
函数原型: uchar RcvByte();
功用: 用来接纳从器材传来的数据,并判别总线过错(不发应对信号),
发完后请用应对函数。
/
uchar RcvByte()
{
uchar retc;
uchar BitCnt;
retc=0;
SDA=1; /*置数据线为输入方法*/
for(BitCnt=0;BitCnt<8;BitCnt++)
{
_Nop();
SCL=0; /*置时钟线为低,预备接纳数据位*/
_Nop();
_Nop(); /*时钟低电平周期大于4.7μs*/
_Nop();
_Nop();
_Nop();
SCL=1; /*置时钟线为高使数据线上数据有用*/
_Nop();
_Nop();
retc=retc<<1;
if(SDA==1)retc=retc+1; /*读数据位,接纳的数据位放入retc中 */
_Nop();
_Nop();
}
SCL=0;
_Nop();
_Nop();
return(retc);
}
/
应对子函数
原型: void Ack_I2c(bit a);
功用:主控器进行应对信号,(可所以应对或非应对信号)
/
void Ack_I2c(bit a)
{
if(a==0)SDA=0; /*在此宣布应对或非应对信号 */
else SDA=1;
_Nop();
_Nop();
_Nop();
SCL=1;
_Nop();
_Nop(); /*时钟低电平周期大于4μs*/
_Nop();
_Nop();
_Nop();
SCL=0; /*清时钟线,钳住I2C总线以便持续接纳*/
_Nop();
_Nop();
}
/*
向无子地址器材发送字节数据函数
函数原型: bit ISendByte(uchar sla,ucahr c);
功用: 从发动总线到发送地址,数据,完毕总线的全过程,从器材地址sla.
假如回来1一共操作成功,不然操作有误。
留意: 运用前有必要已完毕总线。
/
bit ISendByte(uchar sla,uchar c)
{
Start_I2c(); /*发动总线*/
SendByte(sla); /*发送器材地址*/
if(ack==0)return(0);
SendByte(c); /*发送数据*/
if(ack==0)return(0);
Stop_I2c(); /*完毕总线*/
return(1);
}
/*
向有子地址器材发送多字节数据函数
函数原型: bit ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);
功用: 从发动总线到发送地址,子地址,数据,完毕总线的全过程,从器材
地址sla,子地址suba,发送内容是s指向的内容,发送no个字节。
假如回来1一共操作成功,不然操作有误。
留意: 运用前有必要已完毕总线。
/
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
SendByte(*s); /*发送数据*/
if(ack==0)return(0);
s++;
}
Stop_I2c(); /*完毕总线*/
return(1);
}
/*
向无子地址器材读字节数据函数
函数原型: bit IRcvByte(uchar sla,ucahr *c);
功用: 从发动总线到发送地址,读数据,完毕总线的全过程,从器材地
址sla,回来值在c.
假如回来1一共操作成功,不然操作有误。
留意: 运用前有必要已完毕总线。
/
bit IRcvByte(uchar sla,uchar *c)
{
Start_I2c(); /*发动总线*/
SendByte(sla+1); /*发送器材地址*/
if(ack==0)return(0);
*c=RcvByte(); /*读取数据*/
Ack_I2c(1); /*发送非就答位*/
Stop_I2c(); /*完毕总线*/
return(1);
}
/*
向有子地址器材读取多字节数据函数
函数原型: bit ISendStr(uchar sla,uchar suba,ucahr *s,uchar no);
功用: 从发动总线到发送地址,子地址,读数据,完毕总线的全过程,从器材
地址sla,子地址suba,读出的内容放入s指向的存储区,读no个字节。
假如回来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
*s=RcvByte(); /*发送数据*/
Ack_I2c(0); /*发送就答位*/
s++;
}
*s=RcvByte();
Ack_I2c(1); /*发送非应位*/
Stop_I2c(); /*完毕总线*/
return(1);
}