- UID
- 1029342
- 性别
- 男
|
网上搜索了一篇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);
} |
|